Add support for geoip cache db reading

chubin/logging
Igor Chubin 2 years ago
parent 4599029329
commit a27541a25b

@ -6,6 +6,7 @@ import (
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"github.com/chubin/wttr.in/internal/types"
"github.com/chubin/wttr.in/internal/util" "github.com/chubin/wttr.in/internal/util"
) )
@ -75,6 +76,8 @@ type Geo struct {
// IPCacheDB contains the path to the SQLite DB with the IP Geodata cache. // IPCacheDB contains the path to the SQLite DB with the IP Geodata cache.
IPCacheDB string `yaml:"ipCacheDB,omitempty"` IPCacheDB string `yaml:"ipCacheDB,omitempty"`
CacheType types.CacheType `yaml:"cacheType,omitempty"`
} }
// Default contains the default configuration. // Default contains the default configuration.
@ -86,6 +89,7 @@ func Default() *Config {
Geo{ Geo{
IPCache: "/wttr.in/cache/ip2l", IPCache: "/wttr.in/cache/ip2l",
IPCacheDB: "/wttr.in/cache/geoip.db", IPCacheDB: "/wttr.in/cache/geoip.db",
CacheType: types.CacheTypeFiles,
}, },
Logging{ Logging{
AccessLog: "/wttr.in/log/access.log", AccessLog: "/wttr.in/log/access.log",

@ -2,6 +2,7 @@ package ip
import ( import (
"errors" "errors"
"fmt"
"log" "log"
"net/http" "net/http"
"os" "os"
@ -12,7 +13,10 @@ import (
"github.com/chubin/wttr.in/internal/config" "github.com/chubin/wttr.in/internal/config"
"github.com/chubin/wttr.in/internal/routing" "github.com/chubin/wttr.in/internal/routing"
"github.com/chubin/wttr.in/internal/types"
"github.com/chubin/wttr.in/internal/util" "github.com/chubin/wttr.in/internal/util"
"github.com/samonzeweb/godb"
"github.com/samonzeweb/godb/adapters/sqlite"
) )
var ( var (
@ -31,16 +35,34 @@ type Location struct {
Longitude float64 `db:"longitude"` Longitude float64 `db:"longitude"`
} }
func (l *Location) String() string {
if l.Latitude == -1000 {
return fmt.Sprintf(
"%s;%s;%s;%s",
l.CountryCode, l.CountryCode, l.Region, l.City)
}
return fmt.Sprintf(
"%s;%s;%s;%s;%v;%v",
l.CountryCode, l.CountryCode, l.Region, l.City, l.Latitude, l.Longitude)
}
// Cache provides access to the IP Geodata cache. // Cache provides access to the IP Geodata cache.
type Cache struct { type Cache struct {
config *config.Config config *config.Config
db *godb.DB
} }
// NewCache returns new cache reader for the specified config. // NewCache returns new cache reader for the specified config.
func NewCache(config *config.Config) *Cache { func NewCache(config *config.Config) (*Cache, error) {
db, err := godb.Open(sqlite.Adapter, config.Geo.IPCacheDB)
if err != nil {
return nil, err
}
return &Cache{ return &Cache{
config: config, config: config,
} db: db,
}, nil
} }
// Read returns location information from the cache, if found, // Read returns location information from the cache, if found,
@ -56,6 +78,13 @@ func NewCache(config *config.Config) *Cache {
// DE;Germany;Free and Hanseatic City of Hamburg;Hamburg;53.5736;9.9782 // DE;Germany;Free and Hanseatic City of Hamburg;Hamburg;53.5736;9.9782
// //
func (c *Cache) Read(addr string) (*Location, error) { func (c *Cache) Read(addr string) (*Location, error) {
if c.config.Geo.CacheType == types.CacheTypeDB {
return c.readFromCacheDB(addr)
}
return c.readFromCacheFile(addr)
}
func (c *Cache) readFromCacheFile(addr string) (*Location, error) {
bytes, err := os.ReadFile(c.cacheFile(addr)) bytes, err := os.ReadFile(c.cacheFile(addr))
if err != nil { if err != nil {
return nil, ErrNotFound return nil, ErrNotFound
@ -63,6 +92,17 @@ func (c *Cache) Read(addr string) (*Location, error) {
return parseCacheEntry(addr, string(bytes)) return parseCacheEntry(addr, string(bytes))
} }
func (c *Cache) readFromCacheDB(addr string) (*Location, error) {
result := Location{}
err := c.db.Select(&result).
Where("IP = ?", addr).
Do()
if err != nil {
return nil, err
}
return &result, nil
}
// cacheFile retuns path to the cache entry for addr. // cacheFile retuns path to the cache entry for addr.
func (c *Cache) cacheFile(addr string) string { func (c *Cache) cacheFile(addr string) string {
return path.Join(c.config.Geo.IPCache, addr) return path.Join(c.config.Geo.IPCache, addr)
@ -144,19 +184,15 @@ func (c *Cache) Response(r *http.Request) *routing.Cadre {
return respERR return respERR
} }
result, err := c.getRaw(ip) result, err := c.Read(ip)
if err != nil { if result == nil || err != nil {
return respERR return respERR
} }
return &routing.Cadre{Body: result} return &routing.Cadre{Body: []byte(result.String())}
} }
return nil return nil
} }
func (c *Cache) getRaw(addr string) ([]byte, error) {
return os.ReadFile(c.cacheFile(addr))
}
func (c *Cache) putRaw(addr, value string) error { func (c *Cache) putRaw(addr, value string) error {
return os.WriteFile(c.cacheFile(addr), []byte(value), 0644) return os.WriteFile(c.cacheFile(addr), []byte(value), 0644)
} }

@ -77,12 +77,17 @@ func NewRequestProcessor(config *config.Config) (*RequestProcessor, error) {
}, },
} }
geoCache, err := geoip.NewCache(config)
if err != nil {
return nil, err
}
rp := &RequestProcessor{ rp := &RequestProcessor{
lruCache: lruCache, lruCache: lruCache,
stats: stats.New(), stats: stats.New(),
upstreamTransport: transport, upstreamTransport: transport,
config: config, config: config,
geoIPCache: geoip.NewCache(config), geoIPCache: geoCache,
} }
// Initialize routes. // Initialize routes.

@ -0,0 +1,8 @@
package types
type CacheType string
const (
CacheTypeDB = "db"
CacheTypeFiles = "files"
)

@ -177,7 +177,10 @@ func main() {
} }
if cli.ConvertGeoIPCache { if cli.ConvertGeoIPCache {
geoIPCache := geoip.NewCache(conf) geoIPCache, err := geoip.NewCache(conf)
if err != nil {
ctx.FatalIfErrorf(err)
}
ctx.FatalIfErrorf(geoIPCache.ConvertCache()) ctx.FatalIfErrorf(geoIPCache.ConvertCache())
return return
} }

Loading…
Cancel
Save