forked from abh/geodns
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathconfig.go
145 lines (119 loc) · 2.55 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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
}