github.com/mackerelio/mackerel-agent-plugins@v0.89.3/mackerel-plugin-mssql/lib/mssql_windows.go (about)

     1  //go:build windows
     2  
     3  package mpmssql
     4  
     5  //go:generate wmi2struct -n -p mpmssql -o wmi.go Win32_PerfRawData_MSSQLSQLEXPRESS_MSSQLSQLEXPRESSBufferManager Win32_PerfRawData_MSSQLSQLEXPRESS_MSSQLSQLEXPRESSSQLStatistics Win32_PerfRawData_MSSQLSQLEXPRESS_MSSQLSQLEXPRESSGeneralStatistics Win32_PerfRawData_MSSQLSQLEXPRESS_MSSQLSQLEXPRESSAccessMethods
     6  
     7  import (
     8  	"flag"
     9  	"os"
    10  	"strings"
    11  
    12  	"golang.org/x/text/cases"
    13  	"golang.org/x/text/language"
    14  
    15  	mp "github.com/mackerelio/go-mackerel-plugin"
    16  	"github.com/yusufpapurcu/wmi"
    17  )
    18  
    19  // MSSQLPlugin store the name of servers
    20  type MSSQLPlugin struct {
    21  	prefix   string
    22  	instance string
    23  }
    24  
    25  // MetricKeyPrefix retruns the metrics key prefix
    26  func (m MSSQLPlugin) MetricKeyPrefix() string {
    27  	if m.prefix == "" {
    28  		m.prefix = "mssql"
    29  	}
    30  	return m.prefix
    31  }
    32  
    33  func (m MSSQLPlugin) name(n string) string {
    34  	if m.instance == "SQLSERVER" {
    35  		return "Win32_PerfRawData_MSSQLSERVER_SQLServer" + n
    36  	} else {
    37  		return "Win32_PerfRawData_MSSQLSQLEXPRESS_MSSQLSQLEXPRESS" + n
    38  	}
    39  }
    40  
    41  // FetchMetrics interface for mackerelplugin
    42  func (m MSSQLPlugin) FetchMetrics() (map[string]float64, error) {
    43  	var bufferManager []Win32_PerfRawData_MSSQLSQLEXPRESS_MSSQLSQLEXPRESSBufferManager
    44  	var sqlStatistics []Win32_PerfRawData_MSSQLSQLEXPRESS_MSSQLSQLEXPRESSSQLStatistics
    45  	var generalStatistics []Win32_PerfRawData_MSSQLSQLEXPRESS_MSSQLSQLEXPRESSGeneralStatistics
    46  	var accessMethods []Win32_PerfRawData_MSSQLSQLEXPRESS_MSSQLSQLEXPRESSAccessMethods
    47  
    48  	var err error
    49  	err = wmi.Query("select * from "+m.name("BufferManager"), &bufferManager)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	err = wmi.Query("select * from "+m.name("SQLStatistics"), &sqlStatistics)
    54  	if err != nil {
    55  		return nil, err
    56  	}
    57  	err = wmi.Query("select * from "+m.name("GeneralStatistics"), &generalStatistics)
    58  	if err != nil {
    59  		return nil, err
    60  	}
    61  	err = wmi.Query("select * from "+m.name("AccessMethods"), &accessMethods)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	stat := make(map[string]float64)
    67  	stat["buffer_cache_hit_ratio"] = float64(bufferManager[0].Buffercachehitratio)
    68  	stat["buffer_page_life_expectancy"] = float64(bufferManager[0].Pagelifeexpectancy)
    69  	stat["buffer_checkpoint_pages"] = float64(bufferManager[0].CheckpointpagesPersec)
    70  	stat["stats_batch_requests"] = float64(sqlStatistics[0].BatchRequestsPersec)
    71  	stat["stats_sql_compilations"] = float64(sqlStatistics[0].SQLCompilationsPersec)
    72  	stat["stats_sql_recompilations"] = float64(sqlStatistics[0].SQLReCompilationsPersec)
    73  	stat["stats_connections"] = float64(generalStatistics[0].UserConnections)
    74  	stat["stats_lock_waits"] = float64(generalStatistics[0].SQLTraceIOProviderLockWaits)
    75  	stat["stats_procs_blocked"] = float64(generalStatistics[0].Processesblocked)
    76  	stat["access_page_splits"] = float64(accessMethods[0].PageSplitsPersec)
    77  	return stat, nil
    78  }
    79  
    80  // GraphDefinition interface for mackerelplugin
    81  func (m MSSQLPlugin) GraphDefinition() map[string](mp.Graphs) {
    82  	labelPrefix := cases.Title(language.Und, cases.NoLower).String(strings.ReplaceAll(m.MetricKeyPrefix(), "mssql", "MSSQL"))
    83  	return map[string](mp.Graphs){
    84  		"buffer": mp.Graphs{
    85  			Label: labelPrefix + " Buffer",
    86  			Unit:  mp.UnitInteger,
    87  			Metrics: []mp.Metrics{
    88  				{
    89  					Name:    "buffer_cache_hit_ratio",
    90  					Label:   "Cache Hit Ratio",
    91  					Diff:    false,
    92  					Stacked: true,
    93  				},
    94  				{
    95  					Name:    "buffer_page_life_expectancy",
    96  					Label:   "Page Life Expectancy",
    97  					Diff:    true,
    98  					Stacked: true,
    99  				},
   100  				{
   101  					Name:    "buffer_checkpoint_pages",
   102  					Label:   "Checkpoint Pages",
   103  					Diff:    false,
   104  					Stacked: true,
   105  				},
   106  			},
   107  		},
   108  		"stats": mp.Graphs{
   109  			Label: labelPrefix + " Stats",
   110  			Unit:  mp.UnitInteger,
   111  			Metrics: []mp.Metrics{
   112  				{
   113  					Name:    "stats_batch_requests",
   114  					Label:   "Batch Requests",
   115  					Diff:    true,
   116  					Stacked: true,
   117  				},
   118  				{
   119  					Name:    "stats_sql_compilations",
   120  					Label:   "SQL Compilations",
   121  					Diff:    true,
   122  					Stacked: true,
   123  				},
   124  				{
   125  					Name:    "stats_sql_recompilations",
   126  					Label:   "SQL Re-Compilations",
   127  					Diff:    true,
   128  					Stacked: true,
   129  				},
   130  				{
   131  					Name:    "stats_connections",
   132  					Label:   "Connections",
   133  					Diff:    false,
   134  					Stacked: true,
   135  				},
   136  				{
   137  					Name:    "stats_lock_waits",
   138  					Label:   "Lock Waits",
   139  					Diff:    false,
   140  					Stacked: true,
   141  				},
   142  				{
   143  					Name:    "stats_procs_blocked",
   144  					Label:   "Procs Blocked",
   145  					Diff:    false,
   146  					Stacked: true,
   147  				},
   148  			},
   149  		},
   150  		"access": mp.Graphs{
   151  			Label: labelPrefix + " Access",
   152  			Unit:  mp.UnitInteger,
   153  			Metrics: []mp.Metrics{
   154  				{
   155  					Name:    "access_page_splits",
   156  					Label:   "Page Splits",
   157  					Diff:    true,
   158  					Stacked: true,
   159  				},
   160  			},
   161  		},
   162  	}
   163  }
   164  
   165  // Do the plugin
   166  func Do() {
   167  	optPrefix := flag.String("metric-key-prefix", "mssql", "Metric key prefix")
   168  	optInstance := flag.String("instance", "SQLSERVER", "Instance name of MSSQL(SQLSERVER or SQLEXPRESS)")
   169  	optTempfile := flag.String("tempfile", "", "Temp file name")
   170  	flag.Parse()
   171  
   172  	instance := strings.ToUpper(*optInstance)
   173  	if instance != "SQLSERVER" && instance != "SQLEXPRESS" {
   174  		flag.Usage()
   175  		os.Exit(2)
   176  	}
   177  	plugin := MSSQLPlugin{
   178  		prefix:   *optPrefix,
   179  		instance: instance,
   180  	}
   181  	helper := mp.NewMackerelPlugin(plugin)
   182  	helper.Tempfile = *optTempfile
   183  	helper.Run()
   184  }