mirror of
https://github.com/prometheus-community/windows_exporter.git
synced 2025-04-18 19:24:05 +03:00
444 lines
15 KiB
Go
444 lines
15 KiB
Go
//go:build windows
|
|
|
|
package mssql
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/prometheus-community/windows_exporter/internal/perfdata"
|
|
"github.com/prometheus-community/windows_exporter/internal/types"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
)
|
|
|
|
type collectorDatabaseReplica struct {
|
|
dbReplicaPerfDataCollectors map[string]*perfdata.Collector
|
|
|
|
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
|
|
}
|
|
|
|
const (
|
|
dbReplicaDatabaseFlowControlDelay = "Database Flow Control Delay"
|
|
dbReplicaDatabaseFlowControlsPerSec = "Database Flow Controls/sec"
|
|
dbReplicaFileBytesReceivedPerSec = "File Bytes Received/sec"
|
|
dbReplicaGroupCommitsPerSec = "Group Commits/Sec"
|
|
dbReplicaGroupCommitTime = "Group Commit Time"
|
|
dbReplicaLogApplyPendingQueue = "Log Apply Pending Queue"
|
|
dbReplicaLogApplyReadyQueue = "Log Apply Ready Queue"
|
|
dbReplicaLogBytesCompressedPerSec = "Log Bytes Compressed/sec"
|
|
dbReplicaLogBytesDecompressedPerSec = "Log Bytes Decompressed/sec"
|
|
dbReplicaLogBytesReceivedPerSec = "Log Bytes Received/sec"
|
|
dbReplicaLogCompressionCacheHitsPerSec = "Log Compression Cache hits/sec"
|
|
dbReplicaLogCompressionCacheMissesPerSec = "Log Compression Cache misses/sec"
|
|
dbReplicaLogCompressionsPerSec = "Log Compressions/sec"
|
|
dbReplicaLogDecompressionsPerSec = "Log Decompressions/sec"
|
|
dbReplicaLogRemainingForUndo = "Log remaining for undo"
|
|
dbReplicaLogSendQueue = "Log Send Queue"
|
|
dbReplicaMirroredWriteTransactionsPerSec = "Mirrored Write Transactions/sec"
|
|
dbReplicaRecoveryQueue = "Recovery Queue"
|
|
dbReplicaRedoBlockedPerSec = "Redo blocked/sec"
|
|
dbReplicaRedoBytesRemaining = "Redo Bytes Remaining"
|
|
dbReplicaRedoneBytesPerSec = "Redone Bytes/sec"
|
|
dbReplicaRedonesPerSec = "Redones/sec"
|
|
dbReplicaTotalLogRequiringUndo = "Total Log requiring undo"
|
|
dbReplicaTransactionDelay = "Transaction Delay"
|
|
)
|
|
|
|
func (c *Collector) buildDatabaseReplica() error {
|
|
var err error
|
|
|
|
c.dbReplicaPerfDataCollectors = make(map[string]*perfdata.Collector, len(c.mssqlInstances))
|
|
counters := []string{
|
|
dbReplicaDatabaseFlowControlDelay,
|
|
dbReplicaDatabaseFlowControlsPerSec,
|
|
dbReplicaFileBytesReceivedPerSec,
|
|
dbReplicaGroupCommitsPerSec,
|
|
dbReplicaGroupCommitTime,
|
|
dbReplicaLogApplyPendingQueue,
|
|
dbReplicaLogApplyReadyQueue,
|
|
dbReplicaLogBytesCompressedPerSec,
|
|
dbReplicaLogBytesDecompressedPerSec,
|
|
dbReplicaLogBytesReceivedPerSec,
|
|
dbReplicaLogCompressionCacheHitsPerSec,
|
|
dbReplicaLogCompressionCacheMissesPerSec,
|
|
dbReplicaLogCompressionsPerSec,
|
|
dbReplicaLogDecompressionsPerSec,
|
|
dbReplicaLogRemainingForUndo,
|
|
dbReplicaLogSendQueue,
|
|
dbReplicaMirroredWriteTransactionsPerSec,
|
|
dbReplicaRecoveryQueue,
|
|
dbReplicaRedoBlockedPerSec,
|
|
dbReplicaRedoBytesRemaining,
|
|
dbReplicaRedoneBytesPerSec,
|
|
dbReplicaRedonesPerSec,
|
|
dbReplicaTotalLogRequiringUndo,
|
|
dbReplicaTransactionDelay,
|
|
}
|
|
|
|
for sqlInstance := range c.mssqlInstances {
|
|
c.dbReplicaPerfDataCollectors[sqlInstance], err = perfdata.NewCollector(c.mssqlGetPerfObjectName(sqlInstance, "Database Replica"), perfdata.InstanceAll, counters)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create Database Replica collector for instance %s: %w", sqlInstance, 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 nil
|
|
}
|
|
|
|
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 *perfdata.Collector) error {
|
|
perfData, err := perfDataCollector.Collect()
|
|
if err != nil {
|
|
return fmt.Errorf("failed to collect %s metrics: %w", c.mssqlGetPerfObjectName(sqlInstance, "Database Replica"), err)
|
|
}
|
|
|
|
for replicaName, data := range perfData {
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaDatabaseFlowControlDelay,
|
|
prometheus.GaugeValue,
|
|
data[dbReplicaDatabaseFlowControlDelay].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaDatabaseFlowControls,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaDatabaseFlowControlsPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaFileBytesReceived,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaFileBytesReceivedPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaGroupCommits,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaGroupCommitsPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaGroupCommitTime,
|
|
prometheus.GaugeValue,
|
|
data[dbReplicaGroupCommitTime].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogApplyPendingQueue,
|
|
prometheus.GaugeValue,
|
|
data[dbReplicaLogApplyPendingQueue].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogApplyReadyQueue,
|
|
prometheus.GaugeValue,
|
|
data[dbReplicaLogApplyReadyQueue].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogBytesCompressed,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaLogBytesCompressedPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogBytesDecompressed,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaLogBytesDecompressedPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogBytesReceived,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaLogBytesReceivedPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogCompressionCachehits,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaLogCompressionCacheHitsPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogCompressionCachemisses,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaLogCompressionCacheMissesPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogCompressions,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaLogCompressionsPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogDecompressions,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaLogDecompressionsPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogremainingforundo,
|
|
prometheus.GaugeValue,
|
|
data[dbReplicaLogRemainingForUndo].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaLogSendQueue,
|
|
prometheus.GaugeValue,
|
|
data[dbReplicaLogSendQueue].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaMirroredWritetransactions,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaMirroredWriteTransactionsPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaRecoveryQueue,
|
|
prometheus.GaugeValue,
|
|
data[dbReplicaRecoveryQueue].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaRedoblocked,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaRedoBlockedPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaRedoBytesRemaining,
|
|
prometheus.GaugeValue,
|
|
data[dbReplicaRedoBytesRemaining].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaRedoneBytes,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaRedoneBytesPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaRedones,
|
|
prometheus.CounterValue,
|
|
data[dbReplicaRedonesPerSec].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaTotalLogrequiringundo,
|
|
prometheus.GaugeValue,
|
|
data[dbReplicaTotalLogRequiringUndo].FirstValue,
|
|
sqlInstance, replicaName,
|
|
)
|
|
|
|
ch <- prometheus.MustNewConstMetric(
|
|
c.dbReplicaTransactionDelay,
|
|
prometheus.GaugeValue,
|
|
data[dbReplicaTransactionDelay].FirstValue/1000.0,
|
|
sqlInstance, replicaName,
|
|
)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Collector) closeDatabaseReplica() {
|
|
for _, collector := range c.dbReplicaPerfDataCollectors {
|
|
collector.Close()
|
|
}
|
|
}
|