bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/cmd/scollector/collectors/sqlagent_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 "github.com/StackExchange/wmi" 12 ) 13 14 func init() { 15 c := &IntervalCollector{ 16 F: c_mssql_agents, 17 Interval: time.Minute * 5, 18 } 19 c.init = wmiInit(c, func() interface{} { return &[]Win32_Service{} }, wqlSQLAgentInstanceFilter, &sqlAgentQuery) 20 collectors = append(collectors, c) 21 } 22 23 const ( 24 wqlSQLAgentInstanceFilter string = `WHERE (Name Like 'SQLAgent$%' or Name = 'SQLSERVERAGENT') and not (StartMode = 'Disabled')` 25 ) 26 27 var ( 28 sqlAgentQuery string 29 ) 30 31 func c_mssql_agents() (opentsdb.MultiDataPoint, error) { 32 var err error 33 var svc_dst []Win32_Service 34 var svc_q = wmi.CreateQuery(&svc_dst, wqlSQLAgentInstanceFilter) 35 err = queryWmi(svc_q, &svc_dst) 36 if err != nil { 37 return nil, slog.Wrap(err) 38 } 39 var md opentsdb.MultiDataPoint 40 add := func(f func([]Win32_Service) (opentsdb.MultiDataPoint, error)) { 41 dps, e := f(svc_dst) 42 if e != nil { 43 err = e 44 } 45 md = append(md, dps...) 46 } 47 add(c_mssql_agent) 48 return md, err 49 } 50 51 func c_mssql_agent(svc_dst []Win32_Service) (opentsdb.MultiDataPoint, error) { 52 var md opentsdb.MultiDataPoint 53 for _, w := range svc_dst { 54 var dst []Win32_PerfRawData_SQLSERVERAGENT_SQLAgentJobs 55 //Default Instance: Win32_PerfRawData_SQLSERVERAGENT_SQLAgentJobs Service: SQLSERVERAGENT 56 //Named Instance: Win32_PerfRawData_SQLAgentOSCARMAYER_SQLAgentOSCARMAYERJobs Service: SQLAgent$OSCARMAYER 57 //WMI Class has Alerts, Schedules, and Other instances, but for now we'll just collect the totals 58 q := wmi.CreateQuery(&dst, `WHERE Name = '_Total'`) 59 label := "mssqlserver" 60 if w.Name != `SQLSERVERAGENT` { 61 if len(w.Name) < 9 { 62 return md, slog.Wrap(fmt.Errorf("invalid service name: %v", w.Name)) 63 } 64 q = instanceAgentWMIQuery(w.Name, q) 65 label = strings.ToLower(w.Name[9:len(w.Name)]) 66 } 67 if err := queryWmi(q, &dst); err != nil { 68 return nil, slog.Wrap(err) 69 } 70 for _, v := range dst { 71 tags := opentsdb.TagSet{"instance": label} 72 Add(&md, "mssql.agent.active_jobs", v.Activejobs, tags, metadata.Gauge, metadata.Count, descMSSQLAgentActivejobs) 73 Add(&md, "mssql.agent.job_results", v.Failedjobs, opentsdb.TagSet{"type": "failed"}.Merge(tags), metadata.Counter, metadata.Count, descMSSQLAgentFailedjobs) 74 Add(&md, "mssql.agent.job_results", v.Successfuljobs, opentsdb.TagSet{"type": "successful"}.Merge(tags), metadata.Counter, metadata.Count, descMSSQLAgentSuccessfuljobs) 75 } 76 } 77 return md, nil 78 } 79 80 const ( 81 descMSSQLAgentActivejobs = "Number of currently running jobs. Note this is not a counter so it often will miss jobs that finish in less than 5 minutes." 82 descMSSQLAgentFailedjobs = "Counter of jobs that failed. This includes Alerts, Scheduled Jobs, and Other jobs." 83 descMSSQLAgentSuccessfuljobs = "Counter of jobs that were successful. This includes Alerts, Scheduled Jobs, and Other jobs." 84 ) 85 86 type Win32_PerfRawData_SQLSERVERAGENT_SQLAgentJobs struct { 87 Activejobs uint64 88 Failedjobs uint64 89 Successfuljobs uint64 90 } 91 92 func instanceAgentWMIQuery(instancename string, wmiquery string) string { 93 var newname = strings.Replace(strings.Replace(instancename, `$`, "", 1), `_`, "", -1) 94 return strings.Replace(wmiquery, `SQLSERVERAGENT_SQLAgent`, newname+`_`+newname, 1) 95 }