gitlab.com/aquachain/aquachain@v1.17.16-rc3.0.20221018032414-e3ddf1e1c055/common/metrics/graphite.go (about)

     1  // Copyright 2018 The aquachain Authors
     2  // This file is part of the aquachain library.
     3  //
     4  // The aquachain library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The aquachain library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the aquachain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package metrics
    18  
    19  import (
    20  	"bufio"
    21  	"fmt"
    22  	"log"
    23  	"net"
    24  	"strconv"
    25  	"strings"
    26  	"time"
    27  )
    28  
    29  // GraphiteConfig provides a container with configuration parameters for
    30  // the Graphite exporter
    31  type GraphiteConfig struct {
    32  	Addr          *net.TCPAddr  // Network address to connect to
    33  	Registry      Registry      // Registry to be exported
    34  	FlushInterval time.Duration // Flush interval
    35  	DurationUnit  time.Duration // Time conversion unit for durations
    36  	Prefix        string        // Prefix to be prepended to metric names
    37  	Percentiles   []float64     // Percentiles to export from timers and histograms
    38  }
    39  
    40  // Graphite is a blocking exporter function which reports metrics in r
    41  // to a graphite server located at addr, flushing them every d duration
    42  // and prepending metric names with prefix.
    43  func Graphite(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
    44  	GraphiteWithConfig(GraphiteConfig{
    45  		Addr:          addr,
    46  		Registry:      r,
    47  		FlushInterval: d,
    48  		DurationUnit:  time.Nanosecond,
    49  		Prefix:        prefix,
    50  		Percentiles:   []float64{0.5, 0.75, 0.95, 0.99, 0.999},
    51  	})
    52  }
    53  
    54  // GraphiteWithConfig is a blocking exporter function just like Graphite,
    55  // but it takes a GraphiteConfig instead.
    56  func GraphiteWithConfig(c GraphiteConfig) {
    57  	log.Printf("WARNING: This go-metrics client has been DEPRECATED! It has been moved to https://github.com/cyberdelia/go-metrics-graphite and will be removed from rcrowley/go-metrics on August 12th 2015")
    58  	for range time.Tick(c.FlushInterval) {
    59  		if err := graphite(&c); nil != err {
    60  			log.Println(err)
    61  		}
    62  	}
    63  }
    64  
    65  // GraphiteOnce performs a single submission to Graphite, returning a
    66  // non-nil error on failed connections. This can be used in a loop
    67  // similar to GraphiteWithConfig for custom error handling.
    68  func GraphiteOnce(c GraphiteConfig) error {
    69  	log.Printf("WARNING: This go-metrics client has been DEPRECATED! It has been moved to https://github.com/cyberdelia/go-metrics-graphite and will be removed from rcrowley/go-metrics on August 12th 2015")
    70  	return graphite(&c)
    71  }
    72  
    73  func graphite(c *GraphiteConfig) error {
    74  	now := time.Now().Unix()
    75  	du := float64(c.DurationUnit)
    76  	conn, err := net.DialTCP("tcp", nil, c.Addr)
    77  	if nil != err {
    78  		return err
    79  	}
    80  	defer conn.Close()
    81  	w := bufio.NewWriter(conn)
    82  	c.Registry.Each(func(name string, i interface{}) {
    83  		switch metric := i.(type) {
    84  		case Counter:
    85  			fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, metric.Count(), now)
    86  		case Gauge:
    87  			fmt.Fprintf(w, "%s.%s.value %d %d\n", c.Prefix, name, metric.Value(), now)
    88  		case GaugeFloat64:
    89  			fmt.Fprintf(w, "%s.%s.value %f %d\n", c.Prefix, name, metric.Value(), now)
    90  		case Histogram:
    91  			h := metric.Snapshot()
    92  			ps := h.Percentiles(c.Percentiles)
    93  			fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, h.Count(), now)
    94  			fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, h.Min(), now)
    95  			fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, h.Max(), now)
    96  			fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, h.Mean(), now)
    97  			fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, h.StdDev(), now)
    98  			for psIdx, psKey := range c.Percentiles {
    99  				key := strings.Replace(strconv.FormatFloat(psKey*100.0, 'f', -1, 64), ".", "", 1)
   100  				fmt.Fprintf(w, "%s.%s.%s-percentile %.2f %d\n", c.Prefix, name, key, ps[psIdx], now)
   101  			}
   102  		case Meter:
   103  			m := metric.Snapshot()
   104  			fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, m.Count(), now)
   105  			fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, m.Rate1(), now)
   106  			fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, m.Rate5(), now)
   107  			fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, m.Rate15(), now)
   108  			fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, m.RateMean(), now)
   109  		case Timer:
   110  			t := metric.Snapshot()
   111  			ps := t.Percentiles(c.Percentiles)
   112  			fmt.Fprintf(w, "%s.%s.count %d %d\n", c.Prefix, name, t.Count(), now)
   113  			fmt.Fprintf(w, "%s.%s.min %d %d\n", c.Prefix, name, t.Min()/int64(du), now)
   114  			fmt.Fprintf(w, "%s.%s.max %d %d\n", c.Prefix, name, t.Max()/int64(du), now)
   115  			fmt.Fprintf(w, "%s.%s.mean %.2f %d\n", c.Prefix, name, t.Mean()/du, now)
   116  			fmt.Fprintf(w, "%s.%s.std-dev %.2f %d\n", c.Prefix, name, t.StdDev()/du, now)
   117  			for psIdx, psKey := range c.Percentiles {
   118  				key := strings.Replace(strconv.FormatFloat(psKey*100.0, 'f', -1, 64), ".", "", 1)
   119  				fmt.Fprintf(w, "%s.%s.%s-percentile %.2f %d\n", c.Prefix, name, key, ps[psIdx], now)
   120  			}
   121  			fmt.Fprintf(w, "%s.%s.one-minute %.2f %d\n", c.Prefix, name, t.Rate1(), now)
   122  			fmt.Fprintf(w, "%s.%s.five-minute %.2f %d\n", c.Prefix, name, t.Rate5(), now)
   123  			fmt.Fprintf(w, "%s.%s.fifteen-minute %.2f %d\n", c.Prefix, name, t.Rate15(), now)
   124  			fmt.Fprintf(w, "%s.%s.mean-rate %.2f %d\n", c.Prefix, name, t.RateMean(), now)
   125  		}
   126  		w.Flush()
   127  	})
   128  	return nil
   129  }