github.com/mackerelio/mackerel-agent-plugins@v0.89.3/mackerel-plugin-windows-process-stats/lib/process-stats_windows.go (about) 1 //go:build windows 2 3 package mpwindowsprocessstats 4 5 import ( 6 "flag" 7 "fmt" 8 "os" 9 "regexp" 10 "sort" 11 "strconv" 12 13 mp "github.com/mackerelio/go-mackerel-plugin-helper" 14 "github.com/mackerelio/golib/logging" 15 "github.com/yusufpapurcu/wmi" 16 ) 17 18 var logger = logging.GetLogger("metrics.plugin.windows-process-stats") 19 20 type Win32_PerfFormattedData_PerfProc_Process struct { 21 ElapsedTime uint64 22 Name string 23 IDProcess uint32 24 PercentProcessorTime uint64 25 WorkingSet uint64 26 } 27 28 type WindowsProcessStatsPlugin struct { 29 Process string 30 Prefix string 31 } 32 33 func getProcesses(processName string) ([]Win32_PerfFormattedData_PerfProc_Process, error) { 34 var procs []Win32_PerfFormattedData_PerfProc_Process 35 36 q := wmi.CreateQuery(&procs, "WHERE (Name like '"+processName+"' OR Name like '"+processName+"#%')") 37 if err := wmi.Query(q, &procs); err != nil { 38 return procs, err 39 } 40 41 sort.Slice(procs, func(i, j int) bool { 42 return procs[i].IDProcess < procs[j].IDProcess 43 }) 44 return procs, nil 45 } 46 47 // FetchMetrics interface for mackerelplugin 48 func (m WindowsProcessStatsPlugin) FetchMetrics() (map[string]interface{}, error) { 49 procs, err := getProcesses(m.Process) 50 if err != nil { 51 return nil, err 52 } 53 stat := make(map[string]interface{}) 54 var re = regexp.MustCompile(`#[0-9]+$`) 55 for k, v := range procs { 56 processName := re.ReplaceAllString(v.Name, "") + "_" + strconv.Itoa(k) 57 metricNameCPU := "cpu." + processName + ".percent_processor_time" 58 metricNameMemory := "memory." + processName + ".working_set" 59 stat[metricNameCPU] = v.PercentProcessorTime 60 stat[metricNameMemory] = v.WorkingSet 61 } 62 63 return stat, nil 64 } 65 66 // GraphDefinition interface for mackerelplugin 67 func (m WindowsProcessStatsPlugin) GraphDefinition() map[string](mp.Graphs) { 68 prefix := m.Prefix 69 return map[string](mp.Graphs){ 70 "cpu.#": mp.Graphs{ 71 Label: fmt.Sprintf("%s Windows Process Stats CPU", prefix), 72 Unit: "percentage", 73 Metrics: []mp.Metrics{ 74 {Name: "percent_processor_time", Label: "cpu", Diff: false, Stacked: false}, 75 }, 76 }, 77 "memory.#": mp.Graphs{ 78 Label: fmt.Sprintf("%s Windows Process Stats Memory", prefix), 79 Unit: "bytes", 80 Metrics: []mp.Metrics{ 81 {Name: "working_set", Label: "memory", Diff: false, Stacked: false}, 82 }, 83 }, 84 } 85 } 86 87 // MetricKeyPrefix interface for mackerelplugin 88 func (m WindowsProcessStatsPlugin) MetricKeyPrefix() string { 89 if m.Prefix == "" { 90 return "windows-process-stats-" + m.Process 91 } 92 return m.Prefix 93 } 94 95 // Do the plugin 96 func Do() { 97 optProcess := flag.String("process", "", "Process name") 98 optMetricKeyPrefix := flag.String("metric-key-prefix", "", "Metric Key Prefix") 99 optTempfile := flag.String("tempfile", "", "Temp file name") 100 flag.Parse() 101 102 if *optProcess == "" { 103 logger.Warningf("Process name is required") 104 flag.PrintDefaults() 105 os.Exit(1) 106 } 107 108 var plugin WindowsProcessStatsPlugin 109 plugin.Process = *optProcess 110 plugin.Prefix = *optMetricKeyPrefix 111 112 helper := mp.NewMackerelPlugin(plugin) 113 helper.Tempfile = *optTempfile 114 helper.Run() 115 }