github.com/mackerelio/mackerel-agent-plugins@v0.89.3/mackerel-plugin-squid/lib/squid.go (about) 1 package mpsquid 2 3 import ( 4 "bufio" 5 "flag" 6 "fmt" 7 "io" 8 "net" 9 "regexp" 10 "strconv" 11 12 mp "github.com/mackerelio/go-mackerel-plugin-helper" 13 ) 14 15 var graphdef = map[string]mp.Graphs{ 16 "squid.requests": { 17 Label: "Squid Client Requests", 18 Unit: "integer", 19 Metrics: []mp.Metrics{ 20 {Name: "requests", Label: "Requests", Diff: true}, 21 }, 22 }, 23 "squid.cache_hit_ratio.5min": { 24 Label: "Squid Client Cache Hit Ratio (5min)", 25 Unit: "percentage", 26 Metrics: []mp.Metrics{ 27 {Name: "request_ratio", Label: "Request Ratio", Diff: false}, 28 {Name: "byte_ratio", Label: "Byte Ratio", Diff: false}, 29 }, 30 }, 31 "squid.cpu_usage_ratio.5min": { 32 Label: "Squid CPU Usage Ratio (5min)", 33 Unit: "percentage", 34 Metrics: []mp.Metrics{ 35 {Name: "cpu_usage", Label: "CPU Usage Ratio", Diff: false}, 36 }, 37 }, 38 "squid.cache_storage_usage": { 39 Label: "Squid Cache Storage Usage", 40 Unit: "percentage", 41 Metrics: []mp.Metrics{ 42 {Name: "swap_used_ratio", Label: "Swap capacity (used)", Diff: false}, 43 {Name: "memory_used_ratio", Label: "Memory capacity (used)", Diff: false}, 44 }, 45 }, 46 "squid.file_descriptor_usage": { 47 Label: "Squid File descriptor usage", 48 Unit: "integer", 49 Metrics: []mp.Metrics{ 50 {Name: "total_fd", Label: "Maximum number of file descriptors", Diff: false}, 51 {Name: "max_fd", Label: "Largest file desc currently in use", Diff: false}, 52 {Name: "current_fd", Label: "Number of file desc currently in use", Diff: false}, 53 {Name: "avail_fd", Label: "Available number of file descriptors", Diff: false}, 54 {Name: "reserved_fd", Label: "Reserved number of file descriptors", Diff: false}, 55 {Name: "open_files", Label: "Store Disk files open", Diff: false}, 56 {Name: "queued_files", Label: "Files queued for open", Diff: false}, 57 }, 58 }, 59 "squid.memory_account_for": { 60 Label: "Squid Memory accounted for", 61 Unit: "integer", 62 Metrics: []mp.Metrics{ 63 {Name: "memory_poll_alloc", Label: "memPoolAlloc calls", Diff: true}, 64 {Name: "memory_poll_free", Label: "memPoolFree calls", Diff: true}, 65 }, 66 }, 67 } 68 69 // SquidPlugin mackerel plugin for squid 70 type SquidPlugin struct { 71 Target string 72 Tempfile string 73 } 74 75 // FetchMetrics interface for mackerelplugin 76 func (m SquidPlugin) FetchMetrics() (map[string]interface{}, error) { 77 conn, err := net.Dial("tcp", m.Target) 78 if err != nil { 79 return nil, err 80 } 81 fmt.Fprintln(conn, "GET cache_object://"+m.Target+"/info HTTP/1.0\n\n") 82 return m.ParseMgrInfo(conn) 83 } 84 85 // ParseMgrInfo parser for squid mgr:info 86 func (m SquidPlugin) ParseMgrInfo(info io.Reader) (map[string]interface{}, error) { 87 // https://wiki.squid-cache.org/Features/CacheManager/Info?highlight=%28Feature..Squid.Cache.Manager%29 88 scanner := bufio.NewScanner(info) 89 90 stat := make(map[string]interface{}) 91 //regexpmap := make(map[string]*regexp.Regexp) 92 regexpmap := map[*regexp.Regexp]string{ 93 regexp.MustCompile("Number of HTTP requests received:\t([0-9]+)"): "requests", 94 // version 2 95 regexp.MustCompile("Request Hit Ratios:\t5min: ([0-9\\.]+)%"): "request_ratio", 96 regexp.MustCompile("Byte Hit Ratios:\t5min: ([0-9\\.]+)%"): "byte_ratio", 97 // version 3 98 regexp.MustCompile("Hits as % of all requests:\t5min: ([0-9\\.]+)%"): "request_ratio", 99 regexp.MustCompile("Hits as % of bytes sent:\t5min: ([0-9\\.]+)%"): "byte_ratio", 100 regexp.MustCompile("CPU Usage, 5 minute avg:\t([0-9\\.]+)%"): "cpu_usage", 101 regexp.MustCompile("Storage Swap capacity:[\t ]+([0-9\\.]+)% used"): "swap_used_ratio", 102 regexp.MustCompile("Storage Mem capacity:[\t ]+([0-9\\.]+)% used"): "memory_used_ratio", 103 regexp.MustCompile("Maximum number of file descriptors:[\t ]+([0-9]+)"): "total_fd", 104 regexp.MustCompile("Largest file desc currently in use:[\t ]+([0-9]+)"): "max_fd", 105 regexp.MustCompile("Number of file desc currently in use:[\t ]+([0-9]+)"): "current_fd", 106 regexp.MustCompile("Available number of file descriptors:[\t ]+([0-9]+)"): "avail_fd", 107 regexp.MustCompile("Reserved number of file descriptors:[\t ]+([0-9]+)"): "reserved_fd", 108 regexp.MustCompile("Store Disk files open:[\t ]+([0-9]+)"): "open_files", 109 regexp.MustCompile("Files queued for open:[\t ]+([0-9]+)"): "queued_files", 110 regexp.MustCompile("memPoolAlloc calls:[\t ]+([0-9]+)"): "memory_poll_alloc", 111 regexp.MustCompile("memPoolFree calls:[\t ]+([0-9]+)"): "memory_poll_free", 112 } 113 114 for scanner.Scan() { 115 line := scanner.Text() 116 s := string(line) 117 118 for rexp, key := range regexpmap { 119 match := rexp.FindStringSubmatch(s) 120 if match == nil { 121 continue 122 } 123 124 v, err := strconv.ParseFloat(match[1], 64) 125 if err != nil { 126 return nil, err 127 } 128 stat[key] = v 129 130 break 131 } 132 } 133 134 return stat, nil 135 } 136 137 // GraphDefinition interface for mackerelplugin 138 func (m SquidPlugin) GraphDefinition() map[string]mp.Graphs { 139 return graphdef 140 } 141 142 // Do the plugin 143 func Do() { 144 optHost := flag.String("host", "localhost", "Hostname") 145 optPort := flag.String("port", "3128", "Port") 146 optTempfile := flag.String("tempfile", "", "Temp file name") 147 flag.Parse() 148 149 var squid SquidPlugin 150 squid.Target = fmt.Sprintf("%s:%s", *optHost, *optPort) 151 helper := mp.NewMackerelPlugin(squid) 152 helper.Tempfile = *optTempfile 153 154 helper.Run() 155 }