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  }