diff options
author | Calle Pettersson <carlpett@users.noreply.github.com> | 2017-09-28 15:06:26 +0200 |
---|---|---|
committer | Johannes 'fish' Ziemke <github@freigeist.org> | 2017-09-28 15:06:26 +0200 |
commit | 859a825bb84bf4fb911fcba445d410965945f088 (patch) | |
tree | 0726b08cf03c790bff3a34a085cecc01e3b927e2 /node_exporter.go | |
parent | 3762191e66e309106e930ab11f9c080fb4428001 (diff) | |
download | prometheus_node_collector-859a825bb84bf4fb911fcba445d410965945f088.tar.bz2 prometheus_node_collector-859a825bb84bf4fb911fcba445d410965945f088.tar.xz prometheus_node_collector-859a825bb84bf4fb911fcba445d410965945f088.zip |
Replace --collectors.enabled with per-collector flags (#640)
* Move NodeCollector into package collector
* Refactor collector enabling
* Update README with new collector enabled flags
* Fix out-of-date inline flag reference syntax
* Use new flags in end-to-end tests
* Add flag to disable all default collectors
* Track if a flag has been set explicitly
* Add --collectors.disable-defaults to README
* Revert disable-defaults flag
* Shorten flags
* Fixup timex collector registration
* Fix end-to-end tests
* Change procfs and sysfs path flags
* Fix review comments
Diffstat (limited to 'node_exporter.go')
-rw-r--r-- | node_exporter.go | 119 |
1 files changed, 6 insertions, 113 deletions
diff --git a/node_exporter.go b/node_exporter.go index 43facf6..1077188 100644 --- a/node_exporter.go +++ b/node_exporter.go | |||
@@ -14,13 +14,8 @@ | |||
14 | package main | 14 | package main |
15 | 15 | ||
16 | import ( | 16 | import ( |
17 | "fmt" | ||
18 | "net/http" | 17 | "net/http" |
19 | _ "net/http/pprof" | 18 | _ "net/http/pprof" |
20 | "sort" | ||
21 | "strings" | ||
22 | "sync" | ||
23 | "time" | ||
24 | 19 | ||
25 | "github.com/prometheus/client_golang/prometheus" | 20 | "github.com/prometheus/client_golang/prometheus" |
26 | "github.com/prometheus/client_golang/prometheus/promhttp" | 21 | "github.com/prometheus/client_golang/prometheus/promhttp" |
@@ -30,103 +25,14 @@ import ( | |||
30 | "gopkg.in/alecthomas/kingpin.v2" | 25 | "gopkg.in/alecthomas/kingpin.v2" |
31 | ) | 26 | ) |
32 | 27 | ||
33 | const ( | ||
34 | defaultCollectors = "arp,bcache,conntrack,cpu,diskstats,entropy,edac,exec,filefd,filesystem,hwmon,infiniband,ipvs,loadavg,mdadm,meminfo,netdev,netstat,sockstat,stat,textfile,time,timex,uname,vmstat,wifi,xfs,zfs" | ||
35 | ) | ||
36 | |||
37 | var ( | ||
38 | scrapeDurationDesc = prometheus.NewDesc( | ||
39 | prometheus.BuildFQName(collector.Namespace, "scrape", "collector_duration_seconds"), | ||
40 | "node_exporter: Duration of a collector scrape.", | ||
41 | []string{"collector"}, | ||
42 | nil, | ||
43 | ) | ||
44 | scrapeSuccessDesc = prometheus.NewDesc( | ||
45 | prometheus.BuildFQName(collector.Namespace, "scrape", "collector_success"), | ||
46 | "node_exporter: Whether a collector succeeded.", | ||
47 | []string{"collector"}, | ||
48 | nil, | ||
49 | ) | ||
50 | ) | ||
51 | |||
52 | // NodeCollector implements the prometheus.Collector interface. | ||
53 | type NodeCollector struct { | ||
54 | collectors map[string]collector.Collector | ||
55 | } | ||
56 | |||
57 | // Describe implements the prometheus.Collector interface. | ||
58 | func (n NodeCollector) Describe(ch chan<- *prometheus.Desc) { | ||
59 | ch <- scrapeDurationDesc | ||
60 | ch <- scrapeSuccessDesc | ||
61 | } | ||
62 | |||
63 | // Collect implements the prometheus.Collector interface. | ||
64 | func (n NodeCollector) Collect(ch chan<- prometheus.Metric) { | ||
65 | wg := sync.WaitGroup{} | ||
66 | wg.Add(len(n.collectors)) | ||
67 | for name, c := range n.collectors { | ||
68 | go func(name string, c collector.Collector) { | ||
69 | execute(name, c, ch) | ||
70 | wg.Done() | ||
71 | }(name, c) | ||
72 | } | ||
73 | wg.Wait() | ||
74 | } | ||
75 | |||
76 | func filterAvailableCollectors(collectors string) string { | ||
77 | var availableCollectors []string | ||
78 | for _, c := range strings.Split(collectors, ",") { | ||
79 | _, ok := collector.Factories[c] | ||
80 | if ok { | ||
81 | availableCollectors = append(availableCollectors, c) | ||
82 | } | ||
83 | } | ||
84 | return strings.Join(availableCollectors, ",") | ||
85 | } | ||
86 | |||
87 | func execute(name string, c collector.Collector, ch chan<- prometheus.Metric) { | ||
88 | begin := time.Now() | ||
89 | err := c.Update(ch) | ||
90 | duration := time.Since(begin) | ||
91 | var success float64 | ||
92 | |||
93 | if err != nil { | ||
94 | log.Errorf("ERROR: %s collector failed after %fs: %s", name, duration.Seconds(), err) | ||
95 | success = 0 | ||
96 | } else { | ||
97 | log.Debugf("OK: %s collector succeeded after %fs.", name, duration.Seconds()) | ||
98 | success = 1 | ||
99 | } | ||
100 | ch <- prometheus.MustNewConstMetric(scrapeDurationDesc, prometheus.GaugeValue, duration.Seconds(), name) | ||
101 | ch <- prometheus.MustNewConstMetric(scrapeSuccessDesc, prometheus.GaugeValue, success, name) | ||
102 | } | ||
103 | |||
104 | func loadCollectors(list string) (map[string]collector.Collector, error) { | ||
105 | collectors := map[string]collector.Collector{} | ||
106 | for _, name := range strings.Split(list, ",") { | ||
107 | fn, ok := collector.Factories[name] | ||
108 | if !ok { | ||
109 | return nil, fmt.Errorf("collector '%s' not available", name) | ||
110 | } | ||
111 | c, err := fn() | ||
112 | if err != nil { | ||
113 | return nil, err | ||
114 | } | ||
115 | collectors[name] = c | ||
116 | } | ||
117 | return collectors, nil | ||
118 | } | ||
119 | |||
120 | func init() { | 28 | func init() { |
121 | prometheus.MustRegister(version.NewCollector("node_exporter")) | 29 | prometheus.MustRegister(version.NewCollector("node_exporter")) |
122 | } | 30 | } |
123 | 31 | ||
124 | func main() { | 32 | func main() { |
125 | var ( | 33 | var ( |
126 | listenAddress = kingpin.Flag("web.listen-address", "Address on which to expose metrics and web interface.").Default(":9100").String() | 34 | listenAddress = kingpin.Flag("web.listen-address", "Address on which to expose metrics and web interface.").Default(":9100").String() |
127 | metricsPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String() | 35 | metricsPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics.").Default("/metrics").String() |
128 | enabledCollectors = kingpin.Flag("collectors.enabled", "Comma-separated list of collectors to use.").Default(filterAvailableCollectors(defaultCollectors)).String() | ||
129 | printCollectors = kingpin.Flag("collectors.print", "If true, print available collectors and exit.").Bool() | ||
130 | ) | 36 | ) |
131 | 37 | ||
132 | log.AddFlags(kingpin.CommandLine) | 38 | log.AddFlags(kingpin.CommandLine) |
@@ -137,29 +43,16 @@ func main() { | |||
137 | log.Infoln("Starting node_exporter", version.Info()) | 43 | log.Infoln("Starting node_exporter", version.Info()) |
138 | log.Infoln("Build context", version.BuildContext()) | 44 | log.Infoln("Build context", version.BuildContext()) |
139 | 45 | ||
140 | if *printCollectors { | 46 | nc, err := collector.NewNodeCollector() |
141 | collectorNames := make(sort.StringSlice, 0, len(collector.Factories)) | ||
142 | for n := range collector.Factories { | ||
143 | collectorNames = append(collectorNames, n) | ||
144 | } | ||
145 | collectorNames.Sort() | ||
146 | fmt.Printf("Available collectors:\n") | ||
147 | for _, n := range collectorNames { | ||
148 | fmt.Printf(" - %s\n", n) | ||
149 | } | ||
150 | return | ||
151 | } | ||
152 | collectors, err := loadCollectors(*enabledCollectors) | ||
153 | if err != nil { | 47 | if err != nil { |
154 | log.Fatalf("Couldn't load collectors: %s", err) | 48 | log.Fatalf("Couldn't create collector: %s", err) |
155 | } | 49 | } |
156 | |||
157 | log.Infof("Enabled collectors:") | 50 | log.Infof("Enabled collectors:") |
158 | for n := range collectors { | 51 | for n := range nc.Collectors { |
159 | log.Infof(" - %s", n) | 52 | log.Infof(" - %s", n) |
160 | } | 53 | } |
161 | 54 | ||
162 | if err := prometheus.Register(NodeCollector{collectors: collectors}); err != nil { | 55 | if err := prometheus.Register(nc); err != nil { |
163 | log.Fatalf("Couldn't register collector: %s", err) | 56 | log.Fatalf("Couldn't register collector: %s", err) |
164 | } | 57 | } |
165 | handler := promhttp.HandlerFor(prometheus.DefaultGatherer, | 58 | handler := promhttp.HandlerFor(prometheus.DefaultGatherer, |