github.com/mackerelio/mackerel-agent-plugins@v0.89.3/mackerel-plugin-varnish/lib/varnish.go (about)

     1  package mpvarnish
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os/exec"
     7  	"regexp"
     8  	"strconv"
     9  	"strings"
    10  
    11  	mp "github.com/mackerelio/go-mackerel-plugin-helper"
    12  )
    13  
    14  var graphdef = map[string]mp.Graphs{
    15  	"varnish.requests": {
    16  		Label: "Varnish Client Requests",
    17  		Unit:  "integer",
    18  		Metrics: []mp.Metrics{
    19  			{Name: "requests", Label: "Requests", Diff: true},
    20  			{Name: "cache_hits", Label: "Hits", Diff: true},
    21  		},
    22  	},
    23  	"varnish.backend": {
    24  		Label: "Varnish Backend",
    25  		Unit:  "integer",
    26  		Metrics: []mp.Metrics{
    27  			{Name: "backend_req", Label: "Requests", Diff: true},
    28  			{Name: "backend_conn", Label: "Conn success", Diff: true},
    29  			{Name: "backend_fail", Label: "Conn fail", Diff: true},
    30  			{Name: "backend_reuse", Label: "Conn reuse", Diff: true},
    31  			{Name: "backend_recycle", Label: "Conn recycle", Diff: true},
    32  		},
    33  	},
    34  	"varnish.objects": {
    35  		Label: "Varnish Objects",
    36  		Unit:  "integer",
    37  		Metrics: []mp.Metrics{
    38  			{Name: "n_object", Label: "object", Diff: false},
    39  			{Name: "n_objectcore", Label: "objectcore", Diff: false},
    40  			{Name: "n_objecthead", Label: "objecthead", Diff: false},
    41  		},
    42  	},
    43  	"varnish.objects_expire": {
    44  		Label: "Varnish Objects Expire",
    45  		Unit:  "integer",
    46  		Metrics: []mp.Metrics{
    47  			{Name: "n_expired", Label: "expire", Diff: true},
    48  		},
    49  	},
    50  	"varnish.busy_requests": {
    51  		Label: "Varnish Busy Requests",
    52  		Unit:  "integer",
    53  		Metrics: []mp.Metrics{
    54  			{Name: "busy_sleep", Label: "sleep", Diff: true},
    55  			{Name: "busy_wakeup", Label: "wakeup", Diff: true},
    56  		},
    57  	},
    58  	"varnish.sma.g_alloc.#": {
    59  		Label: "Varnish SMA Allocations",
    60  		Unit:  "integer",
    61  		Metrics: []mp.Metrics{
    62  			{Name: "g_alloc", Label: "num", Diff: false},
    63  		},
    64  	},
    65  	"varnish.sma.memory.#": {
    66  		Label: "Varnish SMA Memory",
    67  		Unit:  "integer",
    68  		Metrics: []mp.Metrics{
    69  			{Name: "allocated", Label: "Allocated", Diff: false},
    70  			{Name: "available", Label: "Available", Diff: false},
    71  		},
    72  	},
    73  }
    74  
    75  // VarnishPlugin mackerel plugin for varnish
    76  type VarnishPlugin struct {
    77  	VarnishStatPath string
    78  	VarnishName     string
    79  	Tempfile        string
    80  }
    81  
    82  // FetchMetrics interface for mackerelplugin
    83  func (m VarnishPlugin) FetchMetrics() (map[string]interface{}, error) {
    84  	var out []byte
    85  	var err error
    86  
    87  	if m.VarnishName == "" {
    88  		out, err = exec.Command(m.VarnishStatPath, "-1").CombinedOutput()
    89  	} else {
    90  		out, err = exec.Command(m.VarnishStatPath, "-1", "-n", m.VarnishName).CombinedOutput()
    91  	}
    92  	if err != nil {
    93  		return nil, fmt.Errorf("%s: %s", err, out)
    94  	}
    95  
    96  	lineexp := regexp.MustCompile(`^([^ ]+) +(\d+)`)
    97  	smaexp := regexp.MustCompile(`^SMA\.([^\.]+)\.(.+)$`)
    98  
    99  	stat := map[string]interface{}{
   100  		"requests": float64(0),
   101  	}
   102  
   103  	var tmpv float64
   104  	for _, line := range strings.Split(string(out), "\n") {
   105  		match := lineexp.FindStringSubmatch(line)
   106  		if match == nil {
   107  			continue
   108  		}
   109  
   110  		tmpv, err = strconv.ParseFloat(match[2], 64)
   111  		if err != nil {
   112  			continue
   113  		}
   114  
   115  		switch match[1] {
   116  		case "cache_hit", "MAIN.cache_hit":
   117  			stat["cache_hits"] = tmpv
   118  			stat["requests"] = stat["requests"].(float64) + tmpv
   119  		case "cache_miss", "MAIN.cache_miss":
   120  			stat["requests"] = stat["requests"].(float64) + tmpv
   121  		case "cache_hitpass", "MAIN.cache_hitpass":
   122  			stat["requests"] = stat["requests"].(float64) + tmpv
   123  		case "MAIN.backend_req":
   124  			stat["backend_req"] = tmpv
   125  		case "MAIN.backend_conn":
   126  			stat["backend_conn"] = tmpv
   127  		case "MAIN.backend_fail":
   128  			stat["backend_fail"] = tmpv
   129  		case "MAIN.backend_reuse":
   130  			stat["backend_reuse"] = tmpv
   131  		case "MAIN.backend_recycle":
   132  			stat["backend_recycle"] = tmpv
   133  		case "MAIN.n_object":
   134  			stat["n_object"] = tmpv
   135  		case "MAIN.n_objectcore":
   136  			stat["n_objectcore"] = tmpv
   137  		case "MAIN.n_expired":
   138  			stat["n_expired"] = tmpv
   139  		case "MAIN.n_objecthead":
   140  			stat["n_objecthead"] = tmpv
   141  		case "MAIN.busy_sleep":
   142  			stat["busy_sleep"] = tmpv
   143  		case "MAIN.busy_wakeup":
   144  			stat["busy_wakeup"] = tmpv
   145  		default:
   146  			smamatch := smaexp.FindStringSubmatch(match[1])
   147  			if smamatch == nil {
   148  				continue
   149  			}
   150  			switch smamatch[2] {
   151  			case "g_alloc":
   152  				stat["varnish.sma.g_alloc."+smamatch[1]+".g_alloc"] = tmpv
   153  			case "g_bytes":
   154  				stat["varnish.sma.memory."+smamatch[1]+".allocated"] = tmpv
   155  			case "g_space":
   156  				stat["varnish.sma.memory."+smamatch[1]+".available"] = tmpv
   157  			}
   158  		}
   159  	}
   160  
   161  	return stat, err
   162  }
   163  
   164  // GraphDefinition interface for mackerelplugin
   165  func (m VarnishPlugin) GraphDefinition() map[string]mp.Graphs {
   166  	return graphdef
   167  }
   168  
   169  // Do the plugin
   170  func Do() {
   171  	optVarnishStatPath := flag.String("varnishstat", "/usr/bin/varnishstat", "Path of varnishstat")
   172  	optVarnishName := flag.String("varnish-name", "", "Varnish name")
   173  	optTempfile := flag.String("tempfile", "", "Temp file name")
   174  	flag.Parse()
   175  
   176  	var varnish VarnishPlugin
   177  	varnish.VarnishStatPath = *optVarnishStatPath
   178  	varnish.VarnishName = *optVarnishName
   179  	helper := mp.NewMackerelPlugin(varnish)
   180  
   181  	if *optTempfile != "" {
   182  		helper.Tempfile = *optTempfile
   183  	}
   184  
   185  	helper.Run()
   186  }