diff --git a/README.md b/README.md index 8d136bcf..10906337 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ iis | [Win32_PerfRawData_W3SVC_WebService](https://msdn.microsoft.com/en-us/libr logical_disk | [Win32_PerfRawData_PerfDisk_LogicalDisk](https://msdn.microsoft.com/en-us/windows/hardware/aa394307(v=vs.71)) metrics (disk I/O) | ✓ net | [Win32_PerfRawData_Tcpip_NetworkInterface](https://technet.microsoft.com/en-us/security/aa394340(v=vs.80)) metrics (network interface I/O) | ✓ os | [Win32_OperatingSystem](https://msdn.microsoft.com/en-us/library/aa394239) metrics (memory, processes, users) | ✓ +service | [Win32_Service](https://msdn.microsoft.com/en-us/library/aa394418(v=vs.85).aspx) metrics (service states) | ✓ system | Win32_PerfRawData_PerfOS_System metrics (system calls) | ✓ The HELP texts shows the WMI data source, please see MSDN documentation for details. diff --git a/collector/service.go b/collector/service.go new file mode 100644 index 00000000..11323b6f --- /dev/null +++ b/collector/service.go @@ -0,0 +1,83 @@ +// returns data points from Win32_Service +// https://msdn.microsoft.com/en-us/library/aa394418(v=vs.85).aspx - Win32_Service class +package collector + +import ( + "log" + "strings" + + "github.com/StackExchange/wmi" + "github.com/prometheus/client_golang/prometheus" +) + +func init() { + Factories["service"] = NewserviceCollector +} + +// A serviceCollector is a Prometheus collector for WMI Win32_Service metrics +type serviceCollector struct { + State *prometheus.Desc + StartMode *prometheus.Desc +} + +// NewserviceCollector ... +func NewserviceCollector() (Collector, error) { + const subsystem = "service" + return &serviceCollector{ + State: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "state"), + "The state of the service (State)", + []string{"name", "state"}, + nil, + ), + StartMode: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "start_mode"), + "The start mode of the service (StartMode)", + []string{"name", "start_mode"}, + nil, + ), + }, nil +} + +// Collect sends the metric values for each metric +// to the provided prometheus Metric channel. +func (c *serviceCollector) Collect(ch chan<- prometheus.Metric) error { + if desc, err := c.collect(ch); err != nil { + log.Println("[ERROR] failed collecting service metrics:", desc, err) + return err + } + return nil +} + +type Win32_Service struct { + Name string + State string + StartMode string +} + +func (c *serviceCollector) collect(ch chan<- prometheus.Metric) (*prometheus.Desc, error) { + var dst []Win32_Service + q := wmi.CreateQuery(&dst, "") + if err := wmi.Query(q, &dst); err != nil { + return nil, err + } + + for _, service := range dst { + ch <- prometheus.MustNewConstMetric( + c.State, + prometheus.GaugeValue, + 1.0, + strings.ToLower(service.Name), + strings.ToLower(service.State), + ) + + ch <- prometheus.MustNewConstMetric( + c.StartMode, + prometheus.GaugeValue, + 1.0, + strings.ToLower(service.Name), + strings.ToLower(service.StartMode), + ) + } + return nil, nil +} diff --git a/exporter.go b/exporter.go index 9fa30f71..e5837752 100644 --- a/exporter.go +++ b/exporter.go @@ -25,7 +25,7 @@ type WmiCollector struct { } const ( - defaultCollectors = "cpu,cs,logical_disk,net,os,system" + defaultCollectors = "cpu,cs,logical_disk,net,os,service,system" serviceName = "wmi_exporter" )