From 32724a10b099c850b308bb8ba484782a591ef407 Mon Sep 17 00:00:00 2001 From: Johannes 'fish' Ziemke Date: Mon, 28 Jul 2014 12:36:28 +0200 Subject: [PATCH 1/2] Add NTP exporter This exporter gets the time from a NTP server and exposes the offset between the remote and local system time. --- collector/ntp.go | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 collector/ntp.go diff --git a/collector/ntp.go b/collector/ntp.go new file mode 100644 index 00000000..3e3ca041 --- /dev/null +++ b/collector/ntp.go @@ -0,0 +1,56 @@ +// +build !nontp + +package collector + +import ( + "flag" + "fmt" + "time" + + "github.com/beevik/ntp" + "github.com/golang/glog" + "github.com/prometheus/client_golang/prometheus" +) + +var ( + ntpServer = flag.String("ntpServer", "", "NTP server to use for ntp collector.") + ntpDrift = prometheus.NewGauge(prometheus.GaugeOpts{ + Namespace: Namespace, + Name: "ntp_drift_seconds", + Help: "Time between system time and ntp time.", + }) +) + +type ntpCollector struct { +} + +func init() { + Factories["ntp"] = NewNtpCollector +} + +// Takes a config struct and prometheus registry and returns a new Collector exposing +// the offset between ntp and the current system time. +func NewNtpCollector(config Config) (Collector, error) { + if *ntpServer == "" { + return nil, fmt.Errorf("No NTP server specifies, see --ntpServer") + } + c := ntpCollector{} + + if _, err := prometheus.RegisterOrGet(ntpDrift); err != nil { + return nil, err + } + return &c, nil +} + +func (c *ntpCollector) Update() (updates int, err error) { + t, err := ntp.Time(*ntpServer) + if err != nil { + return updates, fmt.Errorf("Couldn't get ntp drift: %s", err) + } + drift := t.Sub(time.Now()) + updates++ + glog.V(1).Infof("Set ntp_drift_seconds: %f", drift.Seconds()) + ntpDrift.Set(drift.Seconds()) + + return updates, err +} From 2b3a112b54d27d7b1ac7dc8f503180bbaf038c77 Mon Sep 17 00:00:00 2001 From: Johannes 'fish' Ziemke Date: Mon, 28 Jul 2014 12:37:01 +0200 Subject: [PATCH 2/2] Add time exporter This simple exporter exposes the systems unix time. It's useful to compare it to the prometheus server time and other targets to detect clock skew. --- collector/time.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ node_exporter.go | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 collector/time.go diff --git a/collector/time.go b/collector/time.go new file mode 100644 index 00000000..172de88f --- /dev/null +++ b/collector/time.go @@ -0,0 +1,47 @@ +// +build !notime + +package collector + +import ( + "time" + + "github.com/golang/glog" + "github.com/prometheus/client_golang/prometheus" +) + +var ( + systemTime = prometheus.NewCounter(prometheus.CounterOpts{ + Namespace: Namespace, + Name: "time", + Help: "System time in seconds since epoch (1970).", + }) +) + +type timeCollector struct { + config Config +} + +func init() { + Factories["time"] = NewTimeCollector +} + +// Takes a config struct and prometheus registry and returns a new Collector exposing +// the current system time in seconds since epoch. +func NewTimeCollector(config Config) (Collector, error) { + c := timeCollector{ + config: config, + } + + if _, err := prometheus.RegisterOrGet(systemTime); err != nil { + return nil, err + } + return &c, nil +} + +func (c *timeCollector) Update() (updates int, err error) { + updates++ + now := time.Now() + glog.V(1).Infof("Set time: %f", now.Unix()) + systemTime.Set(float64(now.Unix())) + return updates, err +} diff --git a/node_exporter.go b/node_exporter.go index 7622cc61..0d8e7b99 100644 --- a/node_exporter.go +++ b/node_exporter.go @@ -26,7 +26,7 @@ var ( configFile = flag.String("config", "node_exporter.conf", "config file.") memProfile = flag.String("memprofile", "", "write memory profile to this file") listeningAddress = flag.String("listen", ":8080", "address to listen on") - enabledCollectors = flag.String("enabledCollectors", "attributes,diskstats,filesystem,loadavg,meminfo,stat,netdev", "comma-seperated list of collectors to use") + enabledCollectors = flag.String("enabledCollectors", "attributes,diskstats,filesystem,loadavg,meminfo,stat,time,netdev", "comma-seperated list of collectors to use") printCollectors = flag.Bool("printCollectors", false, "If true, print available collectors and exit") interval = flag.Duration("interval", 60*time.Second, "refresh interval")