From 217b6702723fed537b3d5018743fdb53113c5cae Mon Sep 17 00:00:00 2001 From: rebortg Date: Mon, 17 Apr 2023 16:17:42 +0200 Subject: [PATCH 1/4] NPS(feature): add nps collector Signed-off-by: rebortg --- collector/nps.go | 422 ++++++++++++++++++++++++++++++++++++++++++ collector/nps_test.go | 9 + docs/README.md | 1 + docs/collector.nps.md | 49 +++++ 4 files changed, 481 insertions(+) create mode 100644 collector/nps.go create mode 100644 collector/nps_test.go create mode 100644 docs/collector.nps.md diff --git a/collector/nps.go b/collector/nps.go new file mode 100644 index 00000000..8273eb8c --- /dev/null +++ b/collector/nps.go @@ -0,0 +1,422 @@ +package collector + +import ( + "github.com/prometheus-community/windows_exporter/log" + "github.com/prometheus/client_golang/prometheus" + "github.com/yusufpapurcu/wmi" +) + +func init() { + registerCollector("nps", newnpsCollector) // TODO: Add any perflib dependencies here +} + +// A npsCollector is a Prometheus collector for WMI Win32_PerfRawData_IAS_NPSAuthenticationServer and Win32_PerfRawData_IAS_NPSAccountingServer metrics + +type npsCollector struct { + AccessAccepts *prometheus.Desc + AccessChallenges *prometheus.Desc + AccessRejects *prometheus.Desc + AccessRequests *prometheus.Desc + AccessBadAuthenticators *prometheus.Desc + AccessDroppedPackets *prometheus.Desc + AccessInvalidRequests *prometheus.Desc + AccessMalformedPackets *prometheus.Desc + AccessPacketsReceived *prometheus.Desc + AccessPacketsSent *prometheus.Desc + AccessServerResetTime *prometheus.Desc + AccessServerUpTime *prometheus.Desc + AccessUnknownType *prometheus.Desc + + AccountingRequests *prometheus.Desc + AccountingResponses *prometheus.Desc + AccountingBadAuthenticators *prometheus.Desc + AccountingDroppedPackets *prometheus.Desc + AccountingInvalidRequests *prometheus.Desc + AccountingMalformedPackets *prometheus.Desc + AccountingNoRecord *prometheus.Desc + AccountingPacketsReceived *prometheus.Desc + AccountingPacketsSent *prometheus.Desc + AccountingServerResetTime *prometheus.Desc + AccountingServerUpTime *prometheus.Desc + AccountingUnknownType *prometheus.Desc +} + +func newnpsCollector() (Collector, error) { + const subsystem = "nps" + return &npsCollector{ + AccessAccepts: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_accepts"), + "(AccessAccepts)", + nil, + nil, + ), + AccessChallenges: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_challenges"), + "(AccessChallenges)", + nil, + nil, + ), + AccessRejects: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_rejects"), + "(AccessRejects)", + nil, + nil, + ), + AccessRequests: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_requests"), + "(AccessRequests)", + nil, + nil, + ), + AccessBadAuthenticators: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_bad_authenticators"), + "(BadAuthenticators)", + nil, + nil, + ), + AccessDroppedPackets: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_dropped_packets"), + "(DroppedPackets)", + nil, + nil, + ), + AccessInvalidRequests: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_invalid_requests"), + "(InvalidRequests)", + nil, + nil, + ), + AccessMalformedPackets: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_malformed_packets"), + "(MalformedPackets)", + nil, + nil, + ), + AccessPacketsReceived: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_packets_received"), + "(PacketsReceived)", + nil, + nil, + ), + AccessPacketsSent: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_packets_sent"), + "(PacketsSent)", + nil, + nil, + ), + AccessServerResetTime: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_server_reset_time"), + "(ServerResetTime)", + nil, + nil, + ), + AccessServerUpTime: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_server_up_time"), + "(ServerUpTime)", + nil, + nil, + ), + AccessUnknownType: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "access_unknown_type"), + "(UnknownType)", + nil, + nil, + ), + + AccountingRequests: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_requests"), + "(AccountingRequests)", + nil, + nil, + ), + AccountingResponses: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_responses"), + "(AccountingResponses)", + nil, + nil, + ), + AccountingBadAuthenticators: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_bad_authenticators"), + "(BadAuthenticators)", + nil, + nil, + ), + AccountingDroppedPackets: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_dropped_packets"), + "(DroppedPackets)", + nil, + nil, + ), + AccountingInvalidRequests: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_invalid_requests"), + "(InvalidRequests)", + nil, + nil, + ), + AccountingMalformedPackets: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_malformed_packets"), + "(MalformedPackets)", + nil, + nil, + ), + AccountingNoRecord: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_no_record"), + "(NoRecord)", + nil, + nil, + ), + AccountingPacketsReceived: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_packets_received"), + "(PacketsReceived)", + nil, + nil, + ), + AccountingPacketsSent: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_packets_sent"), + "(PacketsSent)", + nil, + nil, + ), + AccountingServerResetTime: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_server_reset_time"), + "(ServerResetTime)", + nil, + nil, + ), + AccountingServerUpTime: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_server_up_time"), + "(ServerUpTime)", + nil, + nil, + ), + AccountingUnknownType: prometheus.NewDesc( + prometheus.BuildFQName(Namespace, subsystem, "accounting_unknown_type"), + "(UnknownType)", + nil, + nil, + ), + }, nil +} + +// Collect sends the metric values for each metric +// to the provided prometheus Metric channel. +func (c *npsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error { + if desc, err := c.CollectAccept(ch); err != nil { + log.Error("failed collecting NPS accept data:", desc, err) + return err + } + if desc, err := c.CollectAccounting(ch); err != nil { + log.Error("failed collecting NPS accounting data:", desc, err) + return err + } + return nil +} + +// Win32_PerfRawData_IAS_NPSAuthenticationServer docs: +// - +type Win32_PerfRawData_IAS_NPSAuthenticationServer struct { + Name string + + AccessAccepts uint32 + AccessChallenges uint32 + AccessRejects uint32 + AccessRequests uint32 + AccessBadAuthenticators uint32 + AccessDroppedPackets uint32 + AccessInvalidRequests uint32 + AccessMalformedPackets uint32 + AccessPacketsReceived uint32 + AccessPacketsSent uint32 + AccessServerResetTime uint32 + AccessServerUpTime uint32 + AccessUnknownType uint32 +} + +type Win32_PerfRawData_IAS_NPSAccountingServer struct { + Name string + + AccountingRequests uint32 + AccountingResponses uint32 + AccountingBadAuthenticators uint32 + AccountingDroppedPackets uint32 + AccountingInvalidRequests uint32 + AccountingMalformedPackets uint32 + AccountingNoRecord uint32 + AccountingPacketsReceived uint32 + AccountingPacketsSent uint32 + AccountingServerResetTime uint32 + AccountingServerUpTime uint32 + AccountingUnknownType uint32 +} + +// Collect sends the metric values for each metric +// to the provided prometheus Metric channel. +func (c *npsCollector) CollectAccept(ch chan<- prometheus.Metric) (*prometheus.Desc, error) { + var dst []Win32_PerfRawData_IAS_NPSAuthenticationServer + q := queryAll(&dst) + if err := wmi.Query(q, &dst); err != nil { + return nil, err + } + + ch <- prometheus.MustNewConstMetric( + c.AccessAccepts, + prometheus.CounterValue, + float64(dst[0].AccessAccepts), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessChallenges, + prometheus.CounterValue, + float64(dst[0].AccessChallenges), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessRejects, + prometheus.CounterValue, + float64(dst[0].AccessRejects), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessRequests, + prometheus.CounterValue, + float64(dst[0].AccessRequests), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessBadAuthenticators, + prometheus.CounterValue, + float64(dst[0].AccessBadAuthenticators), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessDroppedPackets, + prometheus.CounterValue, + float64(dst[0].AccessDroppedPackets), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessInvalidRequests, + prometheus.CounterValue, + float64(dst[0].AccessInvalidRequests), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessMalformedPackets, + prometheus.CounterValue, + float64(dst[0].AccessMalformedPackets), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessPacketsReceived, + prometheus.CounterValue, + float64(dst[0].AccessPacketsReceived), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessPacketsSent, + prometheus.CounterValue, + float64(dst[0].AccessPacketsSent), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessServerResetTime, + prometheus.CounterValue, + float64(dst[0].AccessServerResetTime), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessServerUpTime, + prometheus.CounterValue, + float64(dst[0].AccessServerUpTime), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccessUnknownType, + prometheus.CounterValue, + float64(dst[0].AccessUnknownType), + ) + + return nil, nil +} + +func (c *npsCollector) CollectAccounting(ch chan<- prometheus.Metric) (*prometheus.Desc, error) { + var dst []Win32_PerfRawData_IAS_NPSAccountingServer + q := queryAll(&dst) + if err := wmi.Query(q, &dst); err != nil { + return nil, err + } + + ch <- prometheus.MustNewConstMetric( + c.AccountingRequests, + prometheus.CounterValue, + float64(dst[0].AccountingRequests), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingResponses, + prometheus.CounterValue, + float64(dst[0].AccountingResponses), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingBadAuthenticators, + prometheus.CounterValue, + float64(dst[0].AccountingBadAuthenticators), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingDroppedPackets, + prometheus.CounterValue, + float64(dst[0].AccountingDroppedPackets), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingInvalidRequests, + prometheus.CounterValue, + float64(dst[0].AccountingInvalidRequests), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingMalformedPackets, + prometheus.CounterValue, + float64(dst[0].AccountingMalformedPackets), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingNoRecord, + prometheus.CounterValue, + float64(dst[0].AccountingNoRecord), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingPacketsReceived, + prometheus.CounterValue, + float64(dst[0].AccountingPacketsReceived), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingPacketsSent, + prometheus.CounterValue, + float64(dst[0].AccountingPacketsSent), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingServerResetTime, + prometheus.CounterValue, + float64(dst[0].AccountingServerResetTime), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingServerUpTime, + prometheus.CounterValue, + float64(dst[0].AccountingServerUpTime), + ) + + ch <- prometheus.MustNewConstMetric( + c.AccountingUnknownType, + prometheus.CounterValue, + float64(dst[0].AccountingUnknownType), + ) + + return nil, nil +} diff --git a/collector/nps_test.go b/collector/nps_test.go new file mode 100644 index 00000000..6514a73e --- /dev/null +++ b/collector/nps_test.go @@ -0,0 +1,9 @@ +package collector + +import ( + "testing" +) + +func BenchmarkNPSCollector(b *testing.B) { + benchmarkCollector(b, "nps", newNPSCollector) +} diff --git a/docs/README.md b/docs/README.md index 67b67d43..96e5ce1d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -26,6 +26,7 @@ This directory contains documentation of the collectors in the windows_exporter, - [`netframework_clrremoting`](collector.netframework_clrremoting.md) - [`netframework_clrsecurity`](collector.netframework_clrsecurity.md) - [`net`](collector.net.md) +- [`nps`](collector.nps.md) - [`os`](collector.os.md) - [`process`](collector.process.md) - [`remote_fx`](collector.remote_fx.md) diff --git a/docs/collector.nps.md b/docs/collector.nps.md new file mode 100644 index 00000000..20b4731a --- /dev/null +++ b/docs/collector.nps.md @@ -0,0 +1,49 @@ +# nps collector + +The nps collector exposes metrics about the NPS server + +||| +-|- +Metric name prefix | `nps` +Classes | Win32_PerfRawData_IAS_NPSAuthenticationServer
Win32_PerfRawData_IAS_NPSAccountingServer +Enabled by default? | No + +## Flags + +None + +## Metrics + +Name | Description | Type | Labels +-----|-------------|------|------- +`windows_nps_access_accepts` | | counter | None +`windows_nps_access_bad_authenticators` | | counter | None +`windows_nps_access_challenges` | | counter | None +`windows_nps_access_dropped_packets` | | counter | None +`windows_nps_access_invalid_requests` | | counter | None +`windows_nps_access_malformed_packets` | | counter | None +`windows_nps_access_packets_received` | | counter | None +`windows_nps_access_packets_sent` | | counter | None +`windows_nps_access_rejects` | | counter | None +`windows_nps_access_requests` | | counter | None +`windows_nps_access_server_reset_time` | | counter | None +`windows_nps_access_server_up_time` | | counter | None +`windows_nps_access_unknown_type` | | counter | None +`windows_nps_accounting_bad_authenticators` | | counter | None +`windows_nps_accounting_dropped_packets` | | counter | None +`windows_nps_accounting_invalid_requests` | | counter | None +`windows_nps_accounting_malformed_packets` | | counter | None +`windows_nps_accounting_no_record` | | counter | None +`windows_nps_accounting_packets_received` | | counter | None +`windows_nps_accounting_packets_sent` | | counter | None +`windows_nps_accounting_requests` | | counter | None +`windows_nps_accounting_responses` | | counter | None +`windows_nps_accounting_server_reset_time` | | counter | None +`windows_nps_accounting_server_up_time` | | counter | None +`windows_nps_accounting_unknown_type` | | counter | None + +### Example metric +Show current number of processes +``` +windows_nps_access_accepts{instance="localhost"} +``` \ No newline at end of file From 478eaa91d9e6628cad02431f8baff23deb7f9c50 Mon Sep 17 00:00:00 2001 From: rebortg Date: Thu, 20 Apr 2023 14:52:40 +0200 Subject: [PATCH 2/4] delete init() and rename newNPSCollector function Signed-off-by: rebortg --- collector/nps.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/collector/nps.go b/collector/nps.go index 8273eb8c..dfd7e214 100644 --- a/collector/nps.go +++ b/collector/nps.go @@ -6,10 +6,6 @@ import ( "github.com/yusufpapurcu/wmi" ) -func init() { - registerCollector("nps", newnpsCollector) // TODO: Add any perflib dependencies here -} - // A npsCollector is a Prometheus collector for WMI Win32_PerfRawData_IAS_NPSAuthenticationServer and Win32_PerfRawData_IAS_NPSAccountingServer metrics type npsCollector struct { @@ -41,7 +37,7 @@ type npsCollector struct { AccountingUnknownType *prometheus.Desc } -func newnpsCollector() (Collector, error) { +func newNPSCollector() (Collector, error) { const subsystem = "nps" return &npsCollector{ AccessAccepts: prometheus.NewDesc( @@ -213,7 +209,7 @@ func (c *npsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) } // Win32_PerfRawData_IAS_NPSAuthenticationServer docs: -// - +// at the moment there is no Microsoft documentation type Win32_PerfRawData_IAS_NPSAuthenticationServer struct { Name string From 7115c9dc220354b6b9664d94e2f774b0b6d65a26 Mon Sep 17 00:00:00 2001 From: rebortg Date: Tue, 2 May 2023 09:38:47 +0200 Subject: [PATCH 3/4] add nps collector in init.go Signed-off-by: rebortg --- collector/init.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/collector/init.go b/collector/init.go index 0ea15213..e40a0f52 100644 --- a/collector/init.go +++ b/collector/init.go @@ -275,6 +275,11 @@ var collectors = []collectorInit{ builder: newNETFramework_NETCLRSecurityCollector, perfCounterFunc: nil, }, + { + name: "nps", + builder: newNPSCollector, + perfCounterNames: nil, + }, { name: "os", flags: nil, From 95f250ed399821c2e779f01d41f98dcb1ac8640e Mon Sep 17 00:00:00 2001 From: Ben Reedy Date: Tue, 11 Jul 2023 06:17:46 +1000 Subject: [PATCH 4/4] feat: Update NPS collector for go-kit logging Signed-off-by: Ben Reedy --- collector/init.go | 6 +++--- collector/nps.go | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/collector/init.go b/collector/init.go index e40a0f52..a35f4cc1 100644 --- a/collector/init.go +++ b/collector/init.go @@ -276,9 +276,9 @@ var collectors = []collectorInit{ perfCounterFunc: nil, }, { - name: "nps", - builder: newNPSCollector, - perfCounterNames: nil, + name: "nps", + builder: newNPSCollector, + perfCounterFunc: nil, }, { name: "os", diff --git a/collector/nps.go b/collector/nps.go index dfd7e214..cd913c68 100644 --- a/collector/nps.go +++ b/collector/nps.go @@ -1,7 +1,10 @@ package collector import ( - "github.com/prometheus-community/windows_exporter/log" + "fmt" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" "github.com/yusufpapurcu/wmi" ) @@ -9,6 +12,8 @@ import ( // A npsCollector is a Prometheus collector for WMI Win32_PerfRawData_IAS_NPSAuthenticationServer and Win32_PerfRawData_IAS_NPSAccountingServer metrics type npsCollector struct { + logger log.Logger + AccessAccepts *prometheus.Desc AccessChallenges *prometheus.Desc AccessRejects *prometheus.Desc @@ -37,9 +42,11 @@ type npsCollector struct { AccountingUnknownType *prometheus.Desc } -func newNPSCollector() (Collector, error) { +func newNPSCollector(logger log.Logger) (Collector, error) { const subsystem = "nps" + logger = log.With(logger, "collector", subsystem) return &npsCollector{ + logger: logger, AccessAccepts: prometheus.NewDesc( prometheus.BuildFQName(Namespace, subsystem, "access_accepts"), "(AccessAccepts)", @@ -198,11 +205,11 @@ func newNPSCollector() (Collector, error) { // to the provided prometheus Metric channel. func (c *npsCollector) Collect(ctx *ScrapeContext, ch chan<- prometheus.Metric) error { if desc, err := c.CollectAccept(ch); err != nil { - log.Error("failed collecting NPS accept data:", desc, err) + _ = level.Error(c.logger).Log("msg", fmt.Sprintf("failed collecting NPS accept data: %s %v", desc, err)) return err } if desc, err := c.CollectAccounting(ch); err != nil { - log.Error("failed collecting NPS accounting data:", desc, err) + _ = level.Error(c.logger).Log("msg", fmt.Sprintf("failed collecting NPS accounting data: %s %v", desc, err)) return err } return nil @@ -249,7 +256,7 @@ type Win32_PerfRawData_IAS_NPSAccountingServer struct { // to the provided prometheus Metric channel. func (c *npsCollector) CollectAccept(ch chan<- prometheus.Metric) (*prometheus.Desc, error) { var dst []Win32_PerfRawData_IAS_NPSAuthenticationServer - q := queryAll(&dst) + q := queryAll(&dst, c.logger) if err := wmi.Query(q, &dst); err != nil { return nil, err } @@ -337,7 +344,7 @@ func (c *npsCollector) CollectAccept(ch chan<- prometheus.Metric) (*prometheus.D func (c *npsCollector) CollectAccounting(ch chan<- prometheus.Metric) (*prometheus.Desc, error) { var dst []Win32_PerfRawData_IAS_NPSAccountingServer - q := queryAll(&dst) + q := queryAll(&dst, c.logger) if err := wmi.Query(q, &dst); err != nil { return nil, err }