github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/utilities/metrics/graphite.go (about)

     1  package metrics
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"log"
     7  	"net"
     8  	"strconv"
     9  	"strings"
    10  	"time"
    11  )
    12  
    13  type GraphiteConfig struct {
    14  	Addr          *net.TCPAddr
    15  	Registry      Registry
    16  	FlushInterval time.Duration
    17  	DurationUnit  time.Duration
    18  	Prefix        string
    19  	Percentiles   []float64
    20  }
    21  
    22  func Graphite(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
    23  	GraphiteWithConfig(GraphiteConfig{
    24  		Addr:          addr,
    25  		Registry:      r,
    26  		FlushInterval: d,
    27  		DurationUnit:  time.Nanosecond,
    28  		Prefix:        prefix,
    29  		Percentiles:   []float64{0.5, 0.75, 0.95, 0.99, 0.999},
    30  	})
    31  }
    32  
    33  func GraphiteWithConfig(c GraphiteConfig) {
    34  
    35  	for range time.Tick(c.FlushInterval) {
    36  		if err := graphite(&c); nil != err {
    37  			log.Println(err)
    38  		}
    39  	}
    40  }
    41  
    42  func GraphiteOnce(c GraphiteConfig) error {
    43  
    44  	return graphite(&c)
    45  }
    46  
    47  func graphite(c *GraphiteConfig) error {
    48  	now := time.Now().Unix()
    49  	du := float64(c.DurationUnit)
    50  	conn, err := net.DialTCP("tcp", nil, c.Addr)
    51  	if nil != err {
    52  		return err
    53  	}
    54  	defer conn.Close()
    55  	w := bufio.NewWriter(conn)
    56  	c.Registry.Each(func(name string, i interface{}) {
    57  		switch metric := i.(type) {
    58  		case Counter:
    59  			fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, metric.Count(), now)
    60  		case Gauge:
    61  			fmt.Fprintf(w, "%s.%s.value %d %d\n", c.Prefix, name, metric.Value(), now)
    62  		case GaugeFloat64:
    63  			fmt.Fprintf(w, "%s.%s.value %f %d\n", c.Prefix, name, metric.Value(), now)
    64  		case Histogram:
    65  			h := metric.Snapshot()
    66  			ps := h.Percentiles(c.Percentiles)
    67  			fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, h.Count(), now)
    68  			fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, h.Min(), now)
    69  			fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, h.Max(), now)
    70  			fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, h.Mean(), now)
    71  			fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, h.StdDev(), now)
    72  			for psIdx, psKey := range c.Percentiles {
    73  				key := strings.Replace(strconv.FormatFloat(psKey*100.0, 'f', -1, 64), ".", "", 1)
    74  				fmt.Fprintf(w, "%s.%s.%s-percentile %.2f %d\n", c.Prefix, name, key, ps[psIdx], now)
    75  			}
    76  		case Meter:
    77  			m := metric.Snapshot()
    78  			fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, m.Count(), now)
    79  			fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, m.Rate1(), now)
    80  			fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, m.Rate5(), now)
    81  			fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, m.Rate15(), now)
    82  			fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, m.RateMean(), now)
    83  		case Timer:
    84  			t := metric.Snapshot()
    85  			ps := t.Percentiles(c.Percentiles)
    86  			fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, t.Count(), now)
    87  			fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, t.Min()/int64(du), now)
    88  			fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, t.Max()/int64(du), now)
    89  			fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, t.Mean()/du, now)
    90  			fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, t.StdDev()/du, now)
    91  			for psIdx, psKey := range c.Percentiles {
    92  				key := strings.Replace(strconv.FormatFloat(psKey*100.0, 'f', -1, 64), ".", "", 1)
    93  				fmt.Fprintf(w, "%s.%s.%s-percentile %.2f %d\n", c.Prefix, name, key, ps[psIdx], now)
    94  			}
    95  			fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, t.Rate1(), now)
    96  			fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, t.Rate5(), now)
    97  			fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, t.Rate15(), now)
    98  			fmt.Fprintf(w, "%s.%s.mean-rate %.2f %d\n", c.Prefix, name, t.RateMean(), now)
    99  		}
   100  		w.Flush()
   101  	})
   102  	return nil
   103  }