123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- package main
- import (
- "fmt"
- "log"
- "os"
- "sync"
- "time"
- "github.com/abh/geodns/targeting/geoip2"
- "github.com/fsnotify/fsnotify"
- gcfg "gopkg.in/gcfg.v1"
- )
- type AppConfig struct {
- StatHat struct {
- ApiKey string
- }
- Flags struct {
- HasStatHat bool
- }
- GeoIP struct {
- Directory string
- }
- HTTP struct {
- User string
- Password string
- }
- QueryLog struct {
- Path string
- MaxSize int
- Keep int
- }
- Health struct {
- Directory string
- }
- Nodeping struct {
- Token string
- }
- Pingdom struct {
- Username string
- Password string
- AccountEmail string
- AppKey string
- StateMap string
- }
- }
- var Config = new(AppConfig)
- var cfgMutex sync.RWMutex
- func (conf *AppConfig) HasStatHat() bool {
- cfgMutex.RLock()
- defer cfgMutex.RUnlock()
- return conf.Flags.HasStatHat
- }
- func (conf *AppConfig) StatHatApiKey() string {
- cfgMutex.RLock()
- defer cfgMutex.RUnlock()
- return conf.StatHat.ApiKey
- }
- func (conf *AppConfig) GeoIPDirectory() string {
- cfgMutex.RLock()
- defer cfgMutex.RUnlock()
- if len(conf.GeoIP.Directory) > 0 {
- return conf.GeoIP.Directory
- }
- return geoip2.FindDB()
- }
- func configWatcher(fileName string) {
- watcher, err := fsnotify.NewWatcher()
- if err != nil {
- fmt.Println(err)
- return
- }
- if err := watcher.Add(*flagconfig); err != nil {
- fmt.Println(err)
- return
- }
- for {
- select {
- case ev := <-watcher.Events:
- if ev.Name == fileName {
- // Write = when the file is updated directly
- // Rename = when it's updated atomicly
- // Chmod = for `touch`
- if ev.Op&fsnotify.Write == fsnotify.Write ||
- ev.Op&fsnotify.Rename == fsnotify.Rename ||
- ev.Op&fsnotify.Chmod == fsnotify.Chmod {
- time.Sleep(200 * time.Millisecond)
- configReader(fileName)
- }
- }
- case err := <-watcher.Errors:
- log.Println("fsnotify error:", err)
- }
- }
- }
- var lastReadConfig time.Time
- func configReader(fileName string) error {
- stat, err := os.Stat(fileName)
- if err != nil {
- log.Printf("Failed to find config file: %s\n", err)
- return err
- }
- if !stat.ModTime().After(lastReadConfig) {
- return err
- }
- lastReadConfig = time.Now()
- log.Printf("Loading config: %s\n", fileName)
- cfg := new(AppConfig)
- err = gcfg.ReadFileInto(cfg, fileName)
- if err != nil {
- log.Printf("Failed to parse config data: %s\n", err)
- return err
- }
- cfg.Flags.HasStatHat = len(cfg.StatHat.ApiKey) > 0
- // log.Println("STATHAT APIKEY:", cfg.StatHat.ApiKey)
- // log.Println("STATHAT FLAG :", cfg.Flags.HasStatHat)
- cfgMutex.Lock()
- *Config = *cfg // shallow copy to prevent race conditions in referring to Config.foo()
- cfgMutex.Unlock()
- return nil
- }
|