diff --git a/exporter/exporter.go b/exporter/exporter.go index 6c3f4292..7c347461 100644 --- a/exporter/exporter.go +++ b/exporter/exporter.go @@ -80,12 +80,17 @@ func New(configFile string) (e exporter, err error) { log.Fatalf("Couldn't attach collector: %s", err) } + cr, err := NewRunitCollector(e.config, e.registry) + if err != nil { + log.Fatalf("Couldn't attach collector: %s", err) + } + cg, err := NewGmondCollector(e.config, e.registry) if err != nil { log.Fatalf("Couldn't attach collector: %s", err) } - e.collectors = []Collector{&cn, &cg} + e.collectors = []Collector{&cn, &cr, &cg} if e.config.ListeningAddress != "" { e.listeningAddress = e.config.ListeningAddress diff --git a/exporter/runit_collector.go b/exporter/runit_collector.go new file mode 100644 index 00000000..bea9dcd5 --- /dev/null +++ b/exporter/runit_collector.go @@ -0,0 +1,63 @@ +package exporter + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/soundcloud/go-runit/runit" +) + +var () + +type runitCollector struct { + name string + config config + serviceStatus prometheus.Gauge +} + +func NewRunitCollector(config config, registry prometheus.Registry) (runitCollector, error) { + c := runitCollector{ + name: "runit_collector", + config: config, + serviceStatus: prometheus.NewGauge(), + } + + registry.Register( + "node_service_status", + "node_exporter: status of runit service.", + prometheus.NilLabels, + c.serviceStatus, + ) + + return c, nil +} + +func (c *runitCollector) Name() string { return c.name } + +func (c *runitCollector) Update() (updates int, err error) { + services, err := runit.GetServices() + if err != nil { + return 0, err + } + + for _, service := range services { + status, err := service.Status() + if err != nil { + return 0, err + } + debug(c.Name(), "%s is %d on pid %d for %d seconds", service.Name, status.State, status.Pid, status.Duration) + labels := map[string]string{ + "name": service.Name, + "state": runit.StateToString[status.State], + "want": runit.StateToString[status.Want], + } + + if status.NormallyUp { + labels["normally_up"] = "yes" + } else { + labels["normally_up"] = "no" + } + + c.serviceStatus.Set(labels, float64(status.Duration)) + updates++ + } + return updates, err +}