mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2026-02-07 21:46:37 +00:00
436 lines
15 KiB
Go
436 lines
15 KiB
Go
// Copyright 2024 The Prometheus Authors
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//go:build windows
|
|
|
|
package mssql
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/prometheus-community/windows_exporter/internal/pdh"
|
|
"github.com/prometheus-community/windows_exporter/internal/types"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
type collectorDatabaseReplica struct {
|
|
dbReplicaPerfDataCollectors map[string]*pdh.Collector
|
|
dbReplicaPerfDataObject []perfDataCounterValuesDBReplica
|
|
|
|
dbReplicaDatabaseFlowControlDelay *prometheus.Desc
|
|
dbReplicaDatabaseFlowControls *prometheus.Desc
|
|
dbReplicaFileBytesReceived *prometheus.Desc
|
|
dbReplicaGroupCommits *prometheus.Desc
|
|
dbReplicaGroupCommitTime *prometheus.Desc
|
|
dbReplicaLogApplyPendingQueue *prometheus.Desc
|
|
dbReplicaLogApplyReadyQueue *prometheus.Desc
|
|
dbReplicaLogBytesCompressed *prometheus.Desc
|
|
dbReplicaLogBytesDecompressed *prometheus.Desc
|
|
dbReplicaLogBytesReceived *prometheus.Desc
|
|
dbReplicaLogCompressionCachehits *prometheus.Desc
|
|
dbReplicaLogCompressionCachemisses *prometheus.Desc
|
|
dbReplicaLogCompressions *prometheus.Desc
|
|
dbReplicaLogDecompressions *prometheus.Desc
|
|
dbReplicaLogremainingforundo *prometheus.Desc
|
|
dbReplicaLogSendQueue *prometheus.Desc
|
|
dbReplicaMirroredWritetransactions *prometheus.Desc
|
|
dbReplicaRecoveryQueue *prometheus.Desc
|
|
dbReplicaRedoblocked *prometheus.Desc
|
|
dbReplicaRedoBytesRemaining *prometheus.Desc
|
|
dbReplicaRedoneBytes *prometheus.Desc
|
|
dbReplicaRedones *prometheus.Desc
|
|
dbReplicaTotalLogrequiringundo *prometheus.Desc
|
|
dbReplicaTransactionDelay *prometheus.Desc
|
|
}
|
|
|
|
type perfDataCounterValuesDBReplica struct {
|
|
Name string
|
|
|
|
DbReplicaDatabaseFlowControlDelay float64 `perfdata:"Database Flow Control Delay"`
|
|
DbReplicaDatabaseFlowControlsPerSec float64 `perfdata:"Database Flow Controls/sec"`
|
|
DbReplicaFileBytesReceivedPerSec float64 `perfdata:"File Bytes Received/sec"`
|
|
DbReplicaGroupCommitsPerSec float64 `perfdata:"Group Commits/Sec"`
|
|
DbReplicaGroupCommitTime float64 `perfdata:"Group Commit Time"`
|
|
DbReplicaLogApplyPendingQueue float64 `perfdata:"Log Apply Pending Queue"`
|
|
DbReplicaLogApplyReadyQueue float64 `perfdata:"Log Apply Ready Queue"`
|
|
DbReplicaLogBytesCompressedPerSec float64 `perfdata:"Log Bytes Compressed/sec"`
|
|
DbReplicaLogBytesDecompressedPerSec float64 `perfdata:"Log Bytes Decompressed/sec"`
|
|
DbReplicaLogBytesReceivedPerSec float64 `perfdata:"Log Bytes Received/sec"`
|
|
DbReplicaLogCompressionCacheHitsPerSec float64 `perfdata:"Log Compression Cache hits/sec"`
|
|
DbReplicaLogCompressionCacheMissesPerSec float64 `perfdata:"Log Compression Cache misses/sec"`
|
|
DbReplicaLogCompressionsPerSec float64 `perfdata:"Log Compressions/sec"`
|
|
DbReplicaLogDecompressionsPerSec float64 `perfdata:"Log Decompressions/sec"`
|
|
DbReplicaLogRemainingForUndo float64 `perfdata:"Log remaining for undo"`
|
|
DbReplicaLogSendQueue float64 `perfdata:"Log Send Queue"`
|
|
DbReplicaMirroredWriteTransactionsPerSec float64 `perfdata:"Mirrored Write Transactions/sec"`
|
|
DbReplicaRecoveryQueue float64 `perfdata:"Recovery Queue"`
|
|
DbReplicaRedoBlockedPerSec float64 `perfdata:"Redo blocked/sec"`
|
|
DbReplicaRedoBytesRemaining float64 `perfdata:"Redo Bytes Remaining"`
|
|
DbReplicaRedoneBytesPerSec float64 `perfdata:"Redone Bytes/sec"`
|
|
DbReplicaRedonesPerSec float64 `perfdata:"Redones/sec"`
|
|
DbReplicaTotalLogRequiringUndo float64 `perfdata:"Total Log requiring undo"`
|
|
DbReplicaTransactionDelay float64 `perfdata:"Transaction Delay"`
|
|
}
|
|
|
|
func (c *Collector) buildDatabaseReplica() error {
|
|
var err error
|
|
|
|
c.dbReplicaPerfDataCollectors = make(map[string]*pdh.Collector, len(c.mssqlInstances))
|
|
errs := make([]error, 0, len(c.mssqlInstances))
|
|
|
|
for _, sqlInstance := range c.mssqlInstances {
|
|
c.dbReplicaPerfDataCollectors[sqlInstance.name], err = pdh.NewCollector[perfDataCounterValuesDBReplica](pdh.CounterTypeRaw, c.mssqlGetPerfObjectName(sqlInstance.name, "Database Replica"), pdh.InstancesAll)
|
|
if err != nil {
|
|
errs = append(errs, fmt.Errorf("failed to create Database Replica collector for instance %s: %w", sqlInstance.name, err))
|
|
}
|
|
}
|
|
|
|
// Win32_PerfRawData_{instance}_SQLServerDatabaseReplica
|
|
c.dbReplicaDatabaseFlowControlDelay = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_database_flow_control_wait_seconds"),
|
|
"(DatabaseReplica.DatabaseFlowControlDelay)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaDatabaseFlowControls = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_database_initiated_flow_controls"),
|
|
"(DatabaseReplica.DatabaseFlowControls)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaFileBytesReceived = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_received_file_bytes"),
|
|
"(DatabaseReplica.FileBytesReceived)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaGroupCommits = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_group_commits"),
|
|
"(DatabaseReplica.GroupCommits)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaGroupCommitTime = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_group_commit_stall_seconds"),
|
|
"(DatabaseReplica.GroupCommitTime)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogApplyPendingQueue = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_apply_pending_queue"),
|
|
"(DatabaseReplica.LogApplyPendingQueue)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogApplyReadyQueue = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_apply_ready_queue"),
|
|
"(DatabaseReplica.LogApplyReadyQueue)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogBytesCompressed = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_compressed_bytes"),
|
|
"(DatabaseReplica.LogBytesCompressed)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogBytesDecompressed = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_decompressed_bytes"),
|
|
"(DatabaseReplica.LogBytesDecompressed)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogBytesReceived = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_received_bytes"),
|
|
"(DatabaseReplica.LogBytesReceived)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogCompressionCachehits = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_compression_cachehits"),
|
|
"(DatabaseReplica.LogCompressionCachehits)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogCompressionCachemisses = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_compression_cachemisses"),
|
|
"(DatabaseReplica.LogCompressionCachemisses)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogCompressions = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_compressions"),
|
|
"(DatabaseReplica.LogCompressions)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogDecompressions = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_decompressions"),
|
|
"(DatabaseReplica.LogDecompressions)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogremainingforundo = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_remaining_for_undo"),
|
|
"(DatabaseReplica.Logremainingforundo)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaLogSendQueue = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_log_send_queue"),
|
|
"(DatabaseReplica.LogSendQueue)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaMirroredWritetransactions = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_mirrored_write_transactions"),
|
|
"(DatabaseReplica.MirroredWriteTransactions)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaRecoveryQueue = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_recovery_queue_records"),
|
|
"(DatabaseReplica.RecoveryQueue)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaRedoblocked = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_redo_blocks"),
|
|
"(DatabaseReplica.Redoblocked)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaRedoBytesRemaining = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_redo_remaining_bytes"),
|
|
"(DatabaseReplica.RedoBytesRemaining)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaRedoneBytes = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_redone_bytes"),
|
|
"(DatabaseReplica.RedoneBytes)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaRedones = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_redones"),
|
|
"(DatabaseReplica.Redones)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaTotalLogrequiringundo = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_total_log_requiring_undo"),
|
|
"(DatabaseReplica.TotalLogrequiringundo)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
c.dbReplicaTransactionDelay = prometheus.NewDesc(
|
|
prometheus.BuildFQName(types.Namespace, Name, "dbreplica_transaction_delay_seconds"),
|
|
"(DatabaseReplica.TransactionDelay)",
|
|
[]string{"mssql_instance", "replica"},
|
|
nil,
|
|
)
|
|
|
|
return errors.Join(errs...)
|
|
}
|
|
|
|
func (c *Collector) collectDatabaseReplica(ch chan<- prometheus.Metric) error {
|
|
return c.collect(ch, subCollectorDatabaseReplica, c.dbReplicaPerfDataCollectors, c.collectDatabaseReplicaInstance)
|
|
}
|
|
|
|
func (c *Collector) collectDatabaseReplicaInstance(ch chan<- prometheus.Metric, sqlInstance string, perfDataCollector *pdh.Collector) error {
|
|
err := perfDataCollector.Collect(&c.dbReplicaPerfDataObject)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to collect %s metrics: %w", c.mssqlGetPerfObjectName(sqlInstance, "Database Replica"), err)
|
|
}
|
|
|
|
for _, data := range c.dbReplicaPerfDataObject {
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaDatabaseFlowControlDelay,
|
|
prometheus.GaugeValue,
|
|
data.DbReplicaDatabaseFlowControlDelay,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaDatabaseFlowControls,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaDatabaseFlowControlsPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaFileBytesReceived,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaFileBytesReceivedPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaGroupCommits,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaGroupCommitsPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaGroupCommitTime,
|
|
prometheus.GaugeValue,
|
|
data.DbReplicaGroupCommitTime,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogApplyPendingQueue,
|
|
prometheus.GaugeValue,
|
|
data.DbReplicaLogApplyPendingQueue,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogApplyReadyQueue,
|
|
prometheus.GaugeValue,
|
|
data.DbReplicaLogApplyReadyQueue,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogBytesCompressed,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaLogBytesCompressedPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogBytesDecompressed,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaLogBytesDecompressedPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogBytesReceived,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaLogBytesReceivedPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogCompressionCachehits,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaLogCompressionCacheHitsPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogCompressionCachemisses,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaLogCompressionCacheMissesPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogCompressions,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaLogCompressionsPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogDecompressions,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaLogDecompressionsPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogremainingforundo,
|
|
prometheus.GaugeValue,
|
|
data.DbReplicaLogRemainingForUndo,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogSendQueue,
|
|
prometheus.GaugeValue,
|
|
data.DbReplicaLogSendQueue,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaMirroredWritetransactions,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaMirroredWriteTransactionsPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaRecoveryQueue,
|
|
prometheus.GaugeValue,
|
|
data.DbReplicaRecoveryQueue,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaRedoblocked,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaRedoBlockedPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaRedoBytesRemaining,
|
|
prometheus.GaugeValue,
|
|
data.DbReplicaRedoBytesRemaining,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaRedoneBytes,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaRedoneBytesPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaRedones,
|
|
prometheus.CounterValue,
|
|
data.DbReplicaRedonesPerSec,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaTotalLogrequiringundo,
|
|
prometheus.GaugeValue,
|
|
data.DbReplicaTotalLogRequiringUndo,
|
|
sqlInstance, data.Name,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaTransactionDelay,
|
|
prometheus.GaugeValue,
|
|
data.DbReplicaTransactionDelay/1000.0,
|
|
sqlInstance, data.Name,
|
|
)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Collector) closeDatabaseReplica() {
|
|
for _, collector := range c.dbReplicaPerfDataCollectors {
|
|
collector.Close()
|
|
}
|
|
}
|