github.com/mackerelio/mackerel-agent-plugins@v0.89.3/mackerel-plugin-trafficserver/lib/trafficserver.go (about) 1 package mptrafficserver 2 3 import ( 4 "bytes" 5 "flag" 6 "os/exec" 7 "strconv" 8 "strings" 9 10 mp "github.com/mackerelio/go-mackerel-plugin-helper" 11 ) 12 13 var graphdef = map[string]mp.Graphs{ 14 "trafficserver.cache": { 15 Label: "Trafficserver Cache Hits/Misses", 16 Unit: "integer", 17 Metrics: []mp.Metrics{ 18 {Name: "cache_hits", Label: "Hits", Diff: true, Stacked: true, Type: "uint64"}, 19 {Name: "cache_misses", Label: "Misses", Diff: true, Stacked: true, Type: "uint64"}, 20 }, 21 }, 22 "trafficserver.http_response_codes": { 23 Label: "Trafficserver HTTP Response Codes", 24 Unit: "integer", 25 Metrics: []mp.Metrics{ 26 {Name: "http_2xx", Label: "2xx", Diff: true, Stacked: true, Type: "uint64"}, 27 {Name: "http_3xx", Label: "3xx", Diff: true, Stacked: true, Type: "uint64"}, 28 {Name: "http_4xx", Label: "4xx", Diff: true, Stacked: true, Type: "uint64"}, 29 {Name: "http_5xx", Label: "5xx", Diff: true, Stacked: true, Type: "uint64"}, 30 }, 31 }, 32 "trafficserver.connections": { 33 Label: "Trafficserver Current Connections", 34 Unit: "integer", 35 Metrics: []mp.Metrics{ 36 {Name: "conn_server", Label: "Server"}, 37 {Name: "conn_client", Label: "Client"}, 38 }, 39 }, 40 } 41 42 var metricVarDef = map[string]string{ 43 "cache_hits": "proxy.node.cache_total_hits", 44 "cache_misses": "proxy.node.cache_total_misses", 45 "http_2xx": "proxy.process.http.2xx_responses", 46 "http_3xx": "proxy.process.http.3xx_responses", 47 "http_4xx": "proxy.process.http.4xx_responses", 48 "http_5xx": "proxy.process.http.5xx_responses", 49 "conn_server": "proxy.node.current_server_connections", 50 "conn_client": "proxy.node.current_client_connections", 51 } 52 53 // TrafficserverPlugin mackerel plugin for apache trafficserver 54 type TrafficserverPlugin struct { 55 Tempfile string 56 } 57 58 // FetchMetrics interface for mackerelplugin 59 func (m TrafficserverPlugin) FetchMetrics() (map[string]interface{}, error) { 60 var err error 61 strp, err := getDataWithCommand() 62 if err != nil { 63 return nil, err 64 } 65 66 stat := make(map[string]interface{}) 67 err = parseVars(strp, &stat) 68 if err != nil { 69 return nil, err 70 } 71 72 return stat, nil 73 } 74 75 func parseVars(text *string, statp *map[string]interface{}) error { 76 stat := *statp 77 78 varMetric := make(map[string]string) 79 for metric, varkey := range metricVarDef { 80 varMetric[varkey] = metric 81 } 82 83 lines := strings.Split(*text, "\n") 84 for _, line := range lines { 85 factors := strings.Split(line, " ") 86 varkey := factors[0] 87 88 if metric, present := varMetric[varkey]; present { 89 stat[metric], _ = strconv.ParseUint(factors[1], 10, 64) 90 } 91 } 92 93 return nil 94 } 95 96 func getDataWithCommand() (*string, error) { 97 cmd := exec.Command("traffic_line", "-m", "^proxy") 98 99 var out bytes.Buffer 100 cmd.Stdout = &out 101 err := cmd.Run() 102 if err != nil { 103 return nil, err 104 } 105 106 str := out.String() 107 return &str, nil 108 } 109 110 // GraphDefinition interface for mackerelplugin 111 func (m TrafficserverPlugin) GraphDefinition() map[string]mp.Graphs { 112 return graphdef 113 } 114 115 // Do the plugin 116 func Do() { 117 optTempfile := flag.String("tempfile", "", "Temp file name") 118 flag.Parse() 119 120 var trafficserver TrafficserverPlugin 121 122 helper := mp.NewMackerelPlugin(trafficserver) 123 helper.Tempfile = *optTempfile 124 125 helper.Run() 126 }