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:
Jan-Otto Kröpke
2026-10-15 20:42:01 +02:00
committed by GitHub
parent 8138b2e073
commit 11aa13bb2f
6 changed files with 208 additions and 65 deletions
+5 -2
View File
@@ -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.
+3 -3
View File
@@ -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
+10 -1
View File
@@ -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
+64 -55
View File
@@ -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 {
+122
View File
@@ -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)
}
+4 -4
View File
@@ -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"`
}