-
Notifications
You must be signed in to change notification settings - Fork 25
/
Copy pathmain.go
102 lines (89 loc) · 3.15 KB
/
main.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
package main
import (
"flag"
"net/http"
"github.com/howeyc/fsnotify"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/prometheus/common/log"
)
var (
address = flag.String("beanstalkd.address", "localhost:11300", "Beanstalkd server address")
connectionTimeout = flag.Duration("beanstalkd.connection-timeout", 0, "Timeout value for tcp connection to Beanstalkd")
logLevel = flag.String("log.level", "warning", "The log level.")
mappingConfig = flag.String("mapping-config", "", "A file that describes a mapping of tube names.")
sleepBetweenStats = flag.Int("sleep-between-tube-stats", 5000, "The number of milliseconds to sleep between tube stats.")
numTubeStatWorkers = flag.Int("num-tube-stat-workers", 1, "The number of concurrent workers to use to fetch tube stats.")
listenAddress = flag.String("web.listen-address", ":8080", "Address to listen on for web interface and telemetry.")
metricsPath = flag.String("web.telemetry-path", "/metrics", "Path under which to expose metrics.")
)
var (
mapper *tubeMapper
registry *prometheus.Registry
)
func watchConfig(fileName string, mapper *tubeMapper) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
log.Fatal(err)
}
err = watcher.WatchFlags(fileName, fsnotify.FSN_MODIFY)
if err != nil {
log.Fatal(err)
}
for {
select {
case ev := <-watcher.Event:
log.Warnf("Config file changed (%s), attempting reload", ev)
err = mapper.initFromFile(fileName)
if err != nil {
log.Errorf("Error reloading config: %v", err)
mapper.configLoadsMetric.WithLabelValues("failure").Inc()
} else {
log.Warn("Config reloaded successfully")
mapper.configLoadsMetric.WithLabelValues("success").Inc()
}
// Re-add the file watcher since it can get lost on some changes. E.g.
// saving a file with vim results in a RENAME-MODIFY-DELETE event
// sequence, after which the newly written file is no longer watched.
err = watcher.WatchFlags(fileName, fsnotify.FSN_MODIFY)
case err := <-watcher.Error:
log.Errorf("Error watching config: %v", err)
}
}
}
func main() {
flag.Parse()
if *logLevel == "debug" {
log.Base().SetLevel("debug")
}
mapper = newTubeMapper()
if *mappingConfig != "" {
err := mapper.initFromFile(*mappingConfig)
if err != nil {
log.Fatal("Error loading mapping config:", err)
}
go watchConfig(*mappingConfig, mapper)
}
exporter := NewExporter(*address)
exporter.SetConnectionTimeout(*connectionTimeout)
registry = prometheus.NewRegistry()
registry.MustRegister(exporter)
http.Handle(*metricsPath, promhttp.HandlerFor(
registry,
promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError},
))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`
<html>
<head><title>Beanstalkd Exporter</title></head>
<body>
<h1>Beanstalkd Exporter</h1>
<p><a href='` + *metricsPath + `'>Metrics</a></p>
</body>
</html>
`),
)
})
log.Warnf("Listening on port %s .", *listenAddress)
log.Fatal(http.ListenAndServe(*listenAddress, nil))
}