mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-10-17 10:09:05 +02:00
dns: fix zone transfer counter mapping and count queued dynamic updates (#2718)
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
+5
-2
@@ -17,9 +17,9 @@ Most installations need no changes. Go through the checklist below and read the
|
||||
| You use the `container` collector | Replace `containerd-state-dir` with `cri-endpoint` | [container collector](#container-collector) |
|
||||
| You query `windows_gpu_info` | Replace the `phys` label with `device_number` | [GPU collector](#gpu-collector) |
|
||||
| You alert on BitLocker status | Replace `status="disabled"` with `status="off"` | [BitLocker status](#bitlocker-status) |
|
||||
| You query Active Directory latency or security descriptor propagation, DFSR, Hyper-V, logical disk queue, cache, IIS, memory, RemoteFX, scheduled task, SMB server share or terminal services metrics | Update queries | [Renamed, deprecated and retyped metrics](#renamed-deprecated-and-retyped-metrics) |
|
||||
| You query Active Directory latency or security descriptor propagation, DFSR, DNS dynamic update, Hyper-V, logical disk queue, cache, IIS, memory, RemoteFX, scheduled task, SMB server share or terminal services metrics | Update queries | [Renamed, deprecated and retyped metrics](#renamed-deprecated-and-retyped-metrics) |
|
||||
| You enable the `scheduled_task` collector and use tasks below `\Microsoft\` or missed runs | Set `--collector.scheduled_task.exclude` or `missed-runs` | [scheduled_task collector](#scheduled_task-collector) |
|
||||
| You chart SQL Server latencies, SQL Server lock counts, DHCP denials, AD LSA writes, AD computer creations, AD FS database query times or RemoteFX skipped frames | Expect corrected values | [Corrected values](#corrected-values) |
|
||||
| You chart SQL Server latencies, SQL Server lock counts, DHCP denials, AD LSA writes, AD computer creations, AD FS database query times, DNS zone transfers or RemoteFX skipped frames | Expect corrected values | [Corrected values](#corrected-values) |
|
||||
| You enable the `hyperv` or `mscluster` collector | Check the new default sub-collectors | [New default sub-collectors](#new-default-sub-collectors) |
|
||||
| You set scrape timeouts above 5 minutes or below the timeout margin | Review the new limits | [Scrape timeouts](#scrape-timeouts) |
|
||||
| You use the sample Grafana dashboard | Use Grafana 13 or later and import the new dashboard | [Dashboard and alerts](#dashboard-and-alerts) |
|
||||
@@ -252,6 +252,7 @@ Renamed:
|
||||
| `windows_iis_http_request_total_rejected_request` | `windows_iis_http_requests_rejected_total` | Now a counter, use `rate()`; label `app` |
|
||||
| `windows_iis_http_requests_arrival_rate` | `windows_iis_http_requests_arrived_total` | Was a running count, now a counter, use `rate()`; label `app` |
|
||||
| `windows_iis_http_requests_max_queue_item_age` | `windows_iis_http_requests_max_queue_item_age_seconds` | Left out while the queue is empty; label `app` |
|
||||
| `windows_dns_dynamic_updates_queued` | `windows_dns_dynamic_updates_queued_total` | Now a counter, use `rate()` |
|
||||
|
||||
The RemoteFX loss, FEC and retransmission gauges were not percentages. They exported the raw numerator of a Windows sample fraction, a running count that only grows.
|
||||
The numerator and its base are now two counters. Get the ratio with `rate(windows_remote_fx_net_lost_packets_total[5m]) / rate(windows_remote_fx_net_loss_sampled_packets_total[5m])`, and likewise with `windows_remote_fx_net_fec_packets_total` / `windows_remote_fx_net_fec_sampled_packets_total` and `windows_remote_fx_net_retransmitted_packets_total` / `windows_remote_fx_net_retransmission_sampled_packets_total`.
|
||||
@@ -323,6 +324,8 @@ These metrics keep their names, but 0.31 reported wrong values. Graphs show a st
|
||||
- `windows_adfs_db_artifact_query_time_seconds_total` and `windows_adfs_db_config_query_time_seconds_total` are now in seconds. 0.31 scaled the raw ticks by a fixed `1e-8`, so on a typical 10 MHz time base the values were 10 times too small. The new `windows_adfs_db_artifact_queries_total` and `windows_adfs_db_config_queries_total` count the queries, so you can compute the average query time.
|
||||
- `windows_dhcp_denied_due_to_nonmatch_total` now counts denials due to a non-match. In 0.31 it repeated the match denial count.
|
||||
- `windows_remote_fx_gfx_frames_skipped_insufficient_resource_total` with `resource="client"` and `resource="server"` now count the matching frames. In 0.31 the two label values were swapped.
|
||||
- `windows_dns_zone_transfer_requests_sent_total{qtype="soa"}` now counts zone transfer SOA requests sent. In 0.31 it reported zone transfer requests received.
|
||||
- `windows_dns_zone_transfer_success_received_total{qtype="incremental",protocol="udp"}` now counts successful UDP incremental zone transfers. In 0.31 it repeated the TCP count.
|
||||
- `windows_netframework_clrmemory_gc_time_percent` no longer overflows, and it is left out when Windows reports no base value. The `netframework` collector now reads the CLR counters through PDH instead of WMI; names, labels and types are unchanged.
|
||||
- The IIS URI cache flush and kernel cache item metrics read the right Windows counters, and the metadata cache hit metrics are no longer always `0`.
|
||||
- `windows_pagefile_limit_bytes` and `windows_pagefile_free_bytes` read the paging file size from the `Paging File` counter instead of the file system. In 0.31 a paging file that could not be read reported a size of `0` and a negative free space; it is now left out.
|
||||
|
||||
@@ -22,14 +22,14 @@ Name | Description
|
||||
Name | Description | Type | Labels
|
||||
-----|-------------|------|-------
|
||||
`windows_dns_zone_transfer_requests_received_total` | Number of zone transfer requests (AXFR/IXFR) received by the master DNS server | counter | `qtype`
|
||||
`windows_dns_zone_transfer_requests_sent_total` | Number of zone transfer requests (AXFR/IXFR) sent by the secondary DNS server | counter | `qtype`
|
||||
`windows_dns_zone_transfer_requests_sent_total` | Number of zone transfer requests (AXFR/IXFR) and zone transfer SOA requests sent by the secondary DNS server | counter | `qtype` (`full`, `incremental`, `soa`)
|
||||
`windows_dns_zone_transfer_response_received_total` | Number of zone transfer responses (AXFR/IXFR) received by the secondary DNS server | counter | `qtype`
|
||||
`windows_dns_zone_transfer_success_received_total` | Number of successful zone transfers (AXFR/IXFR) received by the secondary DNS server | counter | `qtype`, `protocol`
|
||||
`windows_dns_zone_transfer_success_sent_total` | Number of successful zone transfers (AXFR/IXFR) of the master DNS server | counter | `qtype`
|
||||
`windows_dns_zone_transfer_failures_total` | Number of failed zone transfers of the master DNS server | counter | None
|
||||
`windows_dns_memory_used_bytes` | Current memory used by DNS server | gauge | `area`
|
||||
`windows_dns_dynamic_updates_queued` | Number of dynamic updates queued by the DNS server | gauge | None
|
||||
`windows_dns_dynamic_updates_received_total` | Number of secure update requests received by the DNS server | counter | `operation`
|
||||
`windows_dns_dynamic_updates_queued_total` | Number of dynamic updates queued by the DNS server | counter | None
|
||||
`windows_dns_dynamic_updates_received_total` | Number of dynamic update requests received by the DNS server that were no-operations (noop) or written to the database (written) | counter | `operation`
|
||||
`windows_dns_dynamic_updates_failures_total` | Number of dynamic updates which timed out or were rejected by the DNS server | counter | `reason`
|
||||
`windows_dns_notify_received_total` | Number of notifies received by the secondary DNS server | counter | None
|
||||
`windows_dns_notify_sent_total` | Number of notifies sent by the master DNS server | counter | None
|
||||
|
||||
@@ -20,7 +20,11 @@ secondary server, so zone transfer counters stayed 0.
|
||||
- `Total Query Received` equals `UDP Query Received` + `TCP Query Received`
|
||||
(830 = 820 + 10); `Total Response Sent` likewise (825 = 815 + 10).
|
||||
- `Recursive Send TimeOuts` and `Recursive TimeOut/sec` are a twin pair with
|
||||
different names; the collector reads the `/sec` one.
|
||||
different names; the collector reads `Recursive Send TimeOuts`.
|
||||
- `Dynamic Update Queued` is cumulative: it matches `Queue / Queued` in
|
||||
`dnscmd /statistics 0x00000100` (and `Queued` in
|
||||
`Get-DnsServerStatistics`), not the current `In Queue` value. Publish it as
|
||||
a counter.
|
||||
- Eleven counters of the object have names that belong to other objects and
|
||||
no help text: `% User Time`, `Async Fast Reads/sec`,
|
||||
`Fast Read Not Possibles/sec`, `Fast Read Resource Misses/sec`,
|
||||
@@ -28,6 +32,11 @@ secondary server, so zone transfer counters stayed 0.
|
||||
`Data Flush Pages/sec`, `Level 2 TLB Fills/sec`, `Enumerations Server/sec`
|
||||
and `Virtual Bytes`. `Get-Counter -ListSet DNS` also lists a counter named
|
||||
`176`. All of them stayed 0; the collector ignores them (`_` fields).
|
||||
- Compare live values with `dnscmd /statistics` or `Get-Counter "\DNS\*"`.
|
||||
`ipconfig /registerdns` on a domain member raises the dynamic update
|
||||
counters.
|
||||
- `collectPerfData` publishes one sample; test value mapping with it through
|
||||
a registry (see `dns_internal_test.go`).
|
||||
|
||||
## Counter reference
|
||||
|
||||
|
||||
@@ -158,6 +158,19 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
|
||||
}
|
||||
|
||||
func (c *Collector) buildMetricsCollector(logger *slog.Logger) error {
|
||||
c.buildDescriptors()
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](logger.With(slog.String("collector", Name)), pdh.CounterTypeRaw, "DNS", pdh.InstancesAll)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DNS collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) buildDescriptors() {
|
||||
c.zoneTransferRequestsReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_requests_received_total"),
|
||||
"Number of zone transfer requests (AXFR/IXFR) received by the master DNS server",
|
||||
@@ -166,7 +179,7 @@ func (c *Collector) buildMetricsCollector(logger *slog.Logger) error {
|
||||
)
|
||||
c.zoneTransferRequestsSent = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "zone_transfer_requests_sent_total"),
|
||||
"Number of zone transfer requests (AXFR/IXFR) sent by the secondary DNS server",
|
||||
"Number of zone transfer requests (AXFR/IXFR) and zone transfer SOA requests sent by the secondary DNS server",
|
||||
[]string{"qtype"},
|
||||
nil,
|
||||
)
|
||||
@@ -201,14 +214,14 @@ func (c *Collector) buildMetricsCollector(logger *slog.Logger) error {
|
||||
nil,
|
||||
)
|
||||
c.dynamicUpdatesQueued = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dynamic_updates_queued"),
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dynamic_updates_queued_total"),
|
||||
"Number of dynamic updates queued by the DNS server",
|
||||
nil,
|
||||
nil,
|
||||
)
|
||||
c.dynamicUpdatesReceived = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(types.Namespace, Name, "dynamic_updates_received_total"),
|
||||
"Number of secure update requests received by the DNS server",
|
||||
"Number of dynamic update requests received by the DNS server that were no-operations (noop) or written to the database (written)",
|
||||
[]string{"operation"},
|
||||
nil,
|
||||
)
|
||||
@@ -297,15 +310,6 @@ func (c *Collector) buildMetricsCollector(logger *slog.Logger) error {
|
||||
[]string{"name", "collection_name", "dns_server"},
|
||||
nil,
|
||||
)
|
||||
|
||||
var err error
|
||||
|
||||
c.perfDataCollector, err = pdh.NewCollector[perfDataCounterValues](logger.With(slog.String("collector", Name)), pdh.CounterTypeRaw, "DNS", pdh.InstancesAll)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create DNS collector: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) buildErrorStatsCollector(miSession *mi.Session) error {
|
||||
@@ -357,59 +361,66 @@ func (c *Collector) collectMetrics(ch chan<- prometheus.Metric) error {
|
||||
return fmt.Errorf("failed to collect DNS metrics: %w", types.ErrNoDataUnexpected)
|
||||
}
|
||||
|
||||
c.collectPerfData(ch, c.perfDataObject[0])
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// collectPerfData publishes the metrics of one sample of the DNS object.
|
||||
func (c *Collector) collectPerfData(ch chan<- prometheus.Metric, data perfDataCounterValues) {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].AxfrRequestReceived,
|
||||
data.AxfrRequestReceived,
|
||||
"full",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].IxfrRequestReceived,
|
||||
data.IxfrRequestReceived,
|
||||
"incremental",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsSent,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].AxfrRequestSent,
|
||||
data.AxfrRequestSent,
|
||||
"full",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsSent,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].IxfrRequestSent,
|
||||
data.IxfrRequestSent,
|
||||
"incremental",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferRequestsSent,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].ZoneTransferSOARequestSent,
|
||||
data.ZoneTransferSOARequestSent,
|
||||
"soa",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferResponsesReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].AxfrResponseReceived,
|
||||
data.AxfrResponseReceived,
|
||||
"full",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferResponsesReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].IxfrResponseReceived,
|
||||
data.IxfrResponseReceived,
|
||||
"incremental",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].AxfrSuccessReceived,
|
||||
data.AxfrSuccessReceived,
|
||||
"full",
|
||||
"tcp",
|
||||
)
|
||||
@@ -417,7 +428,7 @@ func (c *Collector) collectMetrics(ch chan<- prometheus.Metric) error {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].IxfrTCPSuccessReceived,
|
||||
data.IxfrTCPSuccessReceived,
|
||||
"incremental",
|
||||
"tcp",
|
||||
)
|
||||
@@ -425,7 +436,7 @@ func (c *Collector) collectMetrics(ch chan<- prometheus.Metric) error {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].IxfrTCPSuccessReceived,
|
||||
data.IxfrUDPSuccessReceived,
|
||||
"incremental",
|
||||
"udp",
|
||||
)
|
||||
@@ -433,204 +444,202 @@ func (c *Collector) collectMetrics(ch chan<- prometheus.Metric) error {
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessSent,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].AxfrSuccessSent,
|
||||
data.AxfrSuccessSent,
|
||||
"full",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferSuccessSent,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].IxfrSuccessSent,
|
||||
data.IxfrSuccessSent,
|
||||
"incremental",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.zoneTransferFailures,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].ZoneTransferFailure,
|
||||
data.ZoneTransferFailure,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
c.perfDataObject[0].CachingMemory,
|
||||
data.CachingMemory,
|
||||
"caching",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
c.perfDataObject[0].DatabaseNodeMemory,
|
||||
data.DatabaseNodeMemory,
|
||||
"database_node",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
c.perfDataObject[0].NbStatMemory,
|
||||
data.NbStatMemory,
|
||||
"nbstat",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
c.perfDataObject[0].RecordFlowMemory,
|
||||
data.RecordFlowMemory,
|
||||
"record_flow",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
c.perfDataObject[0].TcpMessageMemory,
|
||||
data.TcpMessageMemory,
|
||||
"tcp_message",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.memoryUsedBytes,
|
||||
prometheus.GaugeValue,
|
||||
c.perfDataObject[0].UdpMessageMemory,
|
||||
data.UdpMessageMemory,
|
||||
"udp_message",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].DynamicUpdateNoOperation,
|
||||
data.DynamicUpdateNoOperation,
|
||||
"noop",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].DynamicUpdateWrittenToDatabase,
|
||||
data.DynamicUpdateWrittenToDatabase,
|
||||
"written",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesQueued,
|
||||
prometheus.GaugeValue,
|
||||
c.perfDataObject[0].DynamicUpdateQueued,
|
||||
prometheus.CounterValue,
|
||||
data.DynamicUpdateQueued,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesFailures,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].DynamicUpdateRejected,
|
||||
data.DynamicUpdateRejected,
|
||||
"rejected",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.dynamicUpdatesFailures,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].DynamicUpdateTimeOuts,
|
||||
data.DynamicUpdateTimeOuts,
|
||||
"timeout",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.notifyReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].NotifyReceived,
|
||||
data.NotifyReceived,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.notifySent,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].NotifySent,
|
||||
data.NotifySent,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.recursiveQueries,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].RecursiveQueries,
|
||||
data.RecursiveQueries,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.recursiveQueryFailures,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].RecursiveQueryFailure,
|
||||
data.RecursiveQueryFailure,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.recursiveQuerySendTimeouts,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].RecursiveSendTimeOuts,
|
||||
data.RecursiveSendTimeOuts,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.queries,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].TcpQueryReceived,
|
||||
data.TcpQueryReceived,
|
||||
"tcp",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.queries,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].UdpQueryReceived,
|
||||
data.UdpQueryReceived,
|
||||
"udp",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.responses,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].TcpResponseSent,
|
||||
data.TcpResponseSent,
|
||||
"tcp",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.responses,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].UdpResponseSent,
|
||||
data.UdpResponseSent,
|
||||
"udp",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.unmatchedResponsesReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].UnmatchedResponsesReceived,
|
||||
data.UnmatchedResponsesReceived,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsQueries,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].WinsLookupReceived,
|
||||
data.WinsLookupReceived,
|
||||
"forward",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsQueries,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].WinsReverseLookupReceived,
|
||||
data.WinsReverseLookupReceived,
|
||||
"reverse",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsResponses,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].WinsResponseSent,
|
||||
data.WinsResponseSent,
|
||||
"forward",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.winsResponses,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].WinsReverseResponseSent,
|
||||
data.WinsReverseResponseSent,
|
||||
"reverse",
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.secureUpdateFailures,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].SecureUpdateFailure,
|
||||
data.SecureUpdateFailure,
|
||||
)
|
||||
|
||||
ch <- prometheus.MustNewConstMetric(
|
||||
c.secureUpdateReceived,
|
||||
prometheus.CounterValue,
|
||||
c.perfDataObject[0].SecureUpdateReceived,
|
||||
data.SecureUpdateReceived,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Collector) collectErrorStats(ch chan<- prometheus.Metric, maxScrapeDuration time.Duration) error {
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// Copyright The Prometheus Authors
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build windows
|
||||
|
||||
package dns
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
dto "github.com/prometheus/client_model/go"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCollectPerfData(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
data := perfDataCounterValues{
|
||||
AxfrRequestSent: 1,
|
||||
IxfrRequestSent: 2,
|
||||
ZoneTransferSOARequestSent: 3,
|
||||
AxfrSuccessReceived: 4,
|
||||
IxfrTCPSuccessReceived: 5,
|
||||
IxfrUDPSuccessReceived: 6,
|
||||
DynamicUpdateQueued: 93,
|
||||
RecursiveSendTimeOuts: 7,
|
||||
}
|
||||
|
||||
c := New(nil)
|
||||
c.buildDescriptors()
|
||||
|
||||
registry := prometheus.NewPedanticRegistry()
|
||||
require.NoError(t, registry.Register(metricCollector{collector: c, data: data}))
|
||||
|
||||
families, err := registry.Gather()
|
||||
require.NoError(t, err)
|
||||
|
||||
type sample struct {
|
||||
metricType dto.MetricType
|
||||
value float64
|
||||
}
|
||||
|
||||
got := make(map[string]sample)
|
||||
|
||||
for _, family := range families {
|
||||
for _, metric := range family.GetMetric() {
|
||||
labels := make([]string, 0, len(metric.GetLabel()))
|
||||
for _, label := range metric.GetLabel() {
|
||||
labels = append(labels, label.GetName()+"="+label.GetValue())
|
||||
}
|
||||
|
||||
value := metric.GetGauge().GetValue()
|
||||
if family.GetType() == dto.MetricType_COUNTER {
|
||||
value = metric.GetCounter().GetValue()
|
||||
}
|
||||
|
||||
got[family.GetName()+"{"+strings.Join(labels, ",")+"}"] = sample{metricType: family.GetType(), value: value}
|
||||
}
|
||||
}
|
||||
|
||||
for name, want := range map[string]sample{
|
||||
"windows_dns_zone_transfer_requests_sent_total{qtype=full}": {dto.MetricType_COUNTER, 1},
|
||||
"windows_dns_zone_transfer_requests_sent_total{qtype=incremental}": {dto.MetricType_COUNTER, 2},
|
||||
"windows_dns_zone_transfer_requests_sent_total{qtype=soa}": {dto.MetricType_COUNTER, 3},
|
||||
"windows_dns_zone_transfer_success_received_total{protocol=tcp,qtype=full}": {dto.MetricType_COUNTER, 4},
|
||||
"windows_dns_zone_transfer_success_received_total{protocol=tcp,qtype=incremental}": {dto.MetricType_COUNTER, 5},
|
||||
"windows_dns_zone_transfer_success_received_total{protocol=udp,qtype=incremental}": {dto.MetricType_COUNTER, 6},
|
||||
"windows_dns_dynamic_updates_queued_total{}": {dto.MetricType_COUNTER, 93},
|
||||
"windows_dns_recursive_query_send_timeouts_total{}": {dto.MetricType_COUNTER, 7},
|
||||
"windows_dns_memory_used_bytes{area=caching}": {dto.MetricType_GAUGE, 0},
|
||||
} {
|
||||
require.Contains(t, got, name)
|
||||
require.Equal(t, want, got[name], name)
|
||||
}
|
||||
|
||||
require.NotContains(t, got, "windows_dns_dynamic_updates_queued{}")
|
||||
}
|
||||
|
||||
// TestPerfDataCounterNames guards against a field reading a counter of a different name.
|
||||
func TestPerfDataCounterNames(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for field, counter := range map[string]string{
|
||||
"ZoneTransferSOARequestSent": "Zone Transfer SOA Request Sent",
|
||||
"IxfrUDPSuccessReceived": "IXFR UDP Success Received",
|
||||
"IxfrTCPSuccessReceived": "IXFR TCP Success Received",
|
||||
"DynamicUpdateQueued": "Dynamic Update Queued",
|
||||
"RecursiveSendTimeOuts": "Recursive Send TimeOuts",
|
||||
} {
|
||||
f, ok := reflect.TypeFor[perfDataCounterValues]().FieldByName(field)
|
||||
require.True(t, ok, field)
|
||||
require.Equal(t, counter, f.Tag.Get("perfdata"), field)
|
||||
}
|
||||
}
|
||||
|
||||
type metricCollector struct {
|
||||
collector *Collector
|
||||
data perfDataCounterValues
|
||||
}
|
||||
|
||||
func (c metricCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||
prometheus.DescribeByCollect(c, ch)
|
||||
}
|
||||
|
||||
func (c metricCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
c.collector.collectPerfData(ch, c.data)
|
||||
}
|
||||
@@ -70,8 +70,8 @@ type perfDataCounterValues struct {
|
||||
_ float64 `perfdata:"Recursive Queries/sec"`
|
||||
RecursiveQueryFailure float64 `perfdata:"Recursive Query Failure"`
|
||||
_ float64 `perfdata:"Recursive Query Failure/sec"`
|
||||
_ float64 `perfdata:"Recursive Send TimeOuts"`
|
||||
RecursiveSendTimeOuts float64 `perfdata:"Recursive TimeOut/sec"`
|
||||
RecursiveSendTimeOuts float64 `perfdata:"Recursive Send TimeOuts"`
|
||||
_ float64 `perfdata:"Recursive TimeOut/sec"`
|
||||
_ float64 `perfdata:"Responses Suppressed"`
|
||||
_ float64 `perfdata:"Responses Suppressed/sec"`
|
||||
SecureUpdateFailure float64 `perfdata:"Secure Update Failure"`
|
||||
@@ -103,8 +103,8 @@ type perfDataCounterValues struct {
|
||||
WinsReverseResponseSent float64 `perfdata:"WINS Reverse Response Sent"`
|
||||
_ float64 `perfdata:"WINS Reverse Response Sent/sec"`
|
||||
ZoneTransferFailure float64 `perfdata:"Zone Transfer Failure"`
|
||||
ZoneTransferSOARequestSent float64 `perfdata:"Zone Transfer Request Received"`
|
||||
_ float64 `perfdata:"Zone Transfer SOA Request Sent"`
|
||||
_ float64 `perfdata:"Zone Transfer Request Received"`
|
||||
ZoneTransferSOARequestSent float64 `perfdata:"Zone Transfer SOA Request Sent"`
|
||||
_ float64 `perfdata:"Zone Transfer Success"`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user