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  }