mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-27 15:16:35 +00:00
make enabled collectors configurable (based on code from node_exporter)
This commit is contained in:
@@ -13,6 +13,10 @@ import (
|
|||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Factories["iis"] = NewIISCollector
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
siteWhitelist = flag.String("collector.iis.site-whitelist", ".+", "Regexp of sites to whitelist. Site name must both match whitelist and not match blacklist to be included.")
|
siteWhitelist = flag.String("collector.iis.site-whitelist", ".+", "Regexp of sites to whitelist. Site name must both match whitelist and not match blacklist to be included.")
|
||||||
siteBlacklist = flag.String("collector.iis.site-blacklist", "", "Regexp of sites to blacklist. Site name must both match whitelist and not match blacklist to be included.")
|
siteBlacklist = flag.String("collector.iis.site-blacklist", "", "Regexp of sites to blacklist. Site name must both match whitelist and not match blacklist to be included.")
|
||||||
@@ -48,43 +52,43 @@ type IISCollector struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewIISCollector ...
|
// NewIISCollector ...
|
||||||
func NewIISCollector() *IISCollector {
|
func NewIISCollector() (Collector, error) {
|
||||||
const subsystem = "iis"
|
const subsystem = "iis"
|
||||||
|
|
||||||
return &IISCollector{
|
return &IISCollector{
|
||||||
// Gauges
|
// Gauges
|
||||||
CurrentAnonymousUsers: prometheus.NewDesc(
|
CurrentAnonymousUsers: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "current_anonymous_users"),
|
prometheus.BuildFQName(Namespace, subsystem, "current_anonymous_users"),
|
||||||
"Number of users who currently have an anonymous connection using the Web service (WebService.CurrentAnonymousUsers)",
|
"Number of users who currently have an anonymous connection using the Web service (WebService.CurrentAnonymousUsers)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
CurrentBlockedAsyncIORequests: prometheus.NewDesc(
|
CurrentBlockedAsyncIORequests: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "current_blocked_async_io_requests"),
|
prometheus.BuildFQName(Namespace, subsystem, "current_blocked_async_io_requests"),
|
||||||
"Current requests temporarily blocked due to bandwidth throttling settings (WebService.CurrentBlockedAsyncIORequests)",
|
"Current requests temporarily blocked due to bandwidth throttling settings (WebService.CurrentBlockedAsyncIORequests)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
CurrentCGIRequests: prometheus.NewDesc(
|
CurrentCGIRequests: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "current_cgi_requests"),
|
prometheus.BuildFQName(Namespace, subsystem, "current_cgi_requests"),
|
||||||
"Current number of CGI requests being simultaneously processed by the Web service (WebService.CurrentCGIRequests)",
|
"Current number of CGI requests being simultaneously processed by the Web service (WebService.CurrentCGIRequests)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
CurrentConnections: prometheus.NewDesc(
|
CurrentConnections: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "current_connections"),
|
prometheus.BuildFQName(Namespace, subsystem, "current_connections"),
|
||||||
"Current number of connections established with the Web service (WebService.CurrentConnections)",
|
"Current number of connections established with the Web service (WebService.CurrentConnections)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
CurrentISAPIExtensionRequests: prometheus.NewDesc(
|
CurrentISAPIExtensionRequests: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "current_isapi_extension_requests"),
|
prometheus.BuildFQName(Namespace, subsystem, "current_isapi_extension_requests"),
|
||||||
"Current number of ISAPI requests being simultaneously processed by the Web service (WebService.CurrentISAPIExtensionRequests)",
|
"Current number of ISAPI requests being simultaneously processed by the Web service (WebService.CurrentISAPIExtensionRequests)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
CurrentNonAnonymousUsers: prometheus.NewDesc(
|
CurrentNonAnonymousUsers: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "current_non_anonymous_users"),
|
prometheus.BuildFQName(Namespace, subsystem, "current_non_anonymous_users"),
|
||||||
"Number of users who currently have a non-anonymous connection using the Web service (WebService.CurrentNonAnonymousUsers)",
|
"Number of users who currently have a non-anonymous connection using the Web service (WebService.CurrentNonAnonymousUsers)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
@@ -92,91 +96,91 @@ func NewIISCollector() *IISCollector {
|
|||||||
|
|
||||||
// Counters
|
// Counters
|
||||||
TotalBytesReceived: prometheus.NewDesc(
|
TotalBytesReceived: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "received_bytes_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "received_bytes_total"),
|
||||||
"Number of data bytes that have been received by the Web service (WebService.TotalBytesReceived)",
|
"Number of data bytes that have been received by the Web service (WebService.TotalBytesReceived)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalBytesSent: prometheus.NewDesc(
|
TotalBytesSent: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "sent_bytes_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "sent_bytes_total"),
|
||||||
"Number of data bytes that have been sent by the Web service (WebService.TotalBytesSent)",
|
"Number of data bytes that have been sent by the Web service (WebService.TotalBytesSent)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalAnonymousUsers: prometheus.NewDesc(
|
TotalAnonymousUsers: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "anonymous_users_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "anonymous_users_total"),
|
||||||
"Total number of users who established an anonymous connection with the Web service (WebService.TotalAnonymousUsers)",
|
"Total number of users who established an anonymous connection with the Web service (WebService.TotalAnonymousUsers)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalBlockedAsyncIORequests: prometheus.NewDesc(
|
TotalBlockedAsyncIORequests: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "blocked_async_io_requests_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "blocked_async_io_requests_total"),
|
||||||
"Total requests temporarily blocked due to bandwidth throttling settings (WebService.TotalBlockedAsyncIORequests)",
|
"Total requests temporarily blocked due to bandwidth throttling settings (WebService.TotalBlockedAsyncIORequests)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalCGIRequests: prometheus.NewDesc(
|
TotalCGIRequests: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "cgi_requests_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "cgi_requests_total"),
|
||||||
"Total CGI requests is the total number of CGI requests (WebService.TotalCGIRequests)",
|
"Total CGI requests is the total number of CGI requests (WebService.TotalCGIRequests)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalConnectionAttemptsAllInstances: prometheus.NewDesc(
|
TotalConnectionAttemptsAllInstances: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "connection_attempts_all_instances_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "connection_attempts_all_instances_total"),
|
||||||
"Number of connections that have been attempted using the Web service (WebService.TotalConnectionAttemptsAllInstances)",
|
"Number of connections that have been attempted using the Web service (WebService.TotalConnectionAttemptsAllInstances)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalRequests: prometheus.NewDesc(
|
TotalRequests: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "requests_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "requests_total"),
|
||||||
"Number of HTTP requests (WebService.TotalRequests)",
|
"Number of HTTP requests (WebService.TotalRequests)",
|
||||||
[]string{"site", "method"},
|
[]string{"site", "method"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalFilesReceived: prometheus.NewDesc(
|
TotalFilesReceived: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "files_received_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "files_received_total"),
|
||||||
"Number of files received by the Web service (WebService.TotalFilesReceived)",
|
"Number of files received by the Web service (WebService.TotalFilesReceived)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalFilesSent: prometheus.NewDesc(
|
TotalFilesSent: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "files_sent_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "files_sent_total"),
|
||||||
"Number of files sent by the Web service (WebService.TotalFilesSent)",
|
"Number of files sent by the Web service (WebService.TotalFilesSent)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalISAPIExtensionRequests: prometheus.NewDesc(
|
TotalISAPIExtensionRequests: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "ipapi_extension_requests_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "ipapi_extension_requests_total"),
|
||||||
"ISAPI Extension Requests received (WebService.TotalISAPIExtensionRequests)",
|
"ISAPI Extension Requests received (WebService.TotalISAPIExtensionRequests)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalLockedErrors: prometheus.NewDesc(
|
TotalLockedErrors: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "locked_errors_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "locked_errors_total"),
|
||||||
"Number of requests that couldn't be satisfied by the server because the requested resource was locked (WebService.TotalLockedErrors)",
|
"Number of requests that couldn't be satisfied by the server because the requested resource was locked (WebService.TotalLockedErrors)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalLogonAttempts: prometheus.NewDesc(
|
TotalLogonAttempts: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "logon_attempts_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "logon_attempts_total"),
|
||||||
"Number of logons attempts to the Web Service (WebService.TotalLogonAttempts)",
|
"Number of logons attempts to the Web Service (WebService.TotalLogonAttempts)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalNonAnonymousUsers: prometheus.NewDesc(
|
TotalNonAnonymousUsers: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "non_anonymous_users_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "non_anonymous_users_total"),
|
||||||
"Number of users who established a non-anonymous connection with the Web service (WebService.TotalNonAnonymousUsers)",
|
"Number of users who established a non-anonymous connection with the Web service (WebService.TotalNonAnonymousUsers)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalNotFoundErrors: prometheus.NewDesc(
|
TotalNotFoundErrors: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "not_found_errors_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "not_found_errors_total"),
|
||||||
"Number of requests that couldn't be satisfied by the server because the requested document could not be found (WebService.TotalNotFoundErrors)",
|
"Number of requests that couldn't be satisfied by the server because the requested document could not be found (WebService.TotalNotFoundErrors)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
TotalRejectedAsyncIORequests: prometheus.NewDesc(
|
TotalRejectedAsyncIORequests: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "rejected_async_io_requests_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "rejected_async_io_requests_total"),
|
||||||
"Requests rejected due to bandwidth throttling settings (WebService.TotalRejectedAsyncIORequests)",
|
"Requests rejected due to bandwidth throttling settings (WebService.TotalRejectedAsyncIORequests)",
|
||||||
[]string{"site"},
|
[]string{"site"},
|
||||||
nil,
|
nil,
|
||||||
@@ -184,22 +188,17 @@ func NewIISCollector() *IISCollector {
|
|||||||
|
|
||||||
siteWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteWhitelist)),
|
siteWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteWhitelist)),
|
||||||
siteBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteBlacklist)),
|
siteBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *siteBlacklist)),
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *IISCollector) Collect(ch chan<- prometheus.Metric) {
|
func (c *IISCollector) Collect(ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if desc, err := c.collect(ch); err != nil {
|
||||||
log.Println("[ERROR] failed collecting iis metrics:", desc, err)
|
log.Println("[ERROR] failed collecting iis metrics:", desc, err)
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
}
|
return nil
|
||||||
|
|
||||||
// Describe sends the descriptors of each metric over to the provided channel.
|
|
||||||
// The corresponding metric values are sent separately.
|
|
||||||
func (c *IISCollector) Describe(ch chan<- *prometheus.Desc) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Win32_PerfRawData_W3SVC_WebService struct {
|
type Win32_PerfRawData_W3SVC_WebService struct {
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ import (
|
|||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Factories["logical_disk"] = NewLogicalDiskCollector
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ticksToSecondsScaleFactor = 1 / 1e7
|
ticksToSecondsScaleFactor = 1 / 1e7
|
||||||
)
|
)
|
||||||
@@ -42,82 +46,82 @@ type LogicalDiskCollector struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewLogicalDiskCollector ...
|
// NewLogicalDiskCollector ...
|
||||||
func NewLogicalDiskCollector() *LogicalDiskCollector {
|
func NewLogicalDiskCollector() (Collector, error) {
|
||||||
const subsystem = "logical_disk"
|
const subsystem = "logical_disk"
|
||||||
|
|
||||||
return &LogicalDiskCollector{
|
return &LogicalDiskCollector{
|
||||||
RequestsQueued: prometheus.NewDesc(
|
RequestsQueued: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "requests_queued"),
|
prometheus.BuildFQName(Namespace, subsystem, "requests_queued"),
|
||||||
"The number of requests queued to the disk (LogicalDisk.CurrentDiskQueueLength)",
|
"The number of requests queued to the disk (LogicalDisk.CurrentDiskQueueLength)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
ReadBytesTotal: prometheus.NewDesc(
|
ReadBytesTotal: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "read_bytes_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "read_bytes_total"),
|
||||||
"The number of bytes transferred from the disk during read operations (LogicalDisk.DiskReadBytesPerSec)",
|
"The number of bytes transferred from the disk during read operations (LogicalDisk.DiskReadBytesPerSec)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
ReadsTotal: prometheus.NewDesc(
|
ReadsTotal: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "reads_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "reads_total"),
|
||||||
"The number of read operations on the disk (LogicalDisk.DiskReadsPerSec)",
|
"The number of read operations on the disk (LogicalDisk.DiskReadsPerSec)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
WriteBytesTotal: prometheus.NewDesc(
|
WriteBytesTotal: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "write_bytes_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "write_bytes_total"),
|
||||||
"The number of bytes transferred to the disk during write operations (LogicalDisk.DiskWriteBytesPerSec)",
|
"The number of bytes transferred to the disk during write operations (LogicalDisk.DiskWriteBytesPerSec)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
WritesTotal: prometheus.NewDesc(
|
WritesTotal: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "writes_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "writes_total"),
|
||||||
"The number of write operations on the disk (LogicalDisk.DiskWritesPerSec)",
|
"The number of write operations on the disk (LogicalDisk.DiskWritesPerSec)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
ReadTime: prometheus.NewDesc(
|
ReadTime: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "read_seconds_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "read_seconds_total"),
|
||||||
"Seconds that the disk was busy servicing read requests (LogicalDisk.PercentDiskReadTime)",
|
"Seconds that the disk was busy servicing read requests (LogicalDisk.PercentDiskReadTime)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
WriteTime: prometheus.NewDesc(
|
WriteTime: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "write_seconds_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "write_seconds_total"),
|
||||||
"Seconds that the disk was busy servicing write requests (LogicalDisk.PercentDiskWriteTime)",
|
"Seconds that the disk was busy servicing write requests (LogicalDisk.PercentDiskWriteTime)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
FreeSpace: prometheus.NewDesc(
|
FreeSpace: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "free_bytes"),
|
prometheus.BuildFQName(Namespace, subsystem, "free_bytes"),
|
||||||
"Free space in bytes (LogicalDisk.PercentFreeSpace)",
|
"Free space in bytes (LogicalDisk.PercentFreeSpace)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
TotalSpace: prometheus.NewDesc(
|
TotalSpace: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "size_bytes"),
|
prometheus.BuildFQName(Namespace, subsystem, "size_bytes"),
|
||||||
"Total space in bytes (LogicalDisk.PercentFreeSpace_Base)",
|
"Total space in bytes (LogicalDisk.PercentFreeSpace_Base)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
IdleTime: prometheus.NewDesc(
|
IdleTime: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "idle_seconds_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "idle_seconds_total"),
|
||||||
"Seconds that the disk was idle (LogicalDisk.PercentIdleTime)",
|
"Seconds that the disk was idle (LogicalDisk.PercentIdleTime)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
SplitIOs: prometheus.NewDesc(
|
SplitIOs: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, subsystem, "split_ios_total"),
|
prometheus.BuildFQName(Namespace, subsystem, "split_ios_total"),
|
||||||
"The number of I/Os to the disk were split into multiple I/Os (LogicalDisk.SplitIOPerSec)",
|
"The number of I/Os to the disk were split into multiple I/Os (LogicalDisk.SplitIOPerSec)",
|
||||||
[]string{"volume"},
|
[]string{"volume"},
|
||||||
nil,
|
nil,
|
||||||
@@ -125,33 +129,17 @@ func NewLogicalDiskCollector() *LogicalDiskCollector {
|
|||||||
|
|
||||||
volumeWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeWhitelist)),
|
volumeWhitelistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeWhitelist)),
|
||||||
volumeBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeBlacklist)),
|
volumeBlacklistPattern: regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *volumeBlacklist)),
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *LogicalDiskCollector) Collect(ch chan<- prometheus.Metric) {
|
func (c *LogicalDiskCollector) Collect(ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if desc, err := c.collect(ch); err != nil {
|
||||||
log.Println("[ERROR] failed collecting logical_disk metrics:", desc, err)
|
log.Println("[ERROR] failed collecting logical_disk metrics:", desc, err)
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
}
|
return nil
|
||||||
|
|
||||||
// Describe sends the descriptors of each metric over to the provided channel.
|
|
||||||
// The corresponding metric values are sent separately.
|
|
||||||
func (c *LogicalDiskCollector) Describe(ch chan<- *prometheus.Desc) {
|
|
||||||
|
|
||||||
ch <- c.RequestsQueued
|
|
||||||
ch <- c.ReadBytesTotal
|
|
||||||
ch <- c.ReadsTotal
|
|
||||||
ch <- c.WriteBytesTotal
|
|
||||||
ch <- c.WritesTotal
|
|
||||||
ch <- c.ReadTime
|
|
||||||
ch <- c.WriteTime
|
|
||||||
ch <- c.FreeSpace
|
|
||||||
ch <- c.TotalSpace
|
|
||||||
ch <- c.IdleTime
|
|
||||||
ch <- c.SplitIOs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Win32_PerfRawData_PerfDisk_LogicalDisk struct {
|
type Win32_PerfRawData_PerfDisk_LogicalDisk struct {
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ import (
|
|||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Factories["os"] = NewOSCollector
|
||||||
|
}
|
||||||
|
|
||||||
// A OSCollector is a Prometheus collector for WMI Win32_OperatingSystem metrics
|
// A OSCollector is a Prometheus collector for WMI Win32_OperatingSystem metrics
|
||||||
type OSCollector struct {
|
type OSCollector struct {
|
||||||
PhysicalMemoryFreeBytes *prometheus.Desc
|
PhysicalMemoryFreeBytes *prometheus.Desc
|
||||||
@@ -25,105 +29,92 @@ type OSCollector struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewOSCollector ...
|
// NewOSCollector ...
|
||||||
func NewOSCollector() *OSCollector {
|
func NewOSCollector() (Collector, error) {
|
||||||
|
|
||||||
|
const subsystem = "os"
|
||||||
|
|
||||||
return &OSCollector{
|
return &OSCollector{
|
||||||
|
|
||||||
PagingMaxBytes: prometheus.NewDesc(
|
PagingMaxBytes: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, "os", "paging_max_bytes"),
|
prometheus.BuildFQName(Namespace, subsystem, "paging_max_bytes"),
|
||||||
"SizeStoredInPagingFiles",
|
"SizeStoredInPagingFiles",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
PagingFreeBytes: prometheus.NewDesc(
|
PagingFreeBytes: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, "os", "paging_free_bytes"),
|
prometheus.BuildFQName(Namespace, subsystem, "paging_free_bytes"),
|
||||||
"FreeSpaceInPagingFiles",
|
"FreeSpaceInPagingFiles",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
PhysicalMemoryFreeBytes: prometheus.NewDesc(
|
PhysicalMemoryFreeBytes: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, "os", "physical_memory_free_bytes"),
|
prometheus.BuildFQName(Namespace, subsystem, "physical_memory_free_bytes"),
|
||||||
"FreePhysicalMemory",
|
"FreePhysicalMemory",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
Processes: prometheus.NewDesc(
|
Processes: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, "os", "processes"),
|
prometheus.BuildFQName(Namespace, subsystem, "processes"),
|
||||||
"NumberOfProcesses",
|
"NumberOfProcesses",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
ProcessesMax: prometheus.NewDesc(
|
ProcessesMax: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, "os", "processes_max"),
|
prometheus.BuildFQName(Namespace, subsystem, "processes_max"),
|
||||||
"MaxNumberOfProcesses",
|
"MaxNumberOfProcesses",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
ProcessMemoryMaxBytes: prometheus.NewDesc(
|
ProcessMemoryMaxBytes: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, "os", "process_memory_max_bytes"),
|
prometheus.BuildFQName(Namespace, subsystem, "process_memory_max_bytes"),
|
||||||
"MaxProcessMemorySize",
|
"MaxProcessMemorySize",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
Users: prometheus.NewDesc(
|
Users: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, "os", "users"),
|
prometheus.BuildFQName(Namespace, subsystem, "users"),
|
||||||
"NumberOfUsers",
|
"NumberOfUsers",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
VirtualMemoryBytes: prometheus.NewDesc(
|
VirtualMemoryBytes: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, "os", "virtual_memory_bytes"),
|
prometheus.BuildFQName(Namespace, subsystem, "virtual_memory_bytes"),
|
||||||
"TotalVirtualMemorySize",
|
"TotalVirtualMemorySize",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
VisibleMemoryBytes: prometheus.NewDesc(
|
VisibleMemoryBytes: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, "os", "visible_memory_bytes"),
|
prometheus.BuildFQName(Namespace, subsystem, "visible_memory_bytes"),
|
||||||
"TotalVisibleMemorySize",
|
"TotalVisibleMemorySize",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
|
|
||||||
VirtualMemoryFreeBytes: prometheus.NewDesc(
|
VirtualMemoryFreeBytes: prometheus.NewDesc(
|
||||||
prometheus.BuildFQName(wmiNamespace, "os", "virtual_memory_free_bytes"),
|
prometheus.BuildFQName(Namespace, subsystem, "virtual_memory_free_bytes"),
|
||||||
"FreeVirtualMemory",
|
"FreeVirtualMemory",
|
||||||
nil,
|
nil,
|
||||||
nil,
|
nil,
|
||||||
),
|
),
|
||||||
}
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect sends the metric values for each metric
|
// Collect sends the metric values for each metric
|
||||||
// to the provided prometheus Metric channel.
|
// to the provided prometheus Metric channel.
|
||||||
func (c *OSCollector) Collect(ch chan<- prometheus.Metric) {
|
func (c *OSCollector) Collect(ch chan<- prometheus.Metric) error {
|
||||||
if desc, err := c.collect(ch); err != nil {
|
if desc, err := c.collect(ch); err != nil {
|
||||||
log.Println("[ERROR] failed collecting os metrics:", desc, err)
|
log.Println("[ERROR] failed collecting os metrics:", desc, err)
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
}
|
return nil
|
||||||
|
|
||||||
// Describe sends the descriptors of each metric over to the provided channel.
|
|
||||||
// The corresponding metric values are sent separately.
|
|
||||||
func (c *OSCollector) Describe(ch chan<- *prometheus.Desc) {
|
|
||||||
|
|
||||||
ch <- c.PhysicalMemoryFreeBytes
|
|
||||||
ch <- c.PagingFreeBytes
|
|
||||||
ch <- c.VirtualMemoryFreeBytes
|
|
||||||
ch <- c.ProcessesMax
|
|
||||||
ch <- c.ProcessMemoryMaxBytes
|
|
||||||
ch <- c.Processes
|
|
||||||
ch <- c.Users
|
|
||||||
ch <- c.PagingMaxBytes
|
|
||||||
ch <- c.VirtualMemoryBytes
|
|
||||||
ch <- c.VisibleMemoryBytes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Win32_OperatingSystem struct {
|
type Win32_OperatingSystem struct {
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
package collector
|
package collector
|
||||||
|
|
||||||
|
import "github.com/prometheus/client_golang/prometheus"
|
||||||
|
|
||||||
|
// ...
|
||||||
const (
|
const (
|
||||||
wmiNamespace = "wmi"
|
Namespace = "wmi"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Factories ...
|
||||||
|
var Factories = make(map[string]func() (Collector, error))
|
||||||
|
|
||||||
|
// Collector is the interface a collector has to implement.
|
||||||
|
type Collector interface {
|
||||||
|
// Get new metrics and expose them via prometheus registry.
|
||||||
|
Collect(ch chan<- prometheus.Metric) (err error)
|
||||||
|
}
|
||||||
|
|||||||
159
exporter.go
159
exporter.go
@@ -2,76 +2,161 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"log"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/martinlindhe/wmi_exporter/collector"
|
"github.com/martinlindhe/wmi_exporter/collector"
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
"github.com/prometheus/common/log"
|
||||||
|
"github.com/prometheus/common/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
// WmiExporter wraps all the WMI collectors and provides a single global
|
// WmiCollector implements the prometheus.Collector interface.
|
||||||
// exporter to extracts metrics out of. It also ensures that the collection
|
type WmiCollector struct {
|
||||||
// is done in a thread-safe manner, the necessary requirement stated by
|
collectors map[string]collector.Collector
|
||||||
// prometheus. It also implements a prometheus.Collector interface in order
|
|
||||||
// to register it correctly.
|
|
||||||
type WmiExporter struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
collectors []prometheus.Collector
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that the WmiExporter implements the prometheus.Collector interface.
|
const (
|
||||||
var _ prometheus.Collector = &WmiExporter{}
|
defaultCollectors = "logical_disk,os"
|
||||||
|
)
|
||||||
|
|
||||||
// NewWmiExporter creates an instance to WmiExporter and returns a reference
|
var (
|
||||||
// to it. We can choose to enable a collector to extract stats out of by adding
|
scrapeDurations = prometheus.NewSummaryVec(
|
||||||
// it to the list of collectors.
|
prometheus.SummaryOpts{
|
||||||
func NewWmiExporter() *WmiExporter {
|
Namespace: collector.Namespace,
|
||||||
return &WmiExporter{
|
Subsystem: "exporter",
|
||||||
collectors: []prometheus.Collector{
|
Name: "scrape_duration_seconds",
|
||||||
collector.NewOSCollector(),
|
Help: "wmi_exporter: Duration of a scrape job.",
|
||||||
collector.NewLogicalDiskCollector(),
|
|
||||||
collector.NewIISCollector(),
|
|
||||||
},
|
},
|
||||||
}
|
[]string{"collector", "result"},
|
||||||
}
|
)
|
||||||
|
)
|
||||||
|
|
||||||
// Describe sends all the descriptors of the collectors included to
|
// Describe sends all the descriptors of the collectors included to
|
||||||
// the provided channel.
|
// the provided channel.
|
||||||
func (c *WmiExporter) Describe(ch chan<- *prometheus.Desc) {
|
func (coll WmiCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||||
for _, cc := range c.collectors {
|
scrapeDurations.Describe(ch)
|
||||||
cc.Describe(ch)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect sends the collected metrics from each of the collectors to
|
// Collect sends the collected metrics from each of the collectors to
|
||||||
// prometheus. Collect could be called several times concurrently
|
// prometheus. Collect could be called several times concurrently
|
||||||
// and thus its run is protected by a single mutex.
|
// and thus its run is protected by a single mutex.
|
||||||
func (c *WmiExporter) Collect(ch chan<- prometheus.Metric) {
|
func (coll WmiCollector) Collect(ch chan<- prometheus.Metric) {
|
||||||
c.mu.Lock()
|
wg := sync.WaitGroup{}
|
||||||
defer c.mu.Unlock()
|
wg.Add(len(coll.collectors))
|
||||||
|
for name, c := range coll.collectors {
|
||||||
for _, cc := range c.collectors {
|
go func(name string, c collector.Collector) {
|
||||||
cc.Collect(ch)
|
execute(name, c, ch)
|
||||||
|
wg.Done()
|
||||||
|
}(name, c)
|
||||||
}
|
}
|
||||||
|
wg.Wait()
|
||||||
|
scrapeDurations.Collect(ch)
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterAvailableCollectors(collectors string) string {
|
||||||
|
var availableCollectors []string
|
||||||
|
for _, c := range strings.Split(collectors, ",") {
|
||||||
|
_, ok := collector.Factories[c]
|
||||||
|
if ok {
|
||||||
|
availableCollectors = append(availableCollectors, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(availableCollectors, ",")
|
||||||
|
}
|
||||||
|
|
||||||
|
func execute(name string, c collector.Collector, ch chan<- prometheus.Metric) {
|
||||||
|
begin := time.Now()
|
||||||
|
err := c.Collect(ch)
|
||||||
|
duration := time.Since(begin)
|
||||||
|
var result string
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("ERROR: %s collector failed after %fs: %s", name, duration.Seconds(), err)
|
||||||
|
result = "error"
|
||||||
|
} else {
|
||||||
|
log.Debugf("OK: %s collector succeeded after %fs.", name, duration.Seconds())
|
||||||
|
result = "success"
|
||||||
|
}
|
||||||
|
scrapeDurations.WithLabelValues(name, result).Observe(duration.Seconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCollectors(list string) (map[string]collector.Collector, error) {
|
||||||
|
collectors := map[string]collector.Collector{}
|
||||||
|
for _, name := range strings.Split(list, ",") {
|
||||||
|
fn, ok := collector.Factories[name]
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("collector '%s' not available", name)
|
||||||
|
}
|
||||||
|
c, err := fn()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
collectors[name] = c
|
||||||
|
}
|
||||||
|
return collectors, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
prometheus.MustRegister(version.NewCollector("wmi_exporter"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var (
|
var (
|
||||||
addr = flag.String("telemetry.addr", ":9182", "host:port for WMI exporter")
|
showVersion = flag.Bool("version", false, "Print version information.")
|
||||||
metricsPath = flag.String("telemetry.path", "/metrics", "URL path for surfacing collected metrics")
|
listenAddress = flag.String("telemetry.addr", ":9182", "host:port for WMI exporter.")
|
||||||
|
metricsPath = flag.String("telemetry.path", "/metrics", "URL path for surfacing collected metrics.")
|
||||||
|
enabledCollectors = flag.String("collectors.enabled", filterAvailableCollectors(defaultCollectors), "Comma-separated list of collectors to use.")
|
||||||
|
printCollectors = flag.Bool("collectors.print", false, "If true, print available collectors and exit.")
|
||||||
)
|
)
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
prometheus.MustRegister(NewWmiExporter())
|
if *showVersion {
|
||||||
|
fmt.Fprintln(os.Stdout, version.Print("wmi_exporter"))
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *printCollectors {
|
||||||
|
collectorNames := make(sort.StringSlice, 0, len(collector.Factories))
|
||||||
|
for n := range collector.Factories {
|
||||||
|
collectorNames = append(collectorNames, n)
|
||||||
|
}
|
||||||
|
collectorNames.Sort()
|
||||||
|
fmt.Printf("Available collectors:\n")
|
||||||
|
for _, n := range collectorNames {
|
||||||
|
fmt.Printf(" - %s\n", n)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
collectors, err := loadCollectors(*enabledCollectors)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Couldn't load collectors: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Infof("Enabled collectors:")
|
||||||
|
for n := range collectors {
|
||||||
|
log.Infof(" - %s", n)
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeCollector := WmiCollector{collectors: collectors}
|
||||||
|
prometheus.MustRegister(nodeCollector)
|
||||||
|
|
||||||
http.Handle(*metricsPath, prometheus.Handler())
|
http.Handle(*metricsPath, prometheus.Handler())
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Redirect(w, r, *metricsPath, http.StatusMovedPermanently)
|
http.Redirect(w, r, *metricsPath, http.StatusMovedPermanently)
|
||||||
})
|
})
|
||||||
|
|
||||||
log.Printf("Starting WMI exporter on %q", *addr)
|
log.Infoln("Starting WMI exporter", version.Info())
|
||||||
if err := http.ListenAndServe(*addr, nil); err != nil {
|
log.Infoln("Build context", version.BuildContext())
|
||||||
|
|
||||||
|
log.Infoln("Listening on", *listenAddress)
|
||||||
|
if err := http.ListenAndServe(*listenAddress, nil); err != nil {
|
||||||
log.Fatalf("cannot start WMI exporter: %s", err)
|
log.Fatalf("cannot start WMI exporter: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user