github.com/mackerelio/mackerel-agent-plugins@v0.89.3/mackerel-plugin-unicorn/lib/unicorn.go (about) 1 package mpunicorn 2 3 import ( 4 "flag" 5 "fmt" 6 "os" 7 "strings" 8 9 mp "github.com/mackerelio/go-mackerel-plugin-helper" 10 "github.com/mackerelio/golib/logging" 11 "golang.org/x/text/cases" 12 "golang.org/x/text/language" 13 ) 14 15 var logger = logging.GetLogger("metrics.plugin.unicorn") 16 17 // UnicornPlugin mackerel plugin for Unicorn 18 type UnicornPlugin struct { 19 MasterPid string 20 WorkerPids []string 21 Tempfile string 22 Prefix string 23 } 24 25 // FetchMetrics interface for mackerelplugin 26 func (u UnicornPlugin) FetchMetrics() (map[string]interface{}, error) { 27 stat := make(map[string]interface{}) 28 29 workers := len(u.WorkerPids) 30 idles, err := idleWorkerCount(u.WorkerPids) 31 if err != nil { 32 return stat, err 33 } 34 stat["idle_workers"] = fmt.Sprint(idles) 35 stat["busy_workers"] = fmt.Sprint(workers - idles) 36 37 workersM, err := workersMemory() 38 if err != nil { 39 return stat, err 40 } 41 stat["memory_workers"] = workersM 42 43 masterM, err := masterMemory() 44 if err != nil { 45 return stat, err 46 } 47 stat["memory_master"] = masterM 48 49 averageM, err := workersMemoryAvg() 50 if err != nil { 51 return stat, err 52 } 53 stat["memory_workeravg"] = averageM 54 55 return stat, nil 56 } 57 58 // MetricKeyPrefix interface for PluginWithPrefix 59 func (u UnicornPlugin) MetricKeyPrefix() string { 60 if u.Prefix == "" { 61 u.Prefix = "unicorn" 62 } 63 return u.Prefix 64 } 65 66 // GraphDefinition interface for mackerelplugin 67 func (u UnicornPlugin) GraphDefinition() map[string]mp.Graphs { 68 labelPrefix := cases.Title(language.Und, cases.NoLower).String(u.MetricKeyPrefix()) 69 var graphdef = map[string]mp.Graphs{ 70 "memory": { 71 Label: (labelPrefix + " Memory"), 72 Unit: "bytes", 73 Metrics: []mp.Metrics{ 74 {Name: "memory_workers", Label: "Workers", Diff: false, Stacked: true}, 75 {Name: "memory_master", Label: "Master", Diff: false, Stacked: true}, 76 {Name: "memory_workeravg", Label: "Worker Average", Diff: false, Stacked: false}, 77 }, 78 }, 79 "workers": { 80 Label: (labelPrefix + " Workers"), 81 Unit: "integer", 82 Metrics: []mp.Metrics{ 83 {Name: "busy_workers", Label: "Busy Workers", Diff: false, Stacked: true}, 84 {Name: "idle_workers", Label: "Idle Workers", Diff: false, Stacked: true}, 85 }, 86 }, 87 } 88 89 return graphdef 90 } 91 92 // Do the plugin 93 func Do() { 94 optPidFile := flag.String("pidfile", "", "Pid file name") 95 optTempfile := flag.String("tempfile", "", "Temp file name") 96 optPrefix := flag.String("metric-key-prefix", "unicorn", "Prefix") 97 flag.Parse() 98 var unicorn UnicornPlugin 99 100 command = RealCommand{} 101 pipedCommands = RealPipedCommands{} 102 103 if *optPidFile == "" { 104 logger.Errorf("Required unicorn pidfile.") 105 os.Exit(1) 106 } else { 107 pid, err := os.ReadFile(*optPidFile) 108 if err != nil { 109 logger.Errorf("Failed to load unicorn pid file. %s", err) 110 os.Exit(1) 111 } 112 unicorn.MasterPid = strings.Replace(string(pid), "\n", "", 1) 113 } 114 115 workerPids, err := fetchUnicornWorkerPids(unicorn.MasterPid) 116 if err != nil { 117 logger.Errorf("Failed to fetch unicorn worker pids. %s", err) 118 os.Exit(1) 119 } 120 unicorn.WorkerPids = workerPids 121 122 unicorn.Prefix = *optPrefix 123 124 helper := mp.NewMackerelPlugin(unicorn) 125 helper.Tempfile = *optTempfile 126 127 helper.Run() 128 }