collector: name instance labels after the entity they identify (#2744)

Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-16 11:07:04 +02:00
committed by GitHub
parent 3fb18521f6
commit 667200f757
67 changed files with 1960 additions and 751 deletions
+41 -41
View File
@@ -206,63 +206,63 @@ func (c *Collector) buildDescriptors() {
c.connectionBandwidthSavingsUsingDFSReplicationRatio = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_bandwidth_savings_using_dfs_replication_ratio"),
"Share of bandwidth saved by DFS Replication for this connection using RDC and other compression, compared to transferring the files uncompressed (0-1)",
[]string{"name"},
[]string{"connection"},
nil,
)
c.connectionBytesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_bytes_received_total"),
"Total bytes received for connection",
[]string{"name"},
[]string{"connection"},
nil,
)
c.connectionCompressedSizeOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_compressed_size_of_files_received_bytes_total"),
"Total compressed size of files received on the connection, in bytes",
[]string{"name"},
[]string{"connection"},
nil,
)
c.connectionFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_received_files_total"),
"Total number of files received for connection",
[]string{"name"},
[]string{"connection"},
nil,
)
c.connectionRDCBytesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_received_bytes_total"),
"Total bytes received on the connection while replicating files using Remote Differential Compression",
[]string{"name"},
[]string{"connection"},
nil,
)
c.connectionRDCCompressedSizeOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_compressed_size_of_received_files_bytes_total"),
"Total compressed size of files received with Remote Differential Compression on the connection, in bytes. This is the number of bytes that would have been received had RDC not been used",
[]string{"name"},
[]string{"connection"},
nil,
)
c.connectionRDCNumberOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_received_files_total"),
"Total number of files received using remote differential compression",
[]string{"name"},
[]string{"connection"},
nil,
)
c.connectionRDCSizeOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_rdc_size_of_received_files_bytes_total"),
"Total size of received Remote Differential Compression files, in bytes.",
[]string{"name"},
[]string{"connection"},
nil,
)
c.connectionSizeOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "connection_files_received_bytes_total"),
"Total size of files received, in bytes",
[]string{"name"},
[]string{"connection"},
nil,
)
@@ -270,189 +270,189 @@ func (c *Collector) buildDescriptors() {
c.folderBandwidthSavingsUsingDFSReplicationRatio = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_bandwidth_savings_using_dfs_replication_ratio"),
"Share of bandwidth saved by DFS Replication for this replicated folder using RDC and other compression, compared to transferring the files uncompressed (0-1)",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderCompressedSizeOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_compressed_size_of_received_files_bytes_total"),
"Total compressed size of files received on the folder, in bytes",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderConflictBytesCleanedUpTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_cleaned_up_bytes_total"),
"Total size of conflict loser files and folders deleted from the Conflict and Deleted folder, in bytes",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderConflictBytesGeneratedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_generated_bytes_total"),
"Total size of conflict loser files and folders moved to the Conflict and Deleted folder, in bytes",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderConflictFilesCleanedUpTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_cleaned_up_files_total"),
"Number of conflict loser files deleted from the Conflict and Deleted folder",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderConflictFilesGeneratedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_generated_files_total"),
"Number of files and folders moved to the Conflict and Deleted folder",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderConflictFolderCleanupsCompletedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_folder_cleanups_total"),
"Number of deletions of conflict loser files and folders in the Conflict and Deleted",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderConflictSpaceInUse = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_conflict_space_in_use_bytes"),
"Total size of the conflict loser files and folders currently in the Conflict and Deleted folder",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderDeletedSpaceInUse = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_deleted_space_in_use_bytes"),
"Total size (in bytes) of the deleted files and folders currently in the Conflict and Deleted folder",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderDeletedBytesCleanedUpTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_deleted_cleaned_up_bytes_total"),
"Total size (in bytes) of replicating deleted files and folders that were cleaned up from the Conflict and Deleted folder",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderDeletedBytesGeneratedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_deleted_generated_bytes_total"),
"Total size (in bytes) of replicated deleted files and folders that were moved to the Conflict and Deleted folder after they were deleted from a replicated folder on a sending member",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderDeletedFilesCleanedUpTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_deleted_cleaned_up_files_total"),
"Number of files and folders that were cleaned up from the Conflict and Deleted folder",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderDeletedFilesGeneratedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_deleted_generated_files_total"),
"Number of deleted files and folders that were moved to the Conflict and Deleted folder",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderFileInstallsRetriedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_file_installs_retried_total"),
"Total number of file installs that are being retried due to sharing violations or other errors encountered when installing the files",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderFileInstallsSucceededTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_file_installs_succeeded_total"),
"Total number of files that were successfully received from sending members and installed locally on this server",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_received_files_total"),
"Total number of files received",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderRDCBytesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_received_bytes_total"),
"Total number of bytes received in replicating files using Remote Differential Compression",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderRDCCompressedSizeOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_compressed_size_of_received_files_bytes_total"),
"Total compressed size (in bytes) of the files received with Remote Differential Compression",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderRDCNumberOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_received_files_total"),
"Total number of files received with Remote Differential Compression",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderRDCSizeOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_rdc_files_received_bytes_total"),
"Total uncompressed size (in bytes) of the files received with Remote Differential Compression",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderSizeOfFilesReceivedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_files_received_bytes_total"),
"Total uncompressed size (in bytes) of the files received",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderStagingSpaceInUse = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_staging_space_in_use_bytes"),
"Total size of files and folders currently in the staging folder.",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderStagingBytesCleanedUpTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_staging_cleaned_up_bytes_total"),
"Total size (in bytes) of the files and folders that have been cleaned up from the staging folder",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderStagingBytesGeneratedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_staging_generated_bytes_total"),
"Total size (in bytes) of replicated files and folders in the staging folder created by the DFS Replication service since last restart",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderStagingFilesCleanedUpTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_staging_cleaned_up_files_total"),
"Total number of files and folders that have been cleaned up from the staging folder",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderStagingFilesGeneratedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_staging_generated_files_total"),
"Total number of times replicated files and folders have been staged by the DFS Replication service",
[]string{"name"},
[]string{"folder"},
nil,
)
c.folderUpdatesDroppedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "folder_dropped_updates_total"),
"Total number of redundant file replication update records that have been ignored by the DFS Replication service because they did not change the replicated file or folder",
[]string{"name"},
[]string{"folder"},
nil,
)
@@ -460,35 +460,35 @@ func (c *Collector) buildDescriptors() {
c.volumeDatabaseCommitsTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "volume_database_commits_total"),
"Total number of DFSR volume database commits",
[]string{"name"},
[]string{"volume"},
nil,
)
c.volumeDatabaseLookupsTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "volume_database_lookups_total"),
"Total number of DFSR volume database lookups",
[]string{"name"},
[]string{"volume"},
nil,
)
c.volumeUSNJournalUnreadRatio = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "volume_usn_journal_unread_ratio"),
"Share of the volume USN journal that DFS Replication has not read and processed yet (0-1). A journal wrap occurs at 1",
[]string{"name"},
[]string{"volume"},
nil,
)
c.volumeUSNJournalRecordsAcceptedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "volume_usn_journal_accepted_records_total"),
"Total number of USN journal records accepted",
[]string{"name"},
[]string{"volume"},
nil,
)
c.volumeUSNJournalRecordsReadTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "volume_usn_journal_read_records_total"),
"Total number of DFSR volume USN journal records read",
[]string{"name"},
[]string{"volume"},
nil,
)
}
+1 -1
View File
@@ -193,7 +193,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
c.scopeInfo = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "scope_info"),
"DHCP Scope information",
[]string{"name", "superscope_name", "superscope_id", "scope"},
[]string{"scope_name", "superscope_name", "superscope_id", "scope"},
nil,
)
+1 -1
View File
@@ -31,5 +31,5 @@ func BenchmarkCollector(b *testing.B) {
func TestCollector(t *testing.T) {
metrics := testutils.TestCollector(t, dhcp.New, nil)
testutils.RequireFixtureMetric(t, metrics, dhcp.Name, "windows_dhcp_scope_info", prometheus.Labels{"name": "GitHubActions", "scope": "192.0.2.0/24"})
testutils.RequireFixtureMetric(t, metrics, dhcp.Name, "windows_dhcp_scope_info", prometheus.Labels{"scope_name": "GitHubActions", "scope": "192.0.2.0/24"})
}
+11 -14
View File
@@ -86,32 +86,31 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
"device_id",
"model",
"caption",
"name",
},
nil,
)
c.status = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "status"),
"Status of the drive",
[]string{"name", "status"},
[]string{"device_id", "status"},
nil,
)
c.size = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "size_bytes"),
"Size of the disk drive. It is calculated by multiplying the total number of cylinders, tracks in each cylinder, sectors in each track, and bytes in each sector.",
[]string{"name"},
[]string{"device_id"},
nil,
)
c.partitions = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "partitions"),
"Number of partitions",
[]string{"name"},
[]string{"device_id"},
nil,
)
c.availability = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "availability"),
"Availability Status",
[]string{"name", "availability"},
[]string{"device_id", "availability"},
nil,
)
@@ -119,7 +118,7 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
return errors.New("miSession is nil")
}
miQuery, err := mi.NewQuery("SELECT DeviceID, Model, Caption, Name, Partitions, Size, Status, Availability FROM WIN32_DiskDrive")
miQuery, err := mi.NewQuery("SELECT DeviceID, Model, Caption, Partitions, Size, Status, Availability FROM WIN32_DiskDrive")
if err != nil {
return fmt.Errorf("failed to create WMI query: %w", err)
}
@@ -137,7 +136,6 @@ type diskDrive struct {
DeviceID string `mi:"DeviceID"`
Model string `mi:"Model"`
Size uint64 `mi:"Size"`
Name string `mi:"Name"`
Caption string `mi:"Caption"`
Partitions uint32 `mi:"Partitions"`
Status string `mi:"Status"`
@@ -198,16 +196,15 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric, maxScrapeDuration time.
}
for _, disk := range dst {
distName := strings.Trim(disk.Name, `\.`)
deviceID := strings.Trim(disk.DeviceID, `\.`)
ch <- prometheus.MustNewConstMetric(
c.diskInfo,
prometheus.GaugeValue,
1.0,
strings.Trim(disk.DeviceID, `\.`),
deviceID,
strings.TrimRight(disk.Model, " "),
strings.TrimRight(disk.Caption, " "),
distName,
)
for _, status := range allDiskStatus {
@@ -220,7 +217,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric, maxScrapeDuration time.
c.status,
prometheus.GaugeValue,
isCurrentState,
distName,
deviceID,
status,
)
}
@@ -229,14 +226,14 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric, maxScrapeDuration time.
c.size,
prometheus.GaugeValue,
float64(disk.Size),
distName,
deviceID,
)
ch <- prometheus.MustNewConstMetric(
c.partitions,
prometheus.GaugeValue,
float64(disk.Partitions),
distName,
deviceID,
)
for availNum, val := range availMap {
@@ -249,7 +246,7 @@ func (c *Collector) Collect(ch chan<- prometheus.Metric, maxScrapeDuration time.
c.availability,
prometheus.GaugeValue,
isCurrentState,
distName,
deviceID,
val,
)
}
+1 -1
View File
@@ -307,7 +307,7 @@ func (c *Collector) buildDescriptors() {
c.dnsWMIStats = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "wmi_stats_total"),
"DNS WMI statistics from MicrosoftDNS_Statistic",
[]string{"name", "collection_name", "dns_server"},
[]string{"statistic", "collection_name", "dns_server"},
nil,
)
}
@@ -67,49 +67,49 @@ func (c *Collector) buildADAccessProcesses() error {
c.ldapReadTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_read_time_seconds_total"),
"Total time in seconds to send an LDAP read request and receive a response",
[]string{"name"},
[]string{"process"},
nil,
)
c.ldapReadOperations = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_read_operations_total"),
"Total number of LDAP read operations",
[]string{"name"},
[]string{"process"},
nil,
)
c.ldapSearchTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_search_time_seconds_total"),
"Total time in seconds to send an LDAP search request and receive a response",
[]string{"name"},
[]string{"process"},
nil,
)
c.ldapSearchOperations = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_search_operations_total"),
"Total number of LDAP search operations",
[]string{"name"},
[]string{"process"},
nil,
)
c.ldapWriteTime = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_write_time_seconds_total"),
"Total time in seconds to send an LDAP Add/Modify/Delete request and receive a response",
[]string{"name"},
[]string{"process"},
nil,
)
c.ldapWriteOperations = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_write_operations_total"),
"Total number of LDAP Add/Modify/Delete operations",
[]string{"name"},
[]string{"process"},
nil,
)
c.ldapTimeoutErrorsPerSec = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_timeout_errors_total"),
"Total number of LDAP timeout errors",
[]string{"name"},
[]string{"process"},
nil,
)
c.longRunningLDAPOperationsPerMin = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "ldap_long_running_operations_per_second"),
"Long running LDAP operations per second, averaged over the last minute. Exchange reports the per-minute value as a raw count (Windows has no per-minute counter type); the collector divides it by 60",
[]string{"name"},
[]string{"process"},
nil,
)
@@ -60,37 +60,37 @@ func (c *Collector) buildHTTPProxy() error {
c.mailboxServerLocatorAverageLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_mailbox_server_locator_avg_latency_seconds"),
"Average latency in seconds of MailboxServerLocator web service calls",
[]string{"name"},
[]string{"protocol"},
nil,
)
c.averageAuthenticationLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_avg_auth_latency_seconds"),
"Average time in seconds spent authenticating CAS requests over the last 200 samples",
[]string{"name"},
[]string{"protocol"},
nil,
)
c.outstandingProxyRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_outstanding_proxy_requests"),
"Number of concurrent outstanding proxy requests",
[]string{"name"},
[]string{"protocol"},
nil,
)
c.proxyRequestsPerSec = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_requests_total"),
"Number of proxy requests processed each second",
[]string{"name"},
[]string{"protocol"},
nil,
)
c.averageCASProcessingLatency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_avg_cas_processing_latency_seconds"),
"Average latency in seconds of CAS processing time over the last 200 reqs",
[]string{"name"},
[]string{"protocol"},
nil,
)
c.mailboxServerProxyFailureRate = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "http_proxy_mailbox_proxy_failure_ratio"),
"Ratio (0-1) of failures between this CAS and MBX servers over the last 200 samples",
[]string{"name"},
[]string{"protocol"},
nil,
)
@@ -85,115 +85,115 @@ func (c *Collector) buildTransportQueues() error {
c.externalActiveRemoteDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_external_active_remote_delivery"),
"External Active Remote Delivery Queue length",
[]string{"name"},
[]string{"queue"},
nil,
)
c.internalActiveRemoteDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_internal_active_remote_delivery"),
"Internal Active Remote Delivery Queue length",
[]string{"name"},
[]string{"queue"},
nil,
)
c.activeMailboxDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_active_mailbox_delivery"),
"Active Mailbox Delivery Queue length",
[]string{"name"},
[]string{"queue"},
nil,
)
c.retryMailboxDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_retry_mailbox_delivery"),
"Retry Mailbox Delivery Queue length",
[]string{"name"},
[]string{"queue"},
nil,
)
c.unreachableQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_unreachable"),
"Unreachable Queue length",
[]string{"name"},
[]string{"queue"},
nil,
)
c.externalLargestDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_external_largest_delivery"),
"External Largest Delivery Queue length",
[]string{"name"},
[]string{"queue"},
nil,
)
c.internalLargestDeliveryQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_internal_largest_delivery"),
"Internal Largest Delivery Queue length",
[]string{"name"},
[]string{"queue"},
nil,
)
c.poisonQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_poison"),
"Poison Queue length",
[]string{"name"},
[]string{"queue"},
nil,
)
c.messagesQueuedForDeliveryTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_messages_queued_for_delivery_total"),
"Messages Queued For Delivery Total",
[]string{"name"},
[]string{"queue"},
nil,
)
c.messagesSubmittedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_messages_submitted_total"),
"Messages Submitted Total",
[]string{"name"},
[]string{"queue"},
nil,
)
c.messagesDelayedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_messages_delayed_total"),
"Messages Delayed Total",
[]string{"name"},
[]string{"queue"},
nil,
)
c.messagesCompletedDeliveryTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_messages_completed_delivery_total"),
"Messages Completed Delivery Total",
[]string{"name"},
[]string{"queue"},
nil,
)
c.aggregateShadowQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_aggregate_shadow_queue_length"),
"The current number of messages in shadow queues.",
[]string{"name"},
[]string{"queue"},
nil,
)
c.submissionQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_submission_queue_length"),
"Submission Queue Length",
[]string{"name"},
[]string{"queue"},
nil,
)
c.delayQueueLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_delay_queue_length"),
"Delay Queue Length",
[]string{"name"},
[]string{"queue"},
nil,
)
c.itemsCompletedDeliveryTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_items_completed_delivery_total"),
"Items Completed Delivery Total",
[]string{"name"},
[]string{"queue"},
nil,
)
c.itemsQueuedForDeliveryExpiredTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_items_queued_for_delivery_expired_total"),
"Items Queued For Delivery Expired Total",
[]string{"name"},
[]string{"queue"},
nil,
)
c.itemsQueuedForDeliveryTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_items_queued_for_delivery_total"),
"Items Queued For Delivery Total",
[]string{"name"},
[]string{"queue"},
nil,
)
c.itemsResubmittedTotal = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "transport_queues_items_resubmitted_total"),
"Items Resubmitted Total",
[]string{"name"},
[]string{"queue"},
nil,
)
@@ -57,31 +57,31 @@ func (c *Collector) buildWorkloadManagementWorkloads() error {
c.activeTasks = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "workload_active_tasks"),
"Number of active tasks currently running in the background for workload management",
[]string{"name"},
[]string{"workload"},
nil,
)
c.completedTasks = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "workload_completed_tasks_total"),
"Number of workload management tasks that have been completed",
[]string{"name"},
[]string{"workload"},
nil,
)
c.queuedTasks = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "workload_queued_tasks"),
"Number of workload management tasks that are currently queued up waiting to be processed",
[]string{"name"},
[]string{"workload"},
nil,
)
c.yieldedTasks = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "workload_yielded_tasks_total"),
"The total number of tasks that have been yielded by a workload",
[]string{"name"},
[]string{"workload"},
nil,
)
c.isActive = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "workload_is_active"),
"Active indicates whether the workload is in an active (1) or paused (0) state",
[]string{"name"},
[]string{"workload"},
nil,
)
+17 -17
View File
@@ -83,103 +83,103 @@ func (c *Collector) buildVirtualSMB() error {
c.virtualSMBDirectMappedSections = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_direct_mapped_sections"),
"Represents the number of direct-mapped sections in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBDirectMappedPages = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_direct_mapped_pages"),
"Represents the number of direct-mapped pages in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBWriteBytesRDMA = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_rdma_write_bytes_total"),
"Represents the total number of bytes written using RDMA in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBWriteBytes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_write_bytes_total"),
"Represents the total number of bytes written in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBReadBytesRDMA = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_rdma_read_bytes_total"),
"Represents the total number of bytes read using RDMA in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBReadBytes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_read_bytes_total"),
"Represents the total number of bytes read in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBFlushRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_flush_requests_total"),
"Represents the total number of flush requests in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBWriteRequestsRDMA = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_rdma_write_requests_total"),
"Represents the total number of write requests using RDMA in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBWriteRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_write_requests_total"),
"Represents the total number of write requests in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBReadRequestsRDMA = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_rdma_read_requests_total"),
"Represents the total number of read requests using RDMA in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBReadRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_read_requests_total"),
"Represents the total number of read requests in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBCurrentPendingRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_current_pending_requests"),
"Represents the current number of pending requests in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBCurrentOpenFileCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_open_files"),
"Represents the current number of open files in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBTreeConnectCount = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_tree_connects_total"),
"Represents the total number of tree connects in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBRequests = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_requests_total"),
"Represents the total number of requests in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBSentBytes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_sent_bytes_total"),
"Represents the total number of bytes sent in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
c.virtualSMBReceivedBytes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "virtual_smb_received_bytes_total"),
"Represents the total number of bytes received in the virtual SMB",
[]string{"instance"},
[]string{"vm"},
nil,
)
@@ -216,451 +216,451 @@ func (c *Collector) buildClusterDescriptors() {
c.clusterAddEvictDelay = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "add_evict_delay_seconds"),
"Provides access to the cluster's AddEvictDelay property, which is the number of seconds that a new node is delayed after an eviction of another node.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterAdminAccessPoint = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "admin_access_point"),
"The type of the cluster administrative access point.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterAutoAssignNodeSite = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "auto_assign_node_site"),
"Determines whether or not the cluster will attempt to automatically assign nodes to sites based on networks and Active Directory Site information.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterAutoBalancerLevel = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "auto_balancer_level"),
"Determines the level of aggressiveness of AutoBalancer.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterAutoBalancerMode = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "auto_balancer_mode"),
"Determines whether or not the auto balancer is enabled.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterBackupInProgress = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "backup_in_progress"),
"Indicates whether a backup is in progress.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterBlockCacheSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "block_cache_size_bytes"),
"CSV BlockCache size in bytes.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusSvcHangTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "clus_svc_hang_timeout_seconds"),
"Controls how long, in seconds, the cluster network driver waits between Failover Cluster Service heartbeats before it determines that the Failover Cluster Service has stopped responding.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusSvcRegroupOpeningTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "clus_svc_regroup_opening_timeout_seconds"),
"Controls how long, in seconds, a node will wait on other nodes in the opening stage before deciding that they failed.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusSvcRegroupPruningTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "clus_svc_regroup_pruning_timeout_seconds"),
"Controls how long, in seconds, the membership leader will wait to reach full connectivity between cluster nodes.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusSvcRegroupStageTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "clus_svc_regroup_stage_timeout_seconds"),
"Controls how long, in seconds, a node will wait on other nodes in a membership stage before deciding that they failed.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusSvcRegroupTickInMilliseconds = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "clus_svc_regroup_tick_seconds"),
"Controls how frequently, in seconds, the membership algorithm is sending periodic membership messages.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusterEnforcedAntiAffinity = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "cluster_enforced_anti_affinity"),
"Enables or disables hard enforcement of group anti-affinity classes.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusterFunctionalLevel = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "cluster_functional_level"),
"The functional level the cluster is currently running in.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusterGroupWaitDelay = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "cluster_group_wait_delay_seconds"),
"Maximum time in seconds that a group waits for its preferred node to come online during cluster startup before coming online on a different node.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusterLogLevel = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "cluster_log_level"),
"Controls the level of cluster logging.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusterLogSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "cluster_log_size_bytes"),
"Controls the maximum size, in bytes, of the cluster log files on each of the nodes.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterClusterUpgradeVersion = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "cluster_upgrade_version"),
"Specifies the upgrade version the cluster is currently running in.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterCrossSiteDelay = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "cross_site_delay_seconds"),
"Controls how long the cluster network driver waits in seconds between sending Cluster Service heartbeats across sites.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterCrossSiteThreshold = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "cross_site_threshold"),
"Controls how many Cluster Service heartbeats can be missed across sites before it determines that Cluster Service has stopped responding.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterCrossSubnetDelay = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "cross_subnet_delay_seconds"),
"Controls how long the cluster network driver waits in seconds between sending Cluster Service heartbeats across subnets.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterCrossSubnetThreshold = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "cross_subnet_threshold"),
"Controls how many Cluster Service heartbeats can be missed across subnets before it determines that Cluster Service has stopped responding.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterCsvBalancer = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "csv_balancer"),
"Whether automatic balancing for CSV is enabled.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterDatabaseReadWriteMode = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "database_read_write_mode"),
"Sets the database read and write mode.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterDefaultNetworkRole = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "default_network_role"),
"Provides access to the cluster's DefaultNetworkRole property.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterDetectedCloudPlatform = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "detected_cloud_platform"),
"(DetectedCloudPlatform)",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterDetectManagedEvents = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "detect_managed_events"),
"(DetectManagedEvents)",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterDetectManagedEventsThreshold = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "detect_managed_events_threshold"),
"(DetectManagedEventsThreshold)",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterDisableGroupPreferredOwnerRandomization = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "disable_group_preferred_owner_randomization"),
"(DisableGroupPreferredOwnerRandomization)",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterDrainOnShutdown = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "drain_on_shutdown"),
"Whether to drain the node when cluster service is being stopped.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterDynamicQuorumEnabled = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "dynamic_quorum_enabled"),
"Allows cluster service to adjust node weights as needed to increase availability.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterEnableSharedVolumes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "enable_shared_volumes"),
"Enables or disables cluster shared volumes on this cluster.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterFixQuorum = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "fix_quorum"),
"Provides access to the cluster's FixQuorum property, which specifies if the cluster is in a fix quorum state.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterGracePeriodEnabled = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "grace_period_enabled"),
"Whether the node grace period feature of this cluster is enabled.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterGracePeriodTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "grace_period_timeout_seconds"),
"The grace period timeout in seconds.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterGroupDependencyTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "group_dependency_timeout_seconds"),
"The timeout in seconds after which a group will be brought online despite unsatisfied dependencies",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterHangRecoveryAction = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "hang_recovery_action"),
"Controls the action to take if the user-mode processes have stopped responding.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterIgnorePersistentStateOnStartup = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "ignore_persistent_state_on_startup"),
"Provides access to the cluster's IgnorePersistentStateOnStartup property, which specifies whether the cluster will bring online groups that were online when the cluster was shut down.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterLogResourceControls = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "log_resource_controls"),
"Controls the logging of resource controls.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterLowerQuorumPriorityNodeId = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "lower_quorum_priority_node_id"),
"Specifies the Node ID that has a lower priority when voting for quorum is performed. If the quorum vote is split 50/50%, the specified node's vote would be ignored to break the tie. If this is not set then the cluster will pick a node at random to break the tie.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterMaxNumberOfNodes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "max_number_of_nodes"),
"Indicates the maximum number of nodes that may participate in the Cluster.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterMessageBufferLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "message_buffer_length"),
"The maximum unacknowledged message count for GEM.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterMinimumNeverPreemptPriority = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "minimum_never_preempt_priority"),
"Groups with this priority or higher cannot be preempted.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterMinimumPreemptorPriority = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "minimum_preemptor_priority"),
"Minimum priority a cluster group must have to be able to preempt another group.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterNetftIPSecEnabled = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "netft_ip_sec_enabled"),
"Whether IPSec is enabled for cluster internal traffic.cluster",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterPlacementOptions = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "placement_options"),
"Various option flags to modify default placement behavior.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterPlumbAllCrossSubnetRoutes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "plumb_all_cross_subnet_routes"),
"Plumbs all possible cross subnet routes to all nodes.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterPreventQuorum = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "prevent_quorum"),
"Whether the cluster will ignore group persistent state on startup.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterQuarantineDuration = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "quarantine_duration_seconds"),
"The quarantine period timeout in seconds.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterQuarantineThreshold = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "quarantine_threshold"),
"Number of node failures before it will be quarantined.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterQuorumArbitrationTimeMax = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "quorum_arbitration_time_max_seconds"),
"Controls the maximum time, in seconds, necessary to decide the Quorum owner node.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterQuorumArbitrationTimeMin = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "quorum_arbitration_time_min_seconds"),
"Controls the minimum time, in seconds, necessary to decide the Quorum owner node.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterQuorumTypeValue = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "quorum_type_value"),
"Get the current quorum type value. -1: Unknown; 1: Node; 2: FileShareWitness; 3: Storage; 4: None",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterRequestReplyTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "request_reply_timeout_seconds"),
"Controls the request reply time-out period in seconds.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterResiliencyDefaultPeriod = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "resiliency_default_period_seconds"),
"The default resiliency period, in seconds, for the cluster.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterResiliencyLevel = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "resiliency_level"),
"The resiliency level for the cluster.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterRootMemoryReserved = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "root_memory_reserved_bytes"),
"Controls the amount of memory, in bytes, reserved for the parent partition on all cluster nodes.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterRouteHistoryLength = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "route_history_length"),
"The history length for routes to help finding network issues.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterS2DBusTypes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "s2d_bus_types"),
"Bus types for storage spaces direct.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterS2DCacheDesiredState = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "s2d_cache_desired_state"),
"Desired state of the storage spaces direct cache.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterS2DCacheFlashReservePercent = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "s2d_cache_flash_reserve_ratio"),
"Ratio (0-1) of allocated flash space to utilize when caching.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterS2DCachePageSizeKBytes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "s2d_cache_page_size_bytes"),
"Page size in bytes used by S2D cache.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterS2DEnabled = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "s2d_enabled"),
"Whether direct attached storage (DAS) is enabled.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterS2DIOLatencyThreshold = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "s2dio_latency_threshold_seconds"),
"The I/O latency threshold in seconds for storage spaces direct.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterS2DOptimizations = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "s2d_optimizations"),
"Optimization flags for storage spaces direct.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterSameSubnetDelay = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "same_subnet_delay_seconds"),
"Controls how long the cluster network driver waits in seconds between sending Cluster Service heartbeats on the same subnet.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterSameSubnetThreshold = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "same_subnet_threshold"),
"Controls how many Cluster Service heartbeats can be missed on the same subnet before it determines that Cluster Service has stopped responding.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterSecurityLevel = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "security_level"),
"Controls the level of security that should apply to intracluster messages. 0: Clear Text; 1: Sign; 2: Encrypt ",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterSecurityLevelForStorage = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "security_level_for_storage"),
"(SecurityLevelForStorage)",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterSharedVolumeVssWriterOperationTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "shared_volume_vss_writer_operation_timeout_seconds"),
"CSV VSS Writer operation timeout in seconds.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterShutdownTimeoutInMinutes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "shutdown_timeout_seconds"),
"The maximum time in seconds allowed for cluster resources to come offline during cluster service shutdown.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterUseClientAccessNetworksForSharedVolumes = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "use_client_access_networks_for_shared_volumes"),
"Whether the use of client access networks for cluster shared volumes feature of this cluster is enabled. 0: Disabled; 1: Enabled; 2: Auto",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterWitnessDatabaseWriteTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "witness_database_write_timeout_seconds"),
"Controls the maximum time in seconds that a cluster database write to a witness can take before the write is abandoned.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterWitnessDynamicWeight = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "witness_dynamic_weight"),
"The weight of the configured witness.",
[]string{"name"},
[]string{"cluster"},
nil,
)
c.clusterWitnessRestartInterval = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameCluster, "witness_restart_interval_seconds"),
"Controls the witness restart interval in seconds.",
[]string{"name"},
[]string{"cluster"},
nil,
)
}
@@ -111,7 +111,7 @@ func TestClusterNativeMetricContract(t *testing.T) {
t.Fatalf("invalid family %s", name)
}
if !maps.Equal(metricLabels(family.GetMetric()[0]), map[string]string{"name": "CICluster"}) {
if !maps.Equal(metricLabels(family.GetMetric()[0]), map[string]string{"cluster": "CICluster"}) {
t.Fatalf("%s labels = %v", name, metricLabels(family.GetMetric()[0]))
}
}
@@ -75,31 +75,31 @@ func (c *Collector) buildNetworkDescriptors() {
c.networkCharacteristics = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNetwork, "characteristics"),
"Provides the characteristics of the network.",
[]string{"name"},
[]string{"network"},
nil,
)
c.networkFlags = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNetwork, "flags"),
"Provides access to the flags set for the node. ",
[]string{"name"},
[]string{"network"},
nil,
)
c.networkMetric = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNetwork, "metric"),
"The metric of a cluster network (networks with lower values are used first). If this value is set, then the AutoMetric property is set to false.",
[]string{"name"},
[]string{"network"},
nil,
)
c.networkRole = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNetwork, "role"),
"Provides access to the network's Role property. The Role property describes the role of the network in the cluster. 0: None; 1: Cluster; 2: Client; 3: Both ",
[]string{"name"},
[]string{"network"},
nil,
)
c.networkState = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNetwork, "state"),
"Provides the current state of the network. 1-1: Unknown; 0: Unavailable; 1: Down; 2: Partitioned; 3: Up",
[]string{"name"},
[]string{"network"},
nil,
)
}
@@ -71,7 +71,7 @@ func TestNetworkNativeMetricContract(t *testing.T) {
t.Errorf("%s value = %v, want %v", suffix, metric.GetGauge().GetValue(), value)
}
if !maps.Equal(metricLabels(metric), map[string]string{"name": "Cluster Network 1"}) {
if !maps.Equal(metricLabels(metric), map[string]string{"network": "Cluster Network 1"}) {
t.Fatalf("labels = %v", metricLabels(metric))
}
}
+14 -14
View File
@@ -94,85 +94,85 @@ func (c *Collector) buildNodeDescriptors() {
c.nodeBuildNumber = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "build_number"),
"Provides access to the node's BuildNumber property.",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeCharacteristics = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "characteristics"),
"Provides access to the characteristics set for the node.",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeDetectedCloudPlatform = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "detected_cloud_platform"),
"(DetectedCloudPlatform)",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeDynamicWeight = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "dynamic_weight"),
"The dynamic vote weight of the node adjusted by dynamic quorum feature.",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeFlags = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "flags"),
"Provides access to the flags set for the node.",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeMajorVersion = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "major_version"),
"Provides access to the node's MajorVersion property, which specifies the major portion of the Windows version installed.",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeMinorVersion = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "minor_version"),
"Provides access to the node's MinorVersion property, which specifies the minor portion of the Windows version installed.",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeNeedsPreventQuorum = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "needs_prevent_quorum"),
"Whether the cluster service on that node should be started with prevent quorum flag.",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeNodeDrainStatus = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "node_drain_status"),
"The current node drain status of a node. 0: Not Initiated; 1: In Progress; 2: Completed; 3: Failed",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeNodeHighestVersion = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "node_highest_version"),
"Provides access to the node's NodeHighestVersion property, which specifies the highest possible version of the cluster service with which the node can join or communicate.",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeNodeLowestVersion = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "node_lowest_version"),
"Provides access to the node's NodeLowestVersion property, which specifies the lowest possible version of the cluster service with which the node can join or communicate.",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeNodeWeight = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "node_weight"),
"The vote weight of the node.",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeState = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "state"),
"Returns the current state of a node. -1: Unknown; 0: Up; 1: Down; 2: Paused; 3: Joining",
[]string{"name"},
[]string{"node"},
nil,
)
c.nodeStatusInformation = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameNode, "status_information"),
"The isolation or quarantine status of the node.",
[]string{"name"},
[]string{"node"},
nil,
)
}
@@ -87,7 +87,7 @@ func TestNodeNativeMetricContract(t *testing.T) {
t.Errorf("%s value = %v, want %v", suffix, metric.GetGauge().GetValue(), value)
}
if !maps.Equal(metricLabels(metric), map[string]string{"name": "nodeA"}) {
if !maps.Equal(metricLabels(metric), map[string]string{"node": "nodeA"}) {
t.Fatalf("labels = %v", metricLabels(metric))
}
}
@@ -178,7 +178,7 @@ func TestNodeNamesFeedOwnerMetrics(t *testing.T) {
for _, metric := range owners.GetMetric() {
want := 0.0
if metricLabels(metric)["node_name"] == "nodeB" {
if metricLabels(metric)["node"] == "nodeB" {
want = 1
}
@@ -106,109 +106,109 @@ func (c *Collector) buildResourceDescriptors() {
c.resourceCharacteristics = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "characteristics"),
"Provides the characteristics of the object.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceDeadlockTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "deadlock_timeout_seconds"),
"Indicates the length of time to wait, in seconds, before declaring a deadlock in any call into a resource.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceEmbeddedFailureAction = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "embedded_failure_action"),
"The time, in milliseconds, that a resource should remain in a failed state before the Cluster service attempts to restart it.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceFlags = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "flags"),
"Provides access to the flags set for the object.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceIsAlivePollInterval = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "is_alive_poll_interval_seconds"),
"Provides access to the resource's IsAlivePollInterval property, which is the recommended interval in seconds at which the Cluster Service should poll the resource to determine whether it is operational. The series is omitted while the resource uses the interval of its resource type (0xFFFFFFFF).",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceLooksAlivePollInterval = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "looks_alive_poll_interval_seconds"),
"Provides access to the resource's LooksAlivePollInterval property, which is the recommended interval in seconds at which the Cluster Service should poll the resource to determine whether it appears operational. The series is omitted while the resource uses the interval of its resource type (0xFFFFFFFF).",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceMonitorProcessId = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "monitor_process_id"),
"Provides the process ID of the resource host service that is currently hosting the resource.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceOwnerNode = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "owner_node"),
"The node hosting the resource. 0: Not hosted; 1: Hosted",
[]string{"type", "owner_group", "node_name", "name"},
[]string{"type", "resource_group", "node", "resource"},
nil,
)
c.resourceOwnerNode = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "owner_node"),
"The node hosting the resource. 0: Not hosted; 1: Hosted",
[]string{"type", "owner_group", "node_name", "name"},
[]string{"type", "resource_group", "node", "resource"},
nil,
)
c.resourcePendingTimeout = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "pending_timeout_seconds"),
"Provides access to the resource's PendingTimeout property. If a resource cannot be brought online or taken offline in the number of seconds specified by the PendingTimeout property, the resource is forcibly terminated.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceResourceClass = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "resource_class"),
"Gets or sets the resource class of a resource. 0: Unknown; 1: Storage; 2: Network; 32768: Unknown ",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceRestartAction = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "restart_action"),
"Provides access to the resource's RestartAction property, which is the action to be taken by the Cluster Service if the resource fails.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceRestartDelay = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "restart_delay_seconds"),
"Indicates the time delay in seconds before a failed resource is restarted.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceRestartPeriod = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "restart_period_seconds"),
"Provides access to the resource's RestartPeriod property, which is interval of time, in seconds, during which a specified number of restart attempts can be made on a nonresponsive resource.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceRestartThreshold = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "restart_threshold"),
"Provides access to the resource's RestartThreshold property which is the maximum number of restart attempts that can be made on a resource within an interval defined by the RestartPeriod property before the Cluster Service initiates the action specified by the RestartAction property.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceRetryPeriodOnFailure = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "retry_period_on_failure_seconds"),
"Provides access to the resource's RetryPeriodOnFailure property, which is the interval of time (in seconds) that a resource should remain in a failed state before the Cluster service attempts to restart it.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceState = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "state"),
"The current state of the resource. -1: Unknown; 0: Inherited; 1: Initializing; 2: Online; 3: Offline; 4: Failed; 128: Pending; 129: Online Pending; 130: Offline Pending ",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
c.resourceSubClass = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResource, "subclass"),
"Provides the list of references to nodes that can be the owner of this resource.",
[]string{"type", "owner_group", "name"},
[]string{"type", "resource_group", "resource"},
nil,
)
}
@@ -158,7 +158,7 @@ func TestResourceNativeMetricContract(t *testing.T) {
t.Errorf("%s value = %v, want %v", suffix, metric.GetGauge().GetValue(), value)
}
if !maps.Equal(metricLabels(metric), map[string]string{"type": "Physical Disk", "owner_group": "Cluster Group", "name": "Disk"}) {
if !maps.Equal(metricLabels(metric), map[string]string{"type": "Physical Disk", "resource_group": "Cluster Group", "resource": "Disk"}) {
t.Fatalf("labels = %v", metricLabels(metric))
}
}
@@ -172,7 +172,7 @@ func TestResourceNativeMetricContract(t *testing.T) {
labels := metricLabels(metric)
value := 0.0
if labels["node_name"] == "nodeB" {
if labels["node"] == "nodeB" {
value = 1
}
@@ -180,7 +180,7 @@ func TestResourceNativeMetricContract(t *testing.T) {
t.Fatal("invalid owner value")
}
if !maps.Equal(labels, map[string]string{"type": "Physical Disk", "owner_group": "Cluster Group", "name": "Disk", "node_name": labels["node_name"]}) {
if !maps.Equal(labels, map[string]string{"type": "Physical Disk", "resource_group": "Cluster Group", "resource": "Disk", "node": labels["node"]}) {
t.Fatal("invalid owner labels")
}
}
@@ -206,7 +206,7 @@ func TestResourcePartialResultsAndJoinedErrors(t *testing.T) {
for _, family := range families {
for _, metric := range family.GetMetric() {
if metricLabels(metric)["name"] != "Disk" {
if metricLabels(metric)["resource"] != "Disk" {
t.Fatal("published invalid identity")
}
}
@@ -372,7 +372,7 @@ func TestResourceMetricCache(t *testing.T) {
}
for _, metric := range families["windows_mscluster_resource_owner_node"].GetMetric() {
if hosted := metricLabels(metric)["node_name"] == "nodeC"; (metric.GetGauge().GetValue() == 1) != hosted {
if hosted := metricLabels(metric)["node"] == "nodeC"; (metric.GetGauge().GetValue() == 1) != hosted {
t.Fatal("reused the owner node of a changed resource")
}
}
@@ -94,85 +94,85 @@ func (c *Collector) buildResourceGroupDescriptors() {
c.resourceGroupAutoFailbackType = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "auto_failback_type"),
"Provides access to the group's AutoFailbackType property.",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupCharacteristics = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "characteristics"),
"Provides the characteristics of the group.",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupColdStartSetting = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "cold_start_setting"),
"Indicates whether a group can start after a cluster cold start.",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupDefaultOwner = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "default_owner"),
"Number of the last node the resource group was activated on or explicitly moved to.",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupFailbackWindowEnd = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "failback_window_end"),
"The FailbackWindowEnd property provides the latest time that the group can be moved back to the node identified as its preferred node.",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupFailbackWindowStart = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "failback_window_start"),
"The FailbackWindowStart property provides the earliest time (that is, local time as kept by the cluster) that the group can be moved back to the node identified as its preferred node.",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupFailOverPeriod = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "failover_period_seconds"),
"The FailoverPeriod property specifies a number of seconds during which a maximum number of failover attempts, specified by the FailoverThreshold property, can occur. Windows stores it in hours.",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupFailOverThreshold = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "failover_threshold"),
"The FailoverThreshold property specifies the maximum number of failover attempts.",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupFlags = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "flags"),
"Provides access to the flags set for the group. ",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupGroupType = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "group_type"),
"The Type of the resource group.",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupOwnerNode = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "owner_node"),
"The node hosting the resource group. 0: Not hosted; 1: Hosted",
[]string{"node_name", "name"},
[]string{"node", "resource_group"},
nil,
)
c.resourceGroupPriority = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "priority"),
"Priority value of the resource group",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupResiliencyPeriod = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "resiliency_period_seconds"),
"The resiliency period for this group, in seconds.",
[]string{"name"},
[]string{"resource_group"},
nil,
)
c.resourceGroupState = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameResourceGroup, "state"),
"The current state of the resource group. -1: Unknown; 0: Online; 1: Offline; 2: Failed; 3: Partial Online; 4: Pending",
[]string{"name"},
[]string{"resource_group"},
nil,
)
}
@@ -153,7 +153,7 @@ func TestResourceGroupNativeMetricContract(t *testing.T) {
t.Errorf("%s value = %v, want %v", suffix, metric.GetGauge().GetValue(), value)
}
if !maps.Equal(metricLabels(metric), map[string]string{"name": "Cluster Group"}) {
if !maps.Equal(metricLabels(metric), map[string]string{"resource_group": "Cluster Group"}) {
t.Fatalf("labels = %v", metricLabels(metric))
}
}
@@ -167,7 +167,7 @@ func TestResourceGroupNativeMetricContract(t *testing.T) {
labels := metricLabels(metric)
value := 0.0
if labels["node_name"] == "nodeB" {
if labels["node"] == "nodeB" {
value = 1
}
@@ -175,7 +175,7 @@ func TestResourceGroupNativeMetricContract(t *testing.T) {
t.Fatal("invalid owner value")
}
if !maps.Equal(labels, map[string]string{"name": "Cluster Group", "node_name": labels["node_name"]}) {
if !maps.Equal(labels, map[string]string{"resource_group": "Cluster Group", "node": labels["node"]}) {
t.Fatalf("invalid owner labels: %v", labels)
}
}
@@ -206,7 +206,7 @@ func TestResourceGroupPartialResultsAndJoinedErrors(t *testing.T) {
for _, family := range families {
for _, metric := range family.GetMetric() {
if metricLabels(metric)["name"] != "Cluster Group" {
if metricLabels(metric)["resource_group"] != "Cluster Group" {
t.Fatal("published invalid identity")
}
}
@@ -71,21 +71,21 @@ func (c *Collector) buildSharedVolumesDescriptors() {
c.sharedVolumesInfo = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameSharedVolumes, "info"),
"Cluster Shared Volumes information (value is always 1)",
[]string{"name", "path", "volume_guid"},
[]string{"shared_volume", "path", "volume_guid"},
nil,
)
c.sharedVolumesTotalSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameSharedVolumes, "total_bytes"),
"Total size of the Cluster Shared Volume in bytes",
[]string{"name", "volume_guid"},
[]string{"shared_volume", "volume_guid"},
nil,
)
c.sharedVolumesFreeSpace = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameSharedVolumes, "free_bytes"),
"Free space on the Cluster Shared Volume in bytes",
[]string{"name", "volume_guid"},
[]string{"shared_volume", "volume_guid"},
nil,
)
}
@@ -86,7 +86,7 @@ func TestSharedVolumesNativeMetricContract(t *testing.T) {
t.Fatalf("families = %d", len(families))
}
labels := map[string]string{"name": "ClusterPerformanceHistory", "volume_guid": "d3dbada3-448f-4c4c-be4d-122b7f296007"}
labels := map[string]string{"shared_volume": "ClusterPerformanceHistory", "volume_guid": "d3dbada3-448f-4c4c-be4d-122b7f296007"}
for name, want := range map[string]float64{"total_bytes": 21474836480, "free_bytes": 1.9008585728e+10} {
family := families["windows_mscluster_shared_volumes_"+name]
@@ -105,7 +105,7 @@ func TestSharedVolumesNativeMetricContract(t *testing.T) {
}
info := families["windows_mscluster_shared_volumes_info"].GetMetric()[0]
if info.GetGauge().GetValue() != 1 || !maps.Equal(metricLabels(info), map[string]string{"name": "ClusterPerformanceHistory", "path": `C:\ClusterStorage\Volume1`, "volume_guid": "d3dbada3-448f-4c4c-be4d-122b7f296007"}) {
if info.GetGauge().GetValue() != 1 || !maps.Equal(metricLabels(info), map[string]string{"shared_volume": "ClusterPerformanceHistory", "path": `C:\ClusterStorage\Volume1`, "volume_guid": "d3dbada3-448f-4c4c-be4d-122b7f296007"}) {
t.Fatalf("info = %v", metricLabels(info))
}
}
@@ -39,7 +39,7 @@ func TestCollector(t *testing.T) {
"CI Offline IP Address": 3, // Offline
"CI Failed Service": 4, // Failed
} {
metric := testutils.RequireFixtureMetric(t, metrics, mscluster.Name, "windows_mscluster_resource_state", prometheus.Labels{"name": name})
metric := testutils.RequireFixtureMetric(t, metrics, mscluster.Name, "windows_mscluster_resource_state", prometheus.Labels{"resource": name})
if metric != nil && metric.GetGauge().GetValue() != state {
t.Errorf("resource %q state = %v, want %v", name, metric.GetGauge().GetValue(), state)
}
+1 -1
View File
@@ -12,7 +12,7 @@ installed. It is multi-instance. These notes were recorded on Windows Server
`<computer>\private$\<queue>` in lower case. A fresh install already has the
internal queues `server2025\private$\admin_queue$` and
`server2025\private$\order_queue$`. The collector uses the instance name
unchanged as the `name` label.
unchanged as the `queue` label.
- For `Computer Queues`, `Messages/Bytes in Queue` is the dead-letter queue
and `Messages/Bytes in Journal Queue` is the computer journal.
- All values were 0 on the recording host.
+4 -4
View File
@@ -82,25 +82,25 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
c.bytesInJournalQueue = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "journal_queue_bytes"),
"Size of queue journal in bytes",
[]string{"name"},
[]string{"queue"},
nil,
)
c.bytesInQueue = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "queue_bytes"),
"Size of queue in bytes",
[]string{"name"},
[]string{"queue"},
nil,
)
c.messagesInJournalQueue = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "messages_in_journal_queue"),
"Count messages in queue journal",
[]string{"name"},
[]string{"queue"},
nil,
)
c.messagesInQueue = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "messages_in_queue"),
"Count messages in queue",
[]string{"name"},
[]string{"queue"},
nil,
)
@@ -207,7 +207,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
}
if object.InstanceLabel == "" {
object.InstanceLabel = "instance"
object.InstanceLabel = "object_instance"
}
object.collector = collector
@@ -93,7 +93,7 @@ windows_performancecounter_collector_duration_seconds\{collector="process"} [0-9
windows_performancecounter_collector_success\{collector="process"} 1
# HELP windows_performancecounter_process_thread_count windows_exporter: custom Performance Counter metric
# TYPE windows_performancecounter_process_thread_count counter
windows_performancecounter_process_thread_count\{instance=".+"} [0-9.e+-]+
windows_performancecounter_process_thread_count\{object_instance=".+"} [0-9.e+-]+
.*`),
},
{
@@ -373,7 +373,7 @@ func TestCollectorDuplicateInstances(t *testing.T) {
for _, metric := range family.GetMetric() {
for _, label := range metric.GetLabel() {
if label.GetName() == "instance" {
if label.GetName() == "object_instance" {
instances[label.GetValue()] = true
}
}
+1 -1
View File
@@ -125,7 +125,7 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
c.keySuccessDesc = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "key_success"),
"Whether the registry key could be read successfully.",
[]string{"name"},
[]string{"key"},
nil,
)
@@ -132,8 +132,8 @@ func TestCollectorMetrics(t *testing.T) {
// precedes "testgroup" (1).
expected := `# HELP windows_registry_key_success Whether the registry key could be read successfully.
# TYPE windows_registry_key_success gauge
windows_registry_key_success{name="missing_group"} 0
windows_registry_key_success{name="testgroup"} 1
windows_registry_key_success{key="missing_group"} 0
windows_registry_key_success{key="testgroup"} 1
# HELP windows_registry_test_custom_metric custom registry help text
# TYPE windows_registry_test_custom_metric counter
windows_registry_test_custom_metric{foo="bar"} 5e+09
+4 -4
View File
@@ -196,25 +196,25 @@ func (c *Collector) Build(logger *slog.Logger, _ *mi.Session) error {
c.info = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "info"),
"A metric with a constant '1' value labeled with service information",
[]string{"name", "display_name", "run_as", "path_name"},
[]string{"service", "display_name", "run_as", "path_name"},
nil,
)
c.state = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "state"),
"The state of the service (State)",
[]string{"name", "state"},
[]string{"service", "state"},
nil,
)
c.startMode = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "start_mode"),
"The start mode of the service (StartMode)",
[]string{"name", "start_mode"},
[]string{"service", "start_mode"},
nil,
)
c.processID = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "process"),
"Process of started service. The value is the creation time of the process as a unix timestamp.",
[]string{"name", "process_id"},
[]string{"service", "process_id"},
nil,
)
@@ -80,7 +80,7 @@ func serviceMetrics(t assert.TestingT, c *Collector, name string) map[string]flo
)
for _, label := range metric.GetLabel() {
if label.GetName() == "name" {
if label.GetName() == "service" {
matches = label.GetValue() == name
continue
@@ -66,42 +66,42 @@ func (c *Collector) buildStoragePool() error {
c.storagePoolInfo = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameStoragePool, "info"),
"Storage pool information (value is always 1). primordial is true for the built-in primordial pool",
[]string{"name", "unique_id", "primordial"},
[]string{"pool", "unique_id", "primordial"},
nil,
)
c.storagePoolHealthStatus = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameStoragePool, "health_status"),
"Health status of the storage pool. 0: Healthy, 1: Warning, 2: Unhealthy, 5: Unknown",
[]string{"name", "unique_id"},
[]string{"pool", "unique_id"},
nil,
)
c.storagePoolSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameStoragePool, "size_bytes"),
"Total size of the storage pool in bytes",
[]string{"name", "unique_id"},
[]string{"pool", "unique_id"},
nil,
)
c.storagePoolAllocatedSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameStoragePool, "allocated_size_bytes"),
"Allocated size of the storage pool in bytes",
[]string{"name", "unique_id"},
[]string{"pool", "unique_id"},
nil,
)
c.storagePoolOperationalStatus = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameStoragePool, "operational_status"),
"Operational status codes reported for the storage pool (one series per status value)",
[]string{"name", "unique_id", "status"},
[]string{"pool", "unique_id", "status"},
nil,
)
c.storagePoolThinProvisioningAlertThresholds = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameStoragePool, "thin_provisioning_alert_thresholds"),
"Thin provisioning alert thresholds configured for the storage pool, in percent (one series per configured threshold)",
[]string{"name", "unique_id", "threshold"},
[]string{"pool", "unique_id", "threshold"},
nil,
)
@@ -33,10 +33,10 @@ func BenchmarkCollector(b *testing.B) {
func TestCollector(t *testing.T) {
metrics := testutils.TestCollector(t, storage_spaces.New, nil)
pool := prometheus.Labels{"name": "GitHubActions"}
virtualDisk := prometheus.Labels{"name": "CIVirtualDisk"}
pool := prometheus.Labels{"pool": "GitHubActions"}
virtualDisk := prometheus.Labels{"virtual_disk": "CIVirtualDisk"}
testutils.RequireFixtureMetric(t, metrics, storage_spaces.Name, "windows_storage_spaces_pool_info", prometheus.Labels{"name": "GitHubActions", "primordial": "false"})
testutils.RequireFixtureMetric(t, metrics, storage_spaces.Name, "windows_storage_spaces_pool_info", prometheus.Labels{"pool": "GitHubActions", "primordial": "false"})
testutils.RequireFixtureMetric(t, metrics, storage_spaces.Name, "windows_storage_spaces_virtual_disk_info", virtualDisk)
for _, tc := range []struct {
@@ -63,42 +63,42 @@ func (c *Collector) buildVirtualDisk() error {
c.virtualDiskInfo = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameVirtualDisk, "info"),
"Virtual disk information (value is always 1)",
[]string{"name", "unique_id"},
[]string{"virtual_disk", "unique_id"},
nil,
)
c.virtualDiskHealthStatus = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameVirtualDisk, "health_status"),
"Health status of the virtual disk. 0: Healthy, 1: Warning, 2: Unhealthy, 5: Unknown",
[]string{"name", "unique_id"},
[]string{"virtual_disk", "unique_id"},
nil,
)
c.virtualDiskSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameVirtualDisk, "size_bytes"),
"Total size of the virtual disk in bytes",
[]string{"name", "unique_id"},
[]string{"virtual_disk", "unique_id"},
nil,
)
c.virtualDiskAllocatedSize = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameVirtualDisk, "allocated_size_bytes"),
"Allocated size of the virtual disk in bytes (capacity actually provisioned, excludes thin-provisioned unused capacity)",
[]string{"name", "unique_id"},
[]string{"virtual_disk", "unique_id"},
nil,
)
c.virtualDiskFootprintOnPool = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameVirtualDisk, "footprint_on_pool_bytes"),
"Physical storage consumed by the virtual disk on the storage pool in bytes",
[]string{"name", "unique_id"},
[]string{"virtual_disk", "unique_id"},
nil,
)
c.virtualDiskStorageEfficiency = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, nameVirtualDisk, "storage_efficiency_ratio"),
"Storage efficiency ratio (AllocatedSize / FootprintOnPool), omitted while FootprintOnPool is 0",
[]string{"name", "unique_id"},
[]string{"virtual_disk", "unique_id"},
nil,
)
+2 -2
View File
@@ -163,13 +163,13 @@ func (c *Collector) Build(logger *slog.Logger, miSession *mi.Session) error {
c.querySuccessDesc = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "query_success"),
"Whether the WMI query and all of its configured properties could be read successfully.",
[]string{"name"},
[]string{"query"},
nil,
)
c.queryDurationDesc = prometheus.NewDesc(
prometheus.BuildFQName(types.Namespace, Name, "query_duration_seconds"),
"Duration of the WMI query.",
[]string{"name"},
[]string{"query"},
nil,
)
+10 -10
View File
@@ -201,13 +201,13 @@ windows_wmi_os_primary 1
windows_wmi_partial_primary 1
# HELP windows_wmi_query_success Whether the WMI query and all of its configured properties could be read successfully.
# TYPE windows_wmi_query_success gauge
windows_wmi_query_success{name="kernel"} 1
windows_wmi_query_success{name="missing_class"} 0
windows_wmi_query_success{name="os"} 1
windows_wmi_query_success{name="partial"} 0
windows_wmi_query_success{name="shared_a"} 1
windows_wmi_query_success{name="shared_b"} 1
windows_wmi_query_success{name="unsupported_label"} 0
windows_wmi_query_success{query="kernel"} 1
windows_wmi_query_success{query="missing_class"} 0
windows_wmi_query_success{query="os"} 1
windows_wmi_query_success{query="partial"} 0
windows_wmi_query_success{query="shared_a"} 1
windows_wmi_query_success{query="shared_b"} 1
windows_wmi_query_success{query="unsupported_label"} 0
# HELP windows_wmi_test_parent_pid custom wmi help text
# TYPE windows_wmi_test_parent_pid counter
windows_wmi_test_parent_pid{foo="bar",handle="0",path="",pid="0",process="System Idle Process"} 0
@@ -233,7 +233,7 @@ windows_wmi_test_shared{query="b"} 1
require.Equal(t, expected, strings.Join(lines, "\n"))
for _, name := range []string{"kernel", "missing_class", "os", "partial", "shared_a", "shared_b", "unsupported_label"} {
require.Regexp(t, `(?m)^windows_wmi_query_duration_seconds\{name="`+name+`"\} \d`, got)
require.Regexp(t, `(?m)^windows_wmi_query_duration_seconds\{query="`+name+`"\} \d`, got)
}
}
}
@@ -302,8 +302,8 @@ func TestCollectScrapeTimeout(t *testing.T) {
got := scrapeWithTimeout(t, c, time.Nanosecond)
require.Contains(t, got, `windows_wmi_query_success{name="a"} 0`)
require.Contains(t, got, `windows_wmi_query_success{name="b"} 0`)
require.Contains(t, got, `windows_wmi_query_success{query="a"} 0`)
require.Contains(t, got, `windows_wmi_query_success{query="b"} 0`)
require.NotContains(t, got, "windows_wmi_a_primary")
require.NotContains(t, got, "windows_wmi_b_primary")
@@ -0,0 +1,325 @@
// 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.
package metriccontract_test
import (
"fmt"
"os"
"path/filepath"
"regexp"
"slices"
"strings"
"testing"
"github.com/stretchr/testify/require"
)
// compatibilityRulesFile holds recording rules that publish the metrics of
// 0.32 under their 0.31 names and labels. It is generated from the rename
// tables of UPGRADE.md; set UPDATE_COMPATIBILITY_RULES=1 to regenerate it.
const compatibilityRulesFile = "docs/example-0.32-compatibility-rules-new-to-old.yml"
// renameRow matches a row of a rename table in UPGRADE.md: the 0.31 name, the
// 0.32 name and a note.
var renameRow = regexp.MustCompile("^\\|\\s*`(windows_[A-Za-z0-9_]+)`\\s*\\|\\s*`(windows_[A-Za-z0-9_]+)`\\s*\\|\\s*(.*?)\\s*\\|\\s*$")
// labelRow matches a row of the instance label table in UPGRADE.md.
var labelRow = regexp.MustCompile("^\\|\\s*`([a-z_]+)`\\s*\\|([^|]*)\\|([^|]*)\\|([^|]*)\\|\\s*$")
var backticked = regexp.MustCompile("`([^`]+)`")
// conversion turns the value of a 0.32 metric back into its 0.31 value.
type conversion struct {
// match is a lowercase part of the note of a rename.
match string
// expr formats the 0.31 value of the metric %s.
expr string
}
// conversions are tried in order. The first match wins.
//
//nolint:gochecknoglobals
var conversions = []conversion{
{"seconds instead of milliseconds", "%s * 1000"},
{"now in seconds, was milliseconds", "%s * 1000"},
{"seconds instead of microseconds", "%s * 1e6"},
{"seconds instead of minutes", "%s / 60"},
{"seconds instead of hours", "%s / 3600"},
{"bytes instead of kilobytes", "%s / 1024"},
{"was kilobytes, now bytes", "%s / 1024"},
{"bytes instead of megabytes", "%s / 1048576"},
{"hertz instead of megahertz", "%s / 1e6"},
{"instead of percent", "%s * 100"},
{"instead of parts per billion", "%s * 1e9"},
{"instead of the per-minute value", "%s * 3600"},
{"same value", "%s"},
{"unit suffix added", "%s"},
{"now a counter", "%s"},
{"now a gauge", "%s"},
{"was a running count", "%s"},
}
// unconvertible are lowercase parts of notes whose 0.31 value can't be
// computed from the 0.32 metric. They are checked before conversions.
//
//nolint:gochecknoglobals
var unconvertible = []string{
"removed",
"see [",
"see below",
"0.31 divided",
"raw millisecond",
"divide its `rate()` by that",
"label `",
}
type labelRename struct {
metrics *regexp.Regexp
// prefix is the longest literal prefix of the metric names, which
// decides between overlapping rows like windows_mscluster_resource_* and
// windows_mscluster_resourcegroup_*.
prefix string
old []string
new []string
}
// labelRenameOf returns the most specific label rename of the metric name.
func labelRenameOf(renames []labelRename, name string) (labelRename, bool) {
var (
best labelRename
found bool
)
for _, rename := range renames {
if rename.metrics.MatchString(name) && (!found || len(rename.prefix) > len(best.prefix)) {
best, found = rename, true
}
}
return best, found
}
type compatibilityRule struct {
record string
expr string
}
// TestCompatibilityRules checks that the compatibility recording rules are
// generated from the current UPGRADE.md, read only metrics the exporter
// emits and record no name it emits itself.
func TestCompatibilityRules(t *testing.T) {
t.Parallel()
upgrade, err := os.ReadFile(filepath.Join(repoRoot, "UPGRADE.md"))
require.NoError(t, err)
rules := compatibilityRules(t, strings.Split(strings.ReplaceAll(string(upgrade), "\r\n", "\n"), "\n"))
require.NotEmpty(t, rules)
generated := formatCompatibilityRules(rules)
path := filepath.Join(repoRoot, filepath.FromSlash(compatibilityRulesFile))
if os.Getenv("UPDATE_COMPATIBILITY_RULES") != "" {
require.NoError(t, os.WriteFile(path, []byte(generated), 0o644)) //nolint:gosec // a documentation file
}
committed, err := os.ReadFile(path)
require.NoError(t, err)
require.Equal(t, generated, strings.ReplaceAll(string(committed), "\r\n", "\n"),
"%s is out of date with UPGRADE.md. Run: UPDATE_COMPATIBILITY_RULES=1 go test ./internal/metriccontract/", compatibilityRulesFile)
emitted := emittedMetricPatterns(t)
matcher := regexp.MustCompile("^(?:" + strings.Join(emitted, "|") + ")$")
for _, rules := range rules {
for _, rule := range rules {
source := referencePattern.FindStringSubmatch(rule.expr)
require.NotNil(t, source, rule.expr)
require.True(t, matcher.MatchString(source[1]), "%s reads %s, which the exporter does not emit", rule.record, source[1])
require.False(t, matcher.MatchString(rule.record), "%s is emitted by the exporter, a recording rule would duplicate it", rule.record)
}
}
}
// compatibilityRules returns the rules by collector.
func compatibilityRules(t *testing.T, upgrade []string) map[string][]compatibilityRule {
t.Helper()
labels := labelRenames(t, upgrade)
rules := map[string][]compatibilityRule{}
seen := map[string]bool{}
for _, line := range upgrade {
m := renameRow.FindStringSubmatch(line)
if m == nil {
continue
}
oldName, newName, note := m[1], m[2], strings.ToLower(m[3])
if seen[oldName] || slices.ContainsFunc(unconvertible, func(s string) bool { return strings.Contains(note, s) }) {
continue
}
i := slices.IndexFunc(conversions, func(c conversion) bool { return strings.Contains(note, c.match) })
if i < 0 {
t.Logf("%s: no conversion for the note %q, left out", oldName, m[3])
continue
}
seen[oldName] = true
expr := fmt.Sprintf(conversions[i].expr, newName)
var dropped []string
if rename, ok := labelRenameOf(labels, newName); ok {
for j, oldLabel := range rename.old {
expr = fmt.Sprintf(`label_replace(%s, "%s", "$1", "%s", "(.+)")`, expr, oldLabel, rename.new[j])
dropped = append(dropped, rename.new[j])
}
}
if len(dropped) > 0 {
expr = fmt.Sprintf("max without (%s) (%s)", strings.Join(dropped, ", "), expr)
}
collector := collectorOf(t, newName)
rules[collector] = append(rules[collector], compatibilityRule{record: oldName, expr: expr})
}
return rules
}
// labelRenames returns the instance label renames of UPGRADE.md. A label
// named instance in 0.31 is restored as exported_instance, the name under
// which Prometheus stored it next to the target label.
func labelRenames(t *testing.T, upgrade []string) []labelRename {
t.Helper()
var renames []labelRename
for _, line := range upgrade {
m := labelRow.FindStringSubmatch(line)
if m == nil {
continue
}
var (
patterns []string
prefix string
)
for _, metric := range backticked.FindAllStringSubmatch(m[2], -1) {
if strings.HasPrefix(metric[1], "windows_") {
patterns = append(patterns, strings.ReplaceAll(regexp.QuoteMeta(metric[1]), `\*`, "[a-zA-Z0-9_]*"))
prefix, _, _ = strings.Cut(metric[1], "*")
}
}
if len(patterns) == 0 {
continue
}
var oldLabels, newLabels []string
for _, label := range backticked.FindAllStringSubmatch(m[3], -1) {
name := label[1]
if name == "instance" {
name = "exported_instance"
}
oldLabels = append(oldLabels, name)
}
for _, label := range backticked.FindAllStringSubmatch(m[4], -1) {
newLabels = append(newLabels, label[1])
}
require.GreaterOrEqual(t, len(newLabels), len(oldLabels), line)
renames = append(renames, labelRename{
metrics: regexp.MustCompile("^(?:" + strings.Join(patterns, "|") + ")$"),
prefix: prefix,
old: oldLabels,
new: newLabels[:len(oldLabels)],
})
}
require.NotEmpty(t, renames, "the instance label table of UPGRADE.md was not found")
return renames
}
func formatCompatibilityRules(rules map[string][]compatibilityRule) string {
var b strings.Builder
b.WriteString(`# Recording rules that publish the metrics of windows_exporter 0.32 under
# their 0.31 names, units and instance labels, for dashboards and alerts that
# have not been migrated yet. Load them into Prometheus next to the scrape of
# the new exporter and remove them once the queries use the new names.
#
# Generated from UPGRADE.md by internal/metriccontract; do not edit.
#
# Not covered:
# - Metrics that only renamed their instance label, e.g. windows_service_*.
# Recording them under the same name would duplicate every series.
# - Metrics whose 0.31 value can't be computed from 0.32, e.g. removed
# metrics, split metrics and ratios that 0.31 computed wrongly.
# - Series that 0.32 leaves out, e.g. mscluster settings that are zero.
groups:
`)
collectors := make([]string, 0, len(rules))
for collector := range rules {
collectors = append(collectors, collector)
}
slices.Sort(collectors)
for _, collector := range collectors {
fmt.Fprintf(&b, " - name: windows_exporter-0.32-%s\n rules:\n", collector)
for _, rule := range rules[collector] {
fmt.Fprintf(&b, " - record: %s\n expr: %s\n", rule.record, rule.expr)
}
}
return b.String()
}
// collectorOf returns the collector that emits the metric name: the longest
// directory name in internal/collector that prefixes the name, e.g. container
// for windows_containers.
func collectorOf(t *testing.T, name string) string {
t.Helper()
entries, err := os.ReadDir(filepath.Join(repoRoot, "internal", "collector"))
require.NoError(t, err)
var collector string
for _, entry := range entries {
if entry.IsDir() && len(entry.Name()) > len(collector) && strings.HasPrefix(name, "windows_"+entry.Name()) {
collector = entry.Name()
}
}
require.NotEmpty(t, collector, "no collector for %s", name)
return collector
}
+6
View File
@@ -220,6 +220,12 @@ func metricReferences(t *testing.T) []reference {
return filepath.SkipDir
}
// The test of the compatibility rules queries the 0.31 names they
// record; TestCompatibilityRules checks those.
if entry.Name() == "compatibility_rules.test.yaml" {
return nil
}
switch filepath.Ext(path) {
case ".jsonnet", ".libsonnet", ".yaml", ".yml":
files = append(files, path)