bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/scollector/collectors/sql_windows.go (about) 1 package collectors 2 3 import ( 4 "fmt" 5 "strings" 6 "time" 7 8 "bosun.org/metadata" 9 "bosun.org/opentsdb" 10 "bosun.org/slog" 11 "bosun.org/util" 12 "github.com/StackExchange/wmi" 13 ) 14 15 func init() { 16 c := &IntervalCollector{ 17 F: c_mssql, 18 } 19 c.init = wmiInit(c, func() interface{} { return &[]Win32_Service{} }, wqlSQLInstanceFilter, &sqlQuery) 20 collectors = append(collectors, c) 21 22 var dstCluster []MSCluster_Cluster 23 q := wmi.CreateQuery(&dstCluster, ``) 24 if err := queryWmiNamespace(q, &dstCluster, rootMSCluster); err != nil { 25 sqlClusterName = "None" 26 } else if len(dstCluster) != 1 { 27 sqlClusterName = "Unknown" 28 } else { 29 sqlClusterName = dstCluster[0].Name 30 } 31 32 c_replica_db := &IntervalCollector{ 33 F: c_mssql_replica_db, 34 } 35 c_replica_db.init = wmiInit(c_replica_db, func() interface{} { return &[]Win32_PerfRawData_MSSQLSERVER_SQLServerDatabaseReplica{} }, `WHERE Name <> '_Total'`, &sqlAGDBQuery) 36 collectors = append(collectors, c_replica_db) 37 38 c_replica_server := &IntervalCollector{ 39 F: c_mssql_replica_server, 40 } 41 c_replica_server.init = wmiInit(c_replica_server, func() interface{} { return &[]Win32_PerfRawData_MSSQLSERVER_SQLServerAvailabilityReplica{} }, `WHERE Name <> '_Total'`, &sqlAGQuery) 42 collectors = append(collectors, c_replica_server) 43 44 c_replica_votes := &IntervalCollector{ 45 F: c_mssql_replica_votes, 46 Interval: time.Minute * 5, 47 } 48 c_replica_votes.init = wmiInitNamespace(c_replica_votes, func() interface{} { return &[]MSCluster_Node{} }, fmt.Sprintf("WHERE Name = '%s'", util.GetHostManager().GetHostName()), &sqlAGVotes, rootMSCluster) 49 collectors = append(collectors, c_replica_votes) 50 51 c_replica_resources := &IntervalCollector{ 52 F: c_mssql_replica_resources, 53 Interval: time.Minute, 54 } 55 c_replica_resources.init = wmiInitNamespace(c_replica_resources, func() interface{} { return &[]MSCluster_Resource{} }, ``, &sqlAGResources, rootMSCluster) 56 collectors = append(collectors, c_replica_resources) 57 } 58 59 const ( 60 rootMSCluster string = "root\\MSCluster" 61 wqlSQLInstanceFilter string = `WHERE (Name Like 'MSSQL$%' or Name = 'MSSQLSERVER') and not (Name Like 'MSSQL$MICROSOFT##%' or StartMode = 'Disabled')` 62 ) 63 64 var ( 65 sqlClusterName string 66 sqlQuery string 67 sqlAGDBQuery string 68 sqlAGQuery string 69 sqlAGVotes string 70 sqlAGResources string 71 ) 72 73 func c_mssql() (opentsdb.MultiDataPoint, error) { 74 var err error 75 var svc_dst []Win32_Service 76 var svc_q = wmi.CreateQuery(&svc_dst, wqlSQLInstanceFilter) 77 err = queryWmi(svc_q, &svc_dst) 78 if err != nil { 79 return nil, slog.Wrap(err) 80 } 81 var md opentsdb.MultiDataPoint 82 add := func(f func([]Win32_Service) (opentsdb.MultiDataPoint, error)) { 83 dps, e := f(svc_dst) 84 if e != nil { 85 err = e 86 } 87 md = append(md, dps...) 88 } 89 add(c_mssql_general) 90 add(c_mssql_statistics) 91 add(c_mssql_locks) 92 add(c_mssql_databases) 93 add(c_mssql_memory) 94 add(c_mssql_buffer) 95 return md, err 96 } 97 98 func c_mssql_general(svc_dst []Win32_Service) (opentsdb.MultiDataPoint, error) { 99 var md opentsdb.MultiDataPoint 100 for _, w := range svc_dst { 101 var dst []Win32_PerfRawData_MSSQLSERVER_SQLServerGeneralStatistics 102 q := wmi.CreateQuery(&dst, `WHERE Name <> '_Total'`) 103 label := "mssqlserver" 104 if w.Name != `MSSQLSERVER` { 105 q = instanceWMIQuery(w.Name, q) 106 label = strings.ToLower(w.Name[6:len(w.Name)]) 107 } 108 if err := queryWmi(q, &dst); err != nil { 109 return nil, slog.Wrap(err) 110 } 111 for _, v := range dst { 112 tags := opentsdb.TagSet{"instance": label} 113 Add(&md, "mssql.user_connections", v.UserConnections, tags, metadata.Gauge, metadata.Count, descMSSQLUserConnections) 114 Add(&md, "mssql.connection_resets", v.ConnectionResetPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLConnectionResetPersec) 115 Add(&md, "mssql.logins", v.LoginsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLoginsPersec) 116 Add(&md, "mssql.logouts", v.LogoutsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLogoutsPersec) 117 Add(&md, "mssql.mars_deadlocks", v.MarsDeadlocks, tags, metadata.Counter, metadata.Count, descMSSQLMarsDeadlocks) 118 Add(&md, "mssql.proc_blocked", v.Processesblocked, tags, metadata.Gauge, metadata.Count, descMSSQLProcessesblocked) 119 Add(&md, "mssql.temptables_created", v.TempTablesCreationRate, tags, metadata.Counter, metadata.PerSecond, descMSSQLTempTablesCreationRate) 120 Add(&md, "mssql.temptables_to_destroy", v.TempTablesForDestruction, tags, metadata.Gauge, metadata.Count, descMSSQLTempTablesForDestruction) 121 Add(&md, "mssql.transactions_total", v.Transactions, tags, metadata.Gauge, metadata.Count, descMSSQLTransactions) 122 123 } 124 } 125 return md, nil 126 } 127 128 const ( 129 descMSSQLUserConnections = "Number of users connected to the system." 130 descMSSQLConnectionResetPersec = "Total number of connection resets per second." 131 descMSSQLLoginsPersec = "Total number of logins started per second." 132 descMSSQLLogoutsPersec = "Total number of logouts started per second." 133 descMSSQLMarsDeadlocks = "Number of Mars Deadlocks detected." 134 descMSSQLProcessesblocked = "Number of currently blocked processes." 135 descMSSQLTempTablesCreationRate = "Number of temporary tables/table variables created/sec." 136 descMSSQLTempTablesForDestruction = "Number of temporary tables/table variables waiting to be destroyed by the cleanup system thread." 137 descMSSQLTransactions = "Number of transaction enlistments (local, dtc, and bound)." 138 ) 139 140 type Win32_PerfRawData_MSSQLSERVER_SQLServerGeneralStatistics struct { 141 ConnectionResetPersec uint64 142 LoginsPersec uint64 143 LogoutsPersec uint64 144 MarsDeadlocks uint64 145 Processesblocked uint64 146 TempTablesCreationRate uint64 147 TempTablesForDestruction uint64 148 Transactions uint64 149 UserConnections uint64 150 } 151 152 func c_mssql_statistics(svc_dst []Win32_Service) (opentsdb.MultiDataPoint, error) { 153 var md opentsdb.MultiDataPoint 154 for _, w := range svc_dst { 155 var dst []Win32_PerfRawData_MSSQLSERVER_SQLServerSQLStatistics 156 q := wmi.CreateQuery(&dst, `WHERE Name <> '_Total'`) 157 label := "mssqlserver" 158 if w.Name != `MSSQLSERVER` { 159 q = instanceWMIQuery(w.Name, q) 160 label = strings.ToLower(w.Name[6:len(w.Name)]) 161 } 162 err := queryWmi(q, &dst) 163 if err != nil { 164 return nil, slog.Wrap(err) 165 } 166 for _, v := range dst { 167 tags := opentsdb.TagSet{"instance": label} 168 Add(&md, "mssql.autoparam_attempts", v.AutoParamAttemptsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLAutoParamAttemptsPersec) 169 Add(&md, "mssql.autoparam_failed", v.FailedAutoParamsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLFailedAutoParamsPersec) 170 Add(&md, "mssql.autoparam_forced", v.ForcedParameterizationsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLForcedParameterizationsPersec) 171 Add(&md, "mssql.autoparam_safe", v.SafeAutoParamsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLSafeAutoParamsPersec) 172 Add(&md, "mssql.autoparam_unsafe", v.UnsafeAutoParamsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLUnsafeAutoParamsPersec) 173 Add(&md, "mssql.batches", v.BatchRequestsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLBatchRequestsPersec) 174 Add(&md, "mssql.guided_plans", v.GuidedplanexecutionsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLGuidedplanexecutionsPersec) 175 Add(&md, "mssql.misguided_plans", v.MisguidedplanexecutionsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLMisguidedplanexecutionsPersec) 176 Add(&md, "mssql.compilations", v.SQLCompilationsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLSQLCompilationsPersec) 177 Add(&md, "mssql.recompilations", v.SQLReCompilationsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLSQLReCompilationsPersec) 178 } 179 } 180 return md, nil 181 } 182 183 const ( 184 descMSSQLAutoParamAttemptsPersec = "Number of auto-parameterization attempts." 185 descMSSQLFailedAutoParamsPersec = "Number of failed auto-parameterizations." 186 descMSSQLForcedParameterizationsPersec = "Number of statements parameterized by forced parameterization per second." 187 descMSSQLSafeAutoParamsPersec = "Number of safe auto-parameterizations." 188 descMSSQLUnsafeAutoParamsPersec = "Number of unsafe auto-parameterizations." 189 descMSSQLBatchRequestsPersec = "Number of SQL batch requests received by server." 190 descMSSQLGuidedplanexecutionsPersec = "Number of plan executions per second in which the query plan has been generated by using a plan guide." 191 descMSSQLMisguidedplanexecutionsPersec = "Number of plan executions per second in which a plan guide could not be honored during plan generation. The plan guide was disregarded and normal compilation was used to generate the executed plan." 192 descMSSQLSQLCompilationsPersec = "Number of SQL compilations." 193 descMSSQLSQLReCompilationsPersec = "Number of SQL re-compiles." 194 ) 195 196 type Win32_PerfRawData_MSSQLSERVER_SQLServerSQLStatistics struct { 197 AutoParamAttemptsPersec uint64 198 BatchRequestsPersec uint64 199 FailedAutoParamsPersec uint64 200 ForcedParameterizationsPersec uint64 201 GuidedplanexecutionsPersec uint64 202 MisguidedplanexecutionsPersec uint64 203 SafeAutoParamsPersec uint64 204 SQLCompilationsPersec uint64 205 SQLReCompilationsPersec uint64 206 UnsafeAutoParamsPersec uint64 207 } 208 209 func c_mssql_locks(svc_dst []Win32_Service) (opentsdb.MultiDataPoint, error) { 210 var md opentsdb.MultiDataPoint 211 for _, w := range svc_dst { 212 var dst []Win32_PerfRawData_MSSQLSERVER_SQLServerLocks 213 q := wmi.CreateQuery(&dst, `WHERE Name = 'Page' OR Name = 'Extent' OR Name = 'Object' or Name = 'Database'`) 214 label := "mssqlserver" 215 if w.Name != `MSSQLSERVER` { 216 q = instanceWMIQuery(w.Name, q) 217 label = strings.ToLower(w.Name[6:len(w.Name)]) 218 } 219 err := queryWmi(q, &dst) 220 if err != nil { 221 return nil, slog.Wrap(err) 222 } 223 for _, v := range dst { 224 tags := opentsdb.TagSet{"instance": label, "type": v.Name} 225 Add(&md, "mssql.lock_wait_time", v.AverageWaitTimems, tags, metadata.Counter, metadata.MilliSecond, descMSSQLAverageWaitTimems) 226 Add(&md, "mssql.lock_requests", v.LockRequestsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLockRequestsPersec) 227 Add(&md, "mssql.lock_timeouts", v.LockTimeoutsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLockTimeoutsPersec) 228 Add(&md, "mssql.lock_timeouts0", v.LockTimeoutstimeout0Persec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLockTimeoutstimeout0Persec) 229 Add(&md, "mssql.lock_waits", v.LockWaitsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLockWaitsPersec) 230 Add(&md, "mssql.deadlocks", v.NumberofDeadlocksPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLNumberofDeadlocksPersec) 231 } 232 } 233 return md, nil 234 } 235 236 const ( 237 descMSSQLAverageWaitTimems = "The average amount of wait time (milliseconds) for each lock request that resulted in a wait." 238 descMSSQLLockRequestsPersec = "Number of new locks and lock conversions requested from the lock manager." 239 descMSSQLLockTimeoutsPersec = "Number of lock requests that timed out. This includes requests for NOWAIT locks." 240 descMSSQLLockTimeoutstimeout0Persec = "Number of lock requests that timed out. This does not include requests for NOWAIT locks." 241 descMSSQLLockWaitsPersec = "Number of lock requests that could not be satisfied immediately and required the caller to wait before being granted the lock." 242 descMSSQLNumberofDeadlocksPersec = "Number of lock requests that resulted in a deadlock." 243 ) 244 245 type Win32_PerfRawData_MSSQLSERVER_SQLServerLocks struct { 246 AverageWaitTimems uint64 247 LockRequestsPersec uint64 248 LockTimeoutsPersec uint64 249 LockTimeoutstimeout0Persec uint64 250 LockWaitsPersec uint64 251 Name string 252 NumberofDeadlocksPersec uint64 253 } 254 255 func c_mssql_databases(svc_dst []Win32_Service) (opentsdb.MultiDataPoint, error) { 256 var md opentsdb.MultiDataPoint 257 for _, w := range svc_dst { 258 var dst []Win32_PerfRawData_MSSQLSERVER_SQLServerDatabases 259 q := wmi.CreateQuery(&dst, `WHERE Name <> '_Total'`) 260 label := "mssqlserver" 261 if w.Name != `MSSQLSERVER` { 262 q = instanceWMIQuery(w.Name, q) 263 label = strings.ToLower(w.Name[6:len(w.Name)]) 264 } 265 err := queryWmi(q, &dst) 266 if err != nil { 267 return nil, slog.Wrap(err) 268 } 269 for _, v := range dst { 270 tags := opentsdb.TagSet{"instance": label, "db": v.Name} 271 Add(&md, "mssql.active_transactions", v.ActiveTransactions, tags, metadata.Gauge, metadata.Count, descMSSQLActiveTransactions) 272 Add(&md, "mssql.backup_restore_throughput", v.BackupPerRestoreThroughputPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLBackupPerRestoreThroughputPersec) 273 Add(&md, "mssql.bulkcopy_rows", v.BulkCopyRowsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLBulkCopyRowsPersec) 274 Add(&md, "mssql.bulkcopy_throughput", v.BulkCopyThroughputPersec, tags, metadata.Counter, metadata.KBytes, descMSSQLBulkCopyThroughputPersec) 275 Add(&md, "mssql.commit_table_entries", v.Committableentries, tags, metadata.Gauge, metadata.Count, descMSSQLCommittableentries) 276 Add(&md, "mssql.data_files_size", v.DataFilesSizeKB*1024, tags, metadata.Gauge, metadata.Bytes, descMSSQLDataFilesSizeKB) 277 Add(&md, "mssql.dbcc_logical_scan_bytes", v.DBCCLogicalScanBytesPersec, tags, metadata.Counter, metadata.BytesPerSecond, descMSSQLDBCCLogicalScanBytesPersec) 278 //Add(&md, "mssql.group_commit_time", v.GroupCommitTimePersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLGroupCommitTimePersec) 279 Add(&md, "mssql.log_bytes_flushed", v.LogBytesFlushedPersec, tags, metadata.Counter, metadata.BytesPerSecond, descMSSQLLogBytesFlushedPersec) 280 Add(&md, "mssql.log_cache_hit_ratio", v.LogCacheHitRatio, tags, metadata.Counter, metadata.Pct, descMSSQLLogCacheHitRatio) 281 Add(&md, "mssql.log_cache_hit_ratio_base", v.LogCacheHitRatio_Base, tags, metadata.Counter, metadata.None, descMSSQLLogCacheHitRatio_Base) 282 Add(&md, "mssql.log_cache_reads", v.LogCacheReadsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLogCacheReadsPersec) 283 Add(&md, "mssql.log_files_size", v.LogFilesSizeKB*1024, tags, metadata.Gauge, metadata.Bytes, descMSSQLLogFilesSizeKB) 284 Add(&md, "mssql.log_files_used_size", v.LogFilesUsedSizeKB*1024, tags, metadata.Gauge, metadata.Bytes, descMSSQLLogFilesUsedSizeKB) 285 Add(&md, "mssql.log_flushes", v.LogFlushesPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLogFlushesPersec) 286 Add(&md, "mssql.log_flush_waits", v.LogFlushWaitsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLogFlushWaitsPersec) 287 Add(&md, "mssql.log_flush_wait_time", v.LogFlushWaitTime, tags, metadata.Counter, metadata.MilliSecond, descMSSQLLogFlushWaitTime) 288 //Add(&md, "mssql.log_flush_write_time_ms", v.LogFlushWriteTimems, tags, metadata.Counter, metadata.MilliSecond, descMSSQLLogFlushWriteTimems) 289 Add(&md, "mssql.log_growths", v.LogGrowths, tags, metadata.Gauge, metadata.Count, descMSSQLLogGrowths) 290 //Add(&md, "mssql.log_pool_cache_misses", v.LogPoolCacheMissesPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLogPoolCacheMissesPersec) 291 //Add(&md, "mssql.log_pool_disk_reads", v.LogPoolDiskReadsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLogPoolDiskReadsPersec) 292 //Add(&md, "mssql.log_pool_requests", v.LogPoolRequestsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLLogPoolRequestsPersec) 293 Add(&md, "mssql.log_shrinks", v.LogShrinks, tags, metadata.Gauge, metadata.Count, descMSSQLLogShrinks) 294 Add(&md, "mssql.log_truncations", v.LogTruncations, tags, metadata.Gauge, metadata.Count, descMSSQLLogTruncations) 295 Add(&md, "mssql.percent_log_used", v.PercentLogUsed, tags, metadata.Gauge, metadata.Pct, descMSSQLPercentLogUsed) 296 Add(&md, "mssql.repl_pending_xacts", v.ReplPendingXacts, tags, metadata.Gauge, metadata.Count, descMSSQLReplPendingXacts) 297 Add(&md, "mssql.repl_trans_rate", v.ReplTransRate, tags, metadata.Counter, metadata.PerSecond, descMSSQLReplTransRate) 298 Add(&md, "mssql.shrink_data_movement_bytes", v.ShrinkDataMovementBytesPersec, tags, metadata.Counter, metadata.BytesPerSecond, descMSSQLShrinkDataMovementBytesPersec) 299 Add(&md, "mssql.tracked_transactions", v.TrackedtransactionsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLTrackedtransactionsPersec) 300 Add(&md, "mssql.transactions", v.TransactionsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLTransactionsPersec) 301 Add(&md, "mssql.write_transactions", v.WriteTransactionsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLWriteTransactionsPersec) 302 } 303 } 304 return md, nil 305 } 306 307 const ( 308 descMSSQLActiveTransactions = "Number of active update transactions for the database." 309 descMSSQLBackupPerRestoreThroughputPersec = "Read/write throughput for backup/restore of a database." 310 descMSSQLBulkCopyRowsPersec = "Number of rows bulk copied." 311 descMSSQLBulkCopyThroughputPersec = "KiloBytes bulk copied." 312 descMSSQLCommittableentries = "The size of the in-memory part of the commit table for the database." 313 descMSSQLDataFilesSizeKB = "The cumulative size of all the data files in the database." 314 descMSSQLDBCCLogicalScanBytesPersec = "Logical read scan rate for DBCC commands." 315 descMSSQLGroupCommitTimePersec = "Group stall time (microseconds) per second." 316 descMSSQLLogBytesFlushedPersec = "Total number of log bytes flushed." 317 descMSSQLLogCacheHitRatio = "Percentage of log cache reads that were satisfied from the log cache." 318 descMSSQLLogCacheHitRatio_Base = "Percentage of log cache reads that were satisfied from the log cache." 319 descMSSQLLogCacheReadsPersec = "Reads performed through the log manager cache." 320 descMSSQLLogFilesSizeKB = "The cumulative size of all the log files in the database." 321 descMSSQLLogFilesUsedSizeKB = "The cumulative used size of all the log files in the database." 322 descMSSQLLogFlushesPersec = "Number of log flushes." 323 descMSSQLLogFlushWaitsPersec = "Number of commits waiting on log flush." 324 descMSSQLLogFlushWaitTime = "Total wait time (milliseconds)." 325 descMSSQLLogFlushWriteTimems = "Milliseconds it took to perform the writes of log flushes completed in the last second." 326 descMSSQLLogGrowths = "Total number of log growths for this database." 327 descMSSQLLogPoolCacheMissesPersec = "Log block cache misses from log pool." 328 descMSSQLLogPoolDiskReadsPersec = "Log disk reads via log pool." 329 descMSSQLLogPoolRequestsPersec = "Log block requests performed through log pool." 330 descMSSQLLogShrinks = "Total number of log shrinks for this database." 331 descMSSQLLogTruncations = "Total number of log truncations for this database." 332 descMSSQLPercentLogUsed = "The percent of space in the log that is in use." 333 descMSSQLReplPendingXacts = "Number of pending replication transactions in the database." 334 descMSSQLReplTransRate = "Replication transaction rate (replicated transactions/sec.)." 335 descMSSQLShrinkDataMovementBytesPersec = "The rate data is being moved by Autoshrink, DBCC SHRINKDATABASE or SHRINKFILE." 336 descMSSQLTrackedtransactionsPersec = "Number of committed transactions recorded in the commit table for the database." 337 descMSSQLTransactionsPersec = "Number of transactions started for the database." 338 descMSSQLWriteTransactionsPersec = "Number of transactions which wrote to the database in the last second." 339 ) 340 341 type Win32_PerfRawData_MSSQLSERVER_SQLServerDatabases struct { 342 ActiveTransactions uint64 343 BackupPerRestoreThroughputPersec uint64 344 BulkCopyRowsPersec uint64 345 BulkCopyThroughputPersec uint64 346 Committableentries uint64 347 DataFilesSizeKB uint64 348 DBCCLogicalScanBytesPersec uint64 349 //GroupCommitTimePersec uint64 350 LogBytesFlushedPersec uint64 351 LogCacheHitRatio uint64 352 LogCacheHitRatio_Base uint64 353 LogCacheReadsPersec uint64 354 LogFilesSizeKB uint64 355 LogFilesUsedSizeKB uint64 356 LogFlushesPersec uint64 357 LogFlushWaitsPersec uint64 358 LogFlushWaitTime uint64 359 //LogFlushWriteTimems uint64 360 LogGrowths uint64 361 //LogPoolCacheMissesPersec uint64 362 //LogPoolDiskReadsPersec uint64 363 //LogPoolRequestsPersec uint64 364 LogShrinks uint64 365 LogTruncations uint64 366 Name string 367 PercentLogUsed uint64 368 ReplPendingXacts uint64 369 ReplTransRate uint64 370 ShrinkDataMovementBytesPersec uint64 371 TrackedtransactionsPersec uint64 372 TransactionsPersec uint64 373 WriteTransactionsPersec uint64 374 } 375 376 func c_mssql_replica_db() (opentsdb.MultiDataPoint, error) { 377 var dst []Win32_PerfRawData_MSSQLSERVER_SQLServerDatabaseReplica 378 if err := queryWmi(sqlAGDBQuery, &dst); err != nil { 379 return nil, slog.Wrap(err) 380 } 381 var md opentsdb.MultiDataPoint 382 for _, v := range dst { 383 tags := opentsdb.TagSet{"db": v.Name} 384 //see http://technet.microsoft.com/en-us/library/dn135338%28v=sql.110%29.aspx 385 Add(&md, "mssql.replica.bytes_db", v.FileBytesReceivedPersec, opentsdb.TagSet{"db": v.Name, "type": "filestream_received"}, metadata.Counter, metadata.BytesPerSecond, descMSSQLReplicaFileBytesReceivedPersec) 386 Add(&md, "mssql.replica.bytes_db", v.LogBytesReceivedPersec, opentsdb.TagSet{"db": v.Name, "type": "log_received"}, metadata.Counter, metadata.BytesPerSecond, descMSSQLReplicaLogBytesReceivedPersec) 387 Add(&md, "mssql.replica.bytes_db", v.RedoneBytesPersec, opentsdb.TagSet{"db": v.Name, "type": "log_redone"}, metadata.Counter, metadata.BytesPerSecond, descMSSQLReplicaRedoneBytesPersec) 388 Add(&md, "mssql.replica.mirrored_transactions", v.MirroredWriteTransactionsPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLReplicaMirroredWriteTransactionsPersec) 389 Add(&md, "mssql.replica.redo_blocked", v.RedoblockedPersec, tags, metadata.Counter, metadata.PerSecond, descMSSQLReplicaRedoblockedPersec) 390 Add(&md, "mssql.replica.delay_ack", v.TransactionDelay, opentsdb.TagSet{"db": v.Name}, metadata.Counter, metadata.MilliSecond, descMSSQLReplicaTransactionDelay) 391 Add(&md, "mssql.replica.recovery", v.LogSendQueue*1024, opentsdb.TagSet{"db": v.Name, "type": "sending"}, metadata.Gauge, metadata.Bytes, descMSSQLReplicaLogSendQueue) 392 Add(&md, "mssql.replica.recovery", v.RecoveryQueue*1024, opentsdb.TagSet{"db": v.Name, "type": "received"}, metadata.Gauge, metadata.Bytes, descMSSQLReplicaRecoveryQueue) 393 Add(&md, "mssql.replica.recovery", v.RedoBytesRemaining*1024, opentsdb.TagSet{"db": v.Name, "type": "redo"}, metadata.Gauge, metadata.Bytes, descMSSQLReplicaRedoBytesRemaining) 394 Add(&md, "mssql.replica.recovery", v.TotalLogrequiringundo*1024, opentsdb.TagSet{"db": v.Name, "type": "undo_total"}, metadata.Gauge, metadata.Bytes, descMSSQLReplicaTotalLogrequiringundo) 395 Add(&md, "mssql.replica.recovery", v.Logremainingforundo*1024, opentsdb.TagSet{"db": v.Name, "type": "undo_remaining"}, metadata.Gauge, metadata.Bytes, descMSSQLReplicaLogremainingforundo) 396 } 397 return md, nil 398 } 399 400 const ( 401 descMSSQLReplicaFileBytesReceivedPersec = "Amount of filestream data received by the availability replica for the database." 402 descMSSQLReplicaLogBytesReceivedPersec = "Amount of logs received by the availability replica for the database." 403 descMSSQLReplicaLogremainingforundo = "The amount of log in bytes remaining to finish the undo phase." 404 descMSSQLReplicaLogSendQueue = "Amount of logs in bytes that is waiting to be sent to the database replica." 405 descMSSQLReplicaMirroredWriteTransactionsPersec = "Number of transactions which wrote to the mirrored database in the last second, that waited for log to be sent to the mirror." 406 descMSSQLReplicaRecoveryQueue = "Total number of hardened log in bytes that is waiting to be redone on the secondary." 407 descMSSQLReplicaRedoblockedPersec = "Number of times redo gets blocked in the last second." 408 descMSSQLReplicaRedoBytesRemaining = "The amount of log in bytes remaining to be redone to finish the reverting phase." 409 descMSSQLReplicaRedoneBytesPersec = "Amount of log records redone in the last second to catch up the database replica." 410 descMSSQLReplicaTotalLogrequiringundo = "The amount of log in bytes that need to be undone." 411 descMSSQLReplicaTransactionDelay = "Number of milliseconds transaction termination waited for acknowledgement per second." 412 ) 413 414 type Win32_PerfRawData_MSSQLSERVER_SQLServerDatabaseReplica struct { 415 FileBytesReceivedPersec uint64 416 LogBytesReceivedPersec uint64 417 Logremainingforundo uint64 418 LogSendQueue uint64 419 MirroredWriteTransactionsPersec uint64 420 Name string 421 RecoveryQueue uint64 422 RedoblockedPersec uint64 423 RedoBytesRemaining uint64 424 RedoneBytesPersec uint64 425 TotalLogrequiringundo uint64 426 TransactionDelay uint64 427 } 428 429 func c_mssql_replica_server() (opentsdb.MultiDataPoint, error) { 430 var dst []Win32_PerfRawData_MSSQLSERVER_SQLServerAvailabilityReplica 431 if err := queryWmi(sqlAGQuery, &dst); err != nil { 432 return nil, slog.Wrap(err) 433 } 434 var md opentsdb.MultiDataPoint 435 for _, v := range dst { 436 //split name into AvailibilityGroup and Destination. Name is in 'Group:Destination' format 437 s := strings.Split(v.Name, ":") 438 if len(s) != 2 { 439 return nil, fmt.Errorf("Invalid Availibility Group Name: '%s'", v.Name) 440 } 441 destination := strings.ToLower(s[1]) 442 //see http://technet.microsoft.com/en-us/library/ff878472(v=sql.110).aspx 443 //also https://livedemo.customers.na.apm.ibmserviceengage.com/help/index.jsp?topic=%2Fcom.ibm.koq.doc%2Fattr_koqadbst.htm 444 Add(&md, "mssql.replica.bytes_ag", v.BytesReceivedfromReplicaPersec, opentsdb.TagSet{"group": s[0], "destination": destination, "type": "received"}, metadata.Counter, metadata.BytesPerSecond, descMSSQLReplicaBytesReceivedfromReplicaPersec) 445 Add(&md, "mssql.replica.bytes_ag", v.BytesSenttoReplicaPersec, opentsdb.TagSet{"group": s[0], "destination": destination, "type": "sent_replica"}, metadata.Counter, metadata.BytesPerSecond, descMSSQLReplicaBytesSenttoReplicaPersec) 446 Add(&md, "mssql.replica.bytes_ag", v.BytesSenttoTransportPersec, opentsdb.TagSet{"group": s[0], "destination": destination, "type": "sent_transport"}, metadata.Counter, metadata.BytesPerSecond, descMSSQLReplicaBytesSenttoTransportPersec) 447 Add(&md, "mssql.replica.delay_flow", v.FlowControlTimemsPersec, opentsdb.TagSet{"group": s[0], "destination": destination}, metadata.Counter, metadata.MilliSecond, descMSSQLReplicaFlowControlTimemsPersec) 448 Add(&md, "mssql.replica.messages", v.FlowControlPersec, opentsdb.TagSet{"group": s[0], "destination": destination, "type": "flow_control"}, metadata.Counter, metadata.PerSecond, descMSSQLReplicaFlowControlPersec) 449 Add(&md, "mssql.replica.messages", v.ReceivesfromReplicaPersec, opentsdb.TagSet{"group": s[0], "destination": destination, "type": "received"}, metadata.Counter, metadata.PerSecond, descMSSQLReplicaReceivesfromReplicaPersec) 450 Add(&md, "mssql.replica.messages", v.ResentMessagesPersec, opentsdb.TagSet{"group": s[0], "destination": destination, "type": "resent"}, metadata.Counter, metadata.PerSecond, descMSSQLReplicaResentMessagesPersec) 451 Add(&md, "mssql.replica.messages", v.SendstoReplicaPersec, opentsdb.TagSet{"group": s[0], "destination": destination, "type": "sent_replica"}, metadata.Counter, metadata.PerSecond, descMSSQLReplicaSendstoReplicaPersec) 452 Add(&md, "mssql.replica.messages", v.SendstoTransportPersec, opentsdb.TagSet{"group": s[0], "destination": destination, "type": "sent_transport"}, metadata.Counter, metadata.PerSecond, descMSSQLReplicaSendstoTransportPersec) 453 454 } 455 return md, nil 456 } 457 458 const ( 459 descMSSQLReplicaBytesReceivedfromReplicaPersec = "Total bytes receieved from the availability replica." 460 descMSSQLReplicaBytesSenttoReplicaPersec = "Total bytes sent to the availabilty replica." 461 descMSSQLReplicaBytesSenttoTransportPersec = "Total bytes sent to transport for the availabilty replica." 462 descMSSQLReplicaFlowControlPersec = "Number of flow control initiated in the last second." 463 descMSSQLReplicaFlowControlTimemsPersec = "Time in milliseconds messages waited on flow control in the last second." 464 descMSSQLReplicaReceivesfromReplicaPersec = "Total receives from the availability replica." 465 descMSSQLReplicaResentMessagesPersec = "Number of messages being resent in the last second." 466 descMSSQLReplicaSendstoReplicaPersec = "Total sends to the availability replica." 467 descMSSQLReplicaSendstoTransportPersec = "Total sends to transport for the availability replica." 468 ) 469 470 type Win32_PerfRawData_MSSQLSERVER_SQLServerAvailabilityReplica struct { 471 BytesReceivedfromReplicaPersec uint64 472 BytesSenttoReplicaPersec uint64 473 BytesSenttoTransportPersec uint64 474 FlowControlPersec uint64 475 FlowControlTimemsPersec uint64 476 Name string 477 ReceivesfromReplicaPersec uint64 478 ResentMessagesPersec uint64 479 SendstoReplicaPersec uint64 480 SendstoTransportPersec uint64 481 } 482 483 func c_mssql_replica_votes() (opentsdb.MultiDataPoint, error) { 484 var dst []MSCluster_Node 485 if err := queryWmiNamespace(sqlAGVotes, &dst, rootMSCluster); err != nil { 486 return nil, slog.Wrap(err) 487 } 488 489 var md opentsdb.MultiDataPoint 490 for _, v := range dst { 491 Add(&md, "mssql.replica.votes", v.NodeWeight, opentsdb.TagSet{"cluster": sqlClusterName, "type": "standard"}, metadata.Gauge, metadata.Count, descMSSQLReplicaNodeWeight) 492 Add(&md, "mssql.replica.votes", v.DynamicWeight, opentsdb.TagSet{"cluster": sqlClusterName, "type": "dynamic"}, metadata.Gauge, metadata.Count, descMSSQLReplicaDynamicWeight) 493 Add(&md, "mssql.replica.cluster_state", v.State, opentsdb.TagSet{"cluster": sqlClusterName}, metadata.Gauge, metadata.StatusCode, descMSSQLReplicaClusterState) 494 } 495 return md, nil 496 } 497 498 const ( 499 descMSSQLReplicaNodeWeight = "The current vote weight of the node." 500 descMSSQLReplicaDynamicWeight = "The vote weight of the node when adjusted by the dynamic quorum feature." 501 descMSSQLReplicaClusterState = "StateUnknown (-1), Up (0), Down (1), Paused (2), Joining (3)." 502 ) 503 504 type MSCluster_Node struct { 505 Name string 506 NodeWeight uint32 507 DynamicWeight uint32 508 State uint32 509 } 510 511 type MSCluster_Cluster struct { 512 Name string 513 } 514 515 func c_mssql_replica_resources() (opentsdb.MultiDataPoint, error) { 516 var dst []MSCluster_Resource 517 //Only report metrics for resources owned by this node 518 q := wmi.CreateQuery(&dst, fmt.Sprintf("WHERE OwnerNode = '%s'", util.GetHostManager().GetHostName())) 519 if err := queryWmiNamespace(q, &dst, rootMSCluster); err != nil { 520 return nil, slog.Wrap(err) 521 } 522 var md opentsdb.MultiDataPoint 523 for _, v := range dst { 524 Add(&md, "mssql.replica.resource_state", v.State, opentsdb.TagSet{"group": v.OwnerGroup, "type": v.Type, "name": v.Name}, metadata.Gauge, metadata.StatusCode, descMSSQLReplicaResourceState) 525 } 526 return md, nil 527 } 528 529 const ( 530 descMSSQLReplicaResourceState = "StateUnknown (-1), TBD (0), Initializing (1), Online (2), Offline (3), Failed(4), Pending(128), Online Pending (129), Offline Pending (130)." 531 ) 532 533 type MSCluster_Resource struct { 534 Name string 535 OwnerGroup string 536 OwnerNode string 537 Type string 538 State uint32 539 } 540 541 func c_mssql_memory(svc_dst []Win32_Service) (opentsdb.MultiDataPoint, error) { 542 var md opentsdb.MultiDataPoint 543 for _, w := range svc_dst { 544 var dst []Win32_PerfRawData_MSSQLSERVER_SQLServerMemoryManager 545 q := wmi.CreateQuery(&dst, ``) 546 label := "mssqlserver" 547 if w.Name != `MSSQLSERVER` { 548 q = instanceWMIQuery(w.Name, q) 549 label = strings.ToLower(w.Name[6:len(w.Name)]) 550 } 551 if err := queryWmi(q, &dst); err != nil { 552 return nil, slog.Wrap(err) 553 } 554 for _, v := range dst { 555 tags := opentsdb.TagSet{"instance": label} 556 Add(&md, "mssql.memory.target", v.TargetServerMemoryKB*1024, tags, metadata.Gauge, metadata.Bytes, descMSSQLTargetServerMemoryKB) 557 Add(&md, "mssql.memory.total", v.TotalServerMemoryKB*1024, tags, metadata.Gauge, metadata.Bytes, descMSSQLTotalServerMemoryKB) 558 } 559 } 560 return md, nil 561 } 562 563 const ( 564 descMSSQLTargetServerMemoryKB = "Indicates the ideal amount of memory the server can consume." 565 descMSSQLTotalServerMemoryKB = "Specifies the amount of memory the server has committed using the memory manager." 566 ) 567 568 type Win32_PerfRawData_MSSQLSERVER_SQLServerMemoryManager struct { 569 TargetServerMemoryKB uint64 570 TotalServerMemoryKB uint64 571 } 572 573 func c_mssql_buffer(svc_dst []Win32_Service) (opentsdb.MultiDataPoint, error) { 574 var md opentsdb.MultiDataPoint 575 for _, w := range svc_dst { 576 var dst []Win32_PerfRawData_MSSQLSERVER_SQLServerBufferManager 577 q := wmi.CreateQuery(&dst, ``) 578 label := "mssqlserver" 579 if w.Name != `MSSQLSERVER` { 580 q = instanceWMIQuery(w.Name, q) 581 label = strings.ToLower(w.Name[6:len(w.Name)]) 582 } 583 if err := queryWmi(q, &dst); err != nil { 584 return nil, slog.Wrap(err) 585 } 586 for _, v := range dst { 587 tags := opentsdb.TagSet{"instance": label} 588 Add(&md, "mssql.buffer.page_life_expectancy", v.PageLifeExpectancy, tags, metadata.Gauge, metadata.Second, descMSSQLPageLifeExpectancy) 589 if v.BufferCacheHitRatio_Base != 0 { 590 Add(&md, "mssql.buffer.cache_hit_ratio", float64(v.BufferCacheHitRatio*100)/float64(v.BufferCacheHitRatio_Base), tags, metadata.Gauge, metadata.Pct, descBufferCacheHitRatio) 591 } 592 } 593 } 594 return md, nil 595 } 596 597 const ( 598 descMSSQLPageLifeExpectancy = "Indicates the number of seconds a page will stay in the buffer pool without references." 599 descBufferCacheHitRatio = "Percentage of pages that were found in the buffer pool without having to incur a read from disk." 600 ) 601 602 type Win32_PerfRawData_MSSQLSERVER_SQLServerBufferManager struct { 603 PageLifeExpectancy uint64 604 BufferCacheHitRatio uint64 605 BufferCacheHitRatio_Base uint64 606 } 607 608 func instanceWMIQuery(instancename string, wmiquery string) string { 609 var newname = strings.Replace(strings.Replace(instancename, `$`, "", 1), `_`, "", -1) 610 return strings.Replace(wmiquery, `MSSQLSERVER_SQLServer`, newname+`_`+newname, 1) 611 }