ad: fix swapped and misread counters, correct metric units and types (#2717)

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-15 18:02:18 +00:00
committed by GitHub
parent 55275e7db1
commit 49c955c5a5
5 changed files with 822 additions and 619 deletions
+9 -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 Hyper-V, logical disk queue, cache, IIS output cache, 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, Hyper-V, logical disk queue, cache, IIS output cache, 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 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 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) |
@@ -238,6 +238,11 @@ Renamed:
| `windows_remote_fx_net_loss_rate` | `windows_remote_fx_net_lost_packets_total` and `windows_remote_fx_net_loss_sampled_packets_total` | Counters, see below |
| `windows_remote_fx_net_fec_rate` | `windows_remote_fx_net_fec_packets_total` and `windows_remote_fx_net_fec_sampled_packets_total` | Counters, see below |
| `windows_remote_fx_net_retransmission_rate` | `windows_remote_fx_net_retransmitted_packets_total` and `windows_remote_fx_net_retransmission_sampled_packets_total` | Counters, see below |
| `windows_ad_atq_average_request_latency` | `windows_ad_atq_average_request_latency_seconds` | Now in seconds, was milliseconds |
| `windows_ad_sam_group_evaluation_latency` | `windows_ad_sam_group_evaluation_latency_seconds` | Now in seconds, was milliseconds |
| `windows_ad_security_descriptor_propagation_access_wait_total_seconds` | `windows_ad_security_descriptor_propagation_average_exclusion_time_seconds` | Now in seconds, was the raw millisecond average; it is an average, not a total |
| `windows_ad_security_descriptor_propagation_events_total` | `windows_ad_security_descriptor_propagation_suboperations_total` | Same value, it counts sub-operations, not events |
| `windows_ad_security_descriptor_propagation_items_queued_total` | `windows_ad_security_descriptor_propagation_items_queued` | Now a gauge, query it without `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`.
@@ -298,6 +303,8 @@ These metrics keep their names, but 0.31 reported wrong values. Graphs show a st
- `windows_mssql_databases_xtp_controller_dlc_peak_latency_seconds`, `windows_mssql_dbreplica_database_flow_control_wait_seconds` and `windows_mssql_dbreplica_group_commit_stall_seconds` are now in seconds. SQL Server reports microseconds, which 0.31 did not convert correctly.
- `windows_mssql_locks_count` is no longer divided by 1000.
- `windows_ad_directory_operations_total{operation="write",origin="local_security_authority"}` now counts directory writes from the LSA. In 0.31 it repeated the LSA search count.
- `windows_ad_sam_computer_creation_requests_total` and `windows_ad_sam_computer_creation_successful_requests_total` were swapped in 0.31. Requests now count all attempts, successful requests only the successful ones.
- `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_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.
+62 -62
View File
@@ -16,68 +16,68 @@ None
Name | Description | Type | Labels
-----|-------------|------|-------
`windows_ad_address_book_operations_total` | _Not yet documented_ | counter | `operation`
`windows_ad_address_book_client_sessions` | _Not yet documented_ | gauge | None
`windows_ad_approximate_highest_distinguished_name_tag` | _Not yet documented_ | gauge | None
`windows_ad_atq_estimated_delay_seconds` | _Not yet documented_ | gauge | None
`windows_ad_atq_outstanding_requests` | _Not yet documented_ | gauge | None
`windows_ad_atq_average_request_latency` | _Not yet documented_ | gauge | None
`windows_ad_atq_current_threads` | _Not yet documented_ | gauge | `service`
`windows_ad_searches_total` | _Not yet documented_ | counter | `scope`
`windows_ad_database_operations_total` | _Not yet documented_ | counter | `operation`
`windows_ad_binds_total` | _Not yet documented_ | counter | `bind_method`
`windows_ad_replication_highest_usn` | _Not yet documented_ | counter | `state`
`windows_ad_replication_data_intrasite_bytes_total` | _Not yet documented_ | counter | `direction`
`windows_ad_replication_data_intersite_bytes_total` | _Not yet documented_ | counter | `direction`
`windows_ad_replication_inbound_sync_objects_remaining` | _Not yet documented_ | gauge | None
`windows_ad_replication_inbound_link_value_updates_remaining` | _Not yet documented_ | gauge | None
`windows_ad_replication_inbound_objects_updated_total` | _Not yet documented_ | counter | None
`windows_ad_replication_inbound_objects_filtered_total` | _Not yet documented_ | counter | None
`windows_ad_replication_inbound_properties_updated_total` | _Not yet documented_ | counter | None
`windows_ad_replication_inbound_properties_filtered_total` | _Not yet documented_ | counter | None
`windows_ad_replication_pending_operations` | _Not yet documented_ | gauge | None
`windows_ad_replication_pending_synchronizations` | _Not yet documented_ | gauge | None
`windows_ad_replication_sync_requests_total` | _Not yet documented_ | counter | None
`windows_ad_replication_sync_requests_success_total` | _Not yet documented_ | counter | None
`windows_ad_replication_sync_requests_schema_mismatch_failure_total` | _Not yet documented_ | counter | None
`windows_ad_name_translations_total` | _Not yet documented_ | counter | `target_name`
`windows_ad_change_monitors_registered` | _Not yet documented_ | gauge | None
`windows_ad_change_monitor_updates_pending` | _Not yet documented_ | gauge | None
`windows_ad_name_cache_hits_total` | _Not yet documented_ | counter | None
`windows_ad_name_cache_lookups_total` | _Not yet documented_ | counter | None
`windows_ad_directory_operations_total` | _Not yet documented_ | counter | `operation`, `origin`
`windows_ad_directory_search_suboperations_total` | _Not yet documented_ | counter | None
`windows_ad_security_descriptor_propagation_events_total` | _Not yet documented_ | counter | None
`windows_ad_security_descriptor_propagation_events_queued` | _Not yet documented_ | gauge | None
`windows_ad_security_descriptor_propagation_access_wait_total_seconds` | _Not yet documented_ | gauge | None
`windows_ad_security_descriptor_propagation_items_queued_total` | _Not yet documented_ | counter | None
`windows_ad_directory_service_threads` | _Not yet documented_ | gauge | None
`windows_ad_ldap_closed_connections_total` | _Not yet documented_ | counter | None
`windows_ad_ldap_opened_connections_total` | _Not yet documented_ | counter | `type`
`windows_ad_ldap_active_threads` | _Not yet documented_ | gauge | None
`windows_ad_ldap_last_bind_time_seconds` | _Not yet documented_ | gauge | None
`windows_ad_ldap_searches_total` | _Not yet documented_ | counter | None
`windows_ad_ldap_udp_operations_total` | _Not yet documented_ | counter | None
`windows_ad_ldap_writes_total` | _Not yet documented_ | counter | None
`windows_ad_ldap_client_sessions` | This is the number of sessions opened by LDAP clients at the time the data is taken. This is helpful in determining LDAP client activity and if the DC is able to handle the load. Of course, spikes during normal periods of authentication — such as first thing in the morning — are not necessarily a problem, but long sustained periods of high values indicate an overworked DC | gauge | None
`windows_ad_link_values_cleaned_total` | _Not yet documented_ | counter | None
`windows_ad_phantom_objects_cleaned_total` | _Not yet documented_ | counter | None
`windows_ad_phantom_objects_visited_total` | _Not yet documented_ | counter | None
`windows_ad_sam_group_membership_evaluations_total` | _Not yet documented_ | counter | `group_type`
`windows_ad_sam_group_membership_global_catalog_evaluations_total` | _Not yet documented_ | counter | None
`windows_ad_sam_group_membership_evaluations_nontransitive_total` | _Not yet documented_ | counter | None
`windows_ad_sam_group_membership_evaluations_transitive_total` | _Not yet documented_ | counter | None
`windows_ad_sam_group_evaluation_latency` | _Not yet documented_ | gauge | `evaluation_type`
`windows_ad_sam_computer_creation_requests_total` | _Not yet documented_ | counter | None
`windows_ad_sam_computer_creation_successful_requests_total` | _Not yet documented_ | counter | None
`windows_ad_sam_user_creation_requests_total` | _Not yet documented_ | counter | None
`windows_ad_sam_user_creation_successful_requests_total` | _Not yet documented_ | counter | None
`windows_ad_sam_query_display_requests_total` | _Not yet documented_ | counter | None
`windows_ad_sam_enumerations_total` | _Not yet documented_ | counter | None
`windows_ad_sam_membership_changes_total` | _Not yet documented_ | counter | None
`windows_ad_sam_password_changes_total` | _Not yet documented_ | counter | None
`windows_ad_tombstoned_objects_collected_total` | _Not yet documented_ | counter | None
`windows_ad_tombstoned_objects_visited_total` | _Not yet documented_ | counter | None
`windows_ad_address_book_operations_total` | Total number of address book (NSPI) operations, by operation (AB ANR/Browses/Matches/Property Reads/Searches/Proxy Lookups) | counter | `operation`
`windows_ad_address_book_client_sessions` | Number of connected address book (NSPI) client sessions (AB Client Sessions) | gauge | None
`windows_ad_approximate_highest_distinguished_name_tag` | Approximate highest distinguished name tag (DNT) allocated in the directory database (Approximate highest DNT) | gauge | None
`windows_ad_atq_estimated_delay_seconds` | Estimated time in seconds the next request will spend in the ATQ queue before it is serviced (ATQ Estimated Queue Delay) | gauge | None
`windows_ad_atq_outstanding_requests` | Number of requests queued at the ATQ thread pool (ATQ Outstanding Queued Requests) | gauge | None
`windows_ad_atq_average_request_latency_seconds` | Average time in seconds to process a request, not including time spent on the queue (ATQ Request Latency) | gauge | None
`windows_ad_atq_current_threads` | Number of ATQ threads currently servicing requests, by service (ATQ Threads LDAP/Other) | gauge | `service`
`windows_ad_searches_total` | Total number of directory searches, by search scope (Base/Subtree/Onelevel searches) | counter | `scope`
`windows_ad_database_operations_total` | Total number of directory database operations, by operation (Database adds/deletes/modifys/recycles) | counter | `operation`
`windows_ad_binds_total` | Total number of binds, by bind method | counter | `bind_method`
`windows_ad_replication_highest_usn` | Highest update sequence number (USN) committed or issued by this domain controller (DRA Highest USN Committed/Issued) | counter | `state`
`windows_ad_replication_data_intrasite_bytes_total` | Total number of uncompressed bytes replicated within the site, by direction (DRA Inbound/Outbound Bytes Not Compressed (Within Site)) | counter | `direction`
`windows_ad_replication_data_intersite_bytes_total` | Total number of compressed bytes, after compression, replicated between sites, by direction (DRA Inbound/Outbound Bytes Compressed (Between Sites, After Compression)) | counter | `direction`
`windows_ad_replication_inbound_sync_objects_remaining` | Number of objects remaining until a full synchronization completes (DRA Inbound Full Sync Objects Remaining) | gauge | None
`windows_ad_replication_inbound_link_value_updates_remaining` | Number of link value updates received in the current replication packet that are not yet applied (DRA Inbound Link Value Updates Remaining in Packet) | gauge | None
`windows_ad_replication_inbound_objects_updated_total` | Total number of inbound replicated objects applied to the local directory (DRA Inbound Objects Applied) | counter | None
`windows_ad_replication_inbound_objects_filtered_total` | Total number of inbound replicated objects that had no updates to apply (DRA Inbound Objects Filtered) | counter | None
`windows_ad_replication_inbound_properties_updated_total` | Total number of inbound replicated properties applied to the local directory (DRA Inbound Properties Applied) | counter | None
`windows_ad_replication_inbound_properties_filtered_total` | Total number of inbound replicated property changes that were already applied (DRA Inbound Properties Filtered) | counter | None
`windows_ad_replication_pending_operations` | Number of queued replication operations not yet performed (DRA Pending Replication Operations) | gauge | None
`windows_ad_replication_pending_synchronizations` | Number of directory synchronizations queued for this server but not yet processed (DRA Pending Replication Synchronizations) | gauge | None
`windows_ad_replication_sync_requests_total` | Total number of synchronization requests made to replication partners (DRA Sync Requests Made) | counter | None
`windows_ad_replication_sync_requests_success_total` | Total number of successful synchronization requests made to replication partners (DRA Sync Requests Successful) | counter | None
`windows_ad_replication_sync_requests_schema_mismatch_failure_total` | Total number of synchronization requests that failed because of a schema mismatch (DRA Sync Failures on Schema Mismatch) | counter | None
`windows_ad_name_translations_total` | Total number of name translation requests, by origin of the request (DS Client/Server Name Translations) | counter | `target_name`
`windows_ad_change_monitors_registered` | Number of change notification requests registered with this server (DS Monitor List Size) | gauge | None
`windows_ad_change_monitor_updates_pending` | Number of pending change notifications not yet sent to clients (DS Notify Queue Size) | gauge | None
`windows_ad_name_cache_hits_total` | Total number of name translations resolved from the directory name cache (DS Name Cache hit rate numerator) | counter | None
`windows_ad_name_cache_lookups_total` | Total number of lookups in the directory name cache (DS Name Cache hit rate denominator) | counter | None
`windows_ad_directory_operations_total` | Total number of directory reads, searches and writes, by operation and origin (DS % Reads/Searches/Writes from ... numerators) | counter | `operation`, `origin`
`windows_ad_directory_search_suboperations_total` | Total number of directory search sub-operations; one sub-operation roughly corresponds to one object examined (DS Search sub-operations) | counter | None
`windows_ad_security_descriptor_propagation_suboperations_total` | Total number of security descriptor propagation sub-operations; one sub-operation roughly corresponds to one object examined (DS Security Descriptor sub-operations) | counter | None
`windows_ad_security_descriptor_propagation_events_queued` | Number of security descriptor propagation events that are queued but not yet processed (DS Security Descriptor Propagations Events) | gauge | None
`windows_ad_security_descriptor_propagation_average_exclusion_time_seconds` | Average time in seconds the security descriptor propagator waits for exclusive access to database elements during a sub-operation (DS Security Descriptor Propagator Average Exclusion Time, reported in milliseconds like the other latency counters of the object) | gauge | None
`windows_ad_security_descriptor_propagation_items_queued` | Number of objects remaining to examine while processing the current security descriptor propagation event (DS Security Descriptor Propagator Runtime Queue) | gauge | None
`windows_ad_directory_service_threads` | Number of threads in use by the directory service (DS Threads in Use) | gauge | None
`windows_ad_ldap_closed_connections_total` | Total number of closed LDAP connections (LDAP Closed Connections) | counter | None
`windows_ad_ldap_opened_connections_total` | Total number of opened LDAP connections, by type (LDAP New Connections, LDAP New SSL Connections) | counter | `type`
`windows_ad_ldap_active_threads` | Number of threads in use by the LDAP subsystem (LDAP Active Threads) | gauge | None
`windows_ad_ldap_last_bind_time_seconds` | Time in seconds taken by the last successful LDAP bind (LDAP Bind Time) | gauge | None
`windows_ad_ldap_searches_total` | Total number of LDAP search operations (LDAP Searches) | counter | None
`windows_ad_ldap_udp_operations_total` | Total number of LDAP UDP operations (LDAP UDP operations) | counter | None
`windows_ad_ldap_writes_total` | Total number of LDAP write operations (LDAP Writes) | counter | None
`windows_ad_ldap_client_sessions` | Number of sessions opened by LDAP clients (LDAP Client Sessions). Long sustained high values can indicate an overworked domain controller | gauge | None
`windows_ad_link_values_cleaned_total` | Total number of link values cleaned (Link Values Cleaned) | counter | None
`windows_ad_phantom_objects_cleaned_total` | Total number of phantom objects cleaned (Phantoms Cleaned) | counter | None
`windows_ad_phantom_objects_visited_total` | Total number of phantom objects visited (Phantoms Visited) | counter | None
`windows_ad_sam_group_membership_evaluations_total` | Total number of SAM group membership evaluations, by group type (SAM Global/Domain Local/Universal Group Membership Evaluations) | counter | `group_type`
`windows_ad_sam_group_membership_global_catalog_evaluations_total` | Total number of SAM group membership evaluations that required a global catalog (SAM GC Evaluations) | counter | None
`windows_ad_sam_group_membership_evaluations_nontransitive_total` | Total number of non-transitive SAM group membership evaluations (SAM Non-Transitive Membership Evaluations) | counter | None
`windows_ad_sam_group_membership_evaluations_transitive_total` | Total number of transitive SAM group membership evaluations (SAM Transitive Membership Evaluations) | counter | None
`windows_ad_sam_group_evaluation_latency_seconds` | Mean latency in seconds of the last 100 group evaluations performed for authentication, by evaluation type (SAM Account/Resource Group Evaluation Latency, reported in milliseconds like the other latency counters of the object) | gauge | `evaluation_type`
`windows_ad_sam_computer_creation_requests_total` | Total number of attempts to create computer accounts (SAM Machine Creation Attempts) | counter | None
`windows_ad_sam_computer_creation_successful_requests_total` | Total number of computer accounts created successfully (SAM Successful Computer Creations) | counter | None
`windows_ad_sam_user_creation_requests_total` | Total number of attempts to create user accounts (SAM User Creation Attempts) | counter | None
`windows_ad_sam_user_creation_successful_requests_total` | Total number of user accounts created successfully (SAM Successful User Creations) | counter | None
`windows_ad_sam_query_display_requests_total` | Total number of SAM display information queries (SAM Display Information Queries) | counter | None
`windows_ad_sam_enumerations_total` | Total number of SAM enumerations (SAM Enumerations) | counter | None
`windows_ad_sam_membership_changes_total` | Total number of SAM group membership changes (SAM Membership Changes) | counter | None
`windows_ad_sam_password_changes_total` | Total number of SAM password changes (SAM Password Changes) | counter | None
`windows_ad_tombstoned_objects_collected_total` | Total number of tombstoned objects garbage collected (Tombstones Garbage Collected) | counter | None
`windows_ad_tombstoned_objects_visited_total` | Total number of tombstoned objects visited by garbage collection (Tombstones Visited) | counter | None
### Example metric
_This collector does not yet have explained examples, we would appreciate your help adding them!_
+13
View File
@@ -60,6 +60,19 @@ cumulative count or an instantaneous value:
the last 100 evaluations) and
`DS Security Descriptor Propagator Average Exclusion Time`.
The explain texts of `ATQ Estimated Queue Delay`, `ATQ Request Latency`,
`ATQ Queue Latency` and `LDAP Bind Time` state milliseconds. Those of
`SAM Account/Resource Group Evaluation Latency` and
`DS Security Descriptor Propagator Average Exclusion Time` state no unit, and
Microsoft Learn does not document one. The collector treats them as
milliseconds like the other latencies of the object and divides each one it
reads by 1000 for the `_seconds` metrics. On the lab DC the SAM latencies
stayed 0 while about 700 group evaluations ran (S4U logons), so their unit is
not finer than milliseconds. The exclusion time stayed 0 during about 2400 SD
propagation sub-operations without lock contention, which says nothing about
its unit.
If a DC under contention shows implausible values, revisit the scaling.
Most `X` / `X/sec` pairs report the same raw value (for example
`LDAP Add Operations` and `LDAP Add Operations/sec`). `Objects visited/sec` and
`Objects returned/sec` do not: they stayed 0 while `Objects visited` and
File diff suppressed because it is too large Load Diff
+173
View File
@@ -0,0 +1,173 @@
// 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 ad
import (
"testing"
"github.com/prometheus/client_golang/prometheus"
dto "github.com/prometheus/client_model/go"
"github.com/stretchr/testify/require"
)
func TestCollectMetrics(t *testing.T) {
t.Parallel()
// Every counter gets a distinct value, so a metric that reads the wrong
// field shows up as a wrong value.
data := perfDataCounterValues{
AtqEstimatedQueueDelay: 250,
AtqRequestLatency: 1500,
DsPercentSearchesFromLSA: 9,
DsPercentWritesFromLSA: 12,
DsPercentReadsFromLSA: 70,
DsSecurityDescriptorSubOperationsPerSec: 17,
DsSecurityDescriptorPropagationsEvents: 3,
DsSecurityDescriptorPropagatorAverageExclusionTime: 42,
DsSecurityDescriptorPropagatorRuntimeQueue: 5,
LdapBindTime: 20,
SamAccountGroupEvaluationLatency: 30,
SamResourceGroupEvaluationLatency: 40,
SamMachineCreationAttemptsPerSec: 7,
SamSuccessfulComputerCreationsPerSecIncludesAllRequests: 4,
SamUserCreationAttemptsPerSec: 11,
SamSuccessfulUserCreationsPerSec: 10,
}
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)
byName := make(map[string]*dto.MetricFamily, len(families))
for _, family := range families {
require.NotEmpty(t, family.GetHelp(), "metric %s has no HELP", family.GetName())
byName[family.GetName()] = family
}
for _, tc := range []struct {
name string
labels map[string]string
metricType dto.MetricType
value float64
}{
{
name: "windows_ad_directory_operations_total",
labels: map[string]string{"operation": "write", "origin": "local_security_authority"},
metricType: dto.MetricType_COUNTER,
value: 12,
},
{
name: "windows_ad_directory_operations_total",
labels: map[string]string{"operation": "search", "origin": "local_security_authority"},
metricType: dto.MetricType_COUNTER,
value: 9,
},
{
name: "windows_ad_directory_operations_total",
labels: map[string]string{"operation": "read", "origin": "local_security_authority"},
metricType: dto.MetricType_COUNTER,
value: 70,
},
{name: "windows_ad_sam_computer_creation_requests_total", metricType: dto.MetricType_COUNTER, value: 7},
{name: "windows_ad_sam_computer_creation_successful_requests_total", metricType: dto.MetricType_COUNTER, value: 4},
{name: "windows_ad_sam_user_creation_requests_total", metricType: dto.MetricType_COUNTER, value: 11},
{name: "windows_ad_sam_user_creation_successful_requests_total", metricType: dto.MetricType_COUNTER, value: 10},
{name: "windows_ad_security_descriptor_propagation_suboperations_total", metricType: dto.MetricType_COUNTER, value: 17},
{name: "windows_ad_security_descriptor_propagation_events_queued", metricType: dto.MetricType_GAUGE, value: 3},
{name: "windows_ad_security_descriptor_propagation_average_exclusion_time_seconds", metricType: dto.MetricType_GAUGE, value: 0.042},
{name: "windows_ad_security_descriptor_propagation_items_queued", metricType: dto.MetricType_GAUGE, value: 5},
{name: "windows_ad_atq_estimated_delay_seconds", metricType: dto.MetricType_GAUGE, value: 0.25},
{name: "windows_ad_atq_average_request_latency_seconds", metricType: dto.MetricType_GAUGE, value: 1.5},
{name: "windows_ad_ldap_last_bind_time_seconds", metricType: dto.MetricType_GAUGE, value: 0.02},
{
name: "windows_ad_sam_group_evaluation_latency_seconds",
labels: map[string]string{"evaluation_type": "account_group"},
metricType: dto.MetricType_GAUGE,
value: 0.03,
},
{
name: "windows_ad_sam_group_evaluation_latency_seconds",
labels: map[string]string{"evaluation_type": "resource_group"},
metricType: dto.MetricType_GAUGE,
value: 0.04,
},
} {
family, ok := byName[tc.name]
require.True(t, ok, "metric %s not published", tc.name)
require.Equal(t, tc.metricType, family.GetType(), tc.name)
metric := findMetric(t, family, tc.labels)
actual := metric.GetGauge().GetValue()
if tc.metricType == dto.MetricType_COUNTER {
actual = metric.GetCounter().GetValue()
}
require.InDelta(t, tc.value, actual, 1e-9, "%s%v", tc.name, tc.labels)
}
for _, name := range []string{
"windows_ad_atq_average_request_latency",
"windows_ad_sam_group_evaluation_latency",
"windows_ad_security_descriptor_propagation_access_wait_total_seconds",
"windows_ad_security_descriptor_propagation_events_total",
"windows_ad_security_descriptor_propagation_items_queued_total",
} {
require.NotContains(t, byName, name, "renamed metric %s is still published", name)
}
}
func findMetric(t *testing.T, family *dto.MetricFamily, labels map[string]string) *dto.Metric {
t.Helper()
for _, metric := range family.GetMetric() {
matched := 0
for _, label := range metric.GetLabel() {
if value, ok := labels[label.GetName()]; ok && value == label.GetValue() {
matched++
}
}
if matched == len(labels) {
return metric
}
}
require.FailNow(t, "series not found", "%s%v", family.GetName(), labels)
return nil
}
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.collectMetrics(ch, c.data)
}