github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/metrics/opentsdb.go (about)

     1  package metrics
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"log"
     7  	"net"
     8  	"os"
     9  	"strings"
    10  	"time"
    11  )
    12  
    13  var shortHostName = ""
    14  
    15  // OpenTSDBConfig provides a container with configuration parameters for
    16  // the OpenTSDB exporter
    17  type OpenTSDBConfig struct {
    18  	Addr          *net.TCPAddr  // Network address to connect to
    19  	Registry      Registry      // Registry to be exported
    20  	FlushInterval time.Duration // Flush interval
    21  	DurationUnit  time.Duration // Time conversion unit for durations
    22  	Prefix        string        // Prefix to be prepended to metric names
    23  }
    24  
    25  // OpenTSDB is a blocking exporter function which reports metrics in r
    26  // to a TSDB server located at addr, flushing them every d duration
    27  // and prepending metric names with prefix.
    28  func OpenTSDB(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
    29  	OpenTSDBWithConfig(OpenTSDBConfig{
    30  		Addr:          addr,
    31  		Registry:      r,
    32  		FlushInterval: d,
    33  		DurationUnit:  time.Nanosecond,
    34  		Prefix:        prefix,
    35  	})
    36  }
    37  
    38  // OpenTSDBWithConfig is a blocking exporter function just like OpenTSDB,
    39  // but it takes a OpenTSDBConfig instead.
    40  func OpenTSDBWithConfig(c OpenTSDBConfig) {
    41  	for range time.Tick(c.FlushInterval) {
    42  		if err := openTSDB(&c); nil != err {
    43  			log.Println(err)
    44  		}
    45  	}
    46  }
    47  
    48  func getShortHostname() string {
    49  	if shortHostName == "" {
    50  		host, _ := os.Hostname()
    51  		if index := strings.Index(host, "."); index > 0 {
    52  			shortHostName = host[:index]
    53  		} else {
    54  			shortHostName = host
    55  		}
    56  	}
    57  	return shortHostName
    58  }
    59  
    60  func openTSDB(c *OpenTSDBConfig) error {
    61  	shortHostname := getShortHostname()
    62  	now := time.Now().Unix()
    63  	du := float64(c.DurationUnit)
    64  	conn, err := net.DialTCP("tcp", nil, c.Addr)
    65  	if nil != err {
    66  		return err
    67  	}
    68  	defer conn.Close()
    69  	w := bufio.NewWriter(conn)
    70  	c.Registry.Each(func(name string, i interface{}) {
    71  		switch metric := i.(type) {
    72  		case Counter:
    73  			fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, metric.Count(), shortHostname)
    74  		case Gauge:
    75  			fmt.Fprintf(w, "put %s.%s.value %d %d host=%s\n", c.Prefix, name, now, metric.Value(), shortHostname)
    76  		case GaugeFloat64:
    77  			fmt.Fprintf(w, "put %s.%s.value %d %f host=%s\n", c.Prefix, name, now, metric.Value(), shortHostname)
    78  		case Histogram:
    79  			h := metric.Snapshot()
    80  			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
    81  			fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, h.Count(), shortHostname)
    82  			fmt.Fprintf(w, "put %s.%s.min %d %d host=%s\n", c.Prefix, name, now, h.Min(), shortHostname)
    83  			fmt.Fprintf(w, "put %s.%s.max %d %d host=%s\n", c.Prefix, name, now, h.Max(), shortHostname)
    84  			fmt.Fprintf(w, "put %s.%s.mean %d %.2f host=%s\n", c.Prefix, name, now, h.Mean(), shortHostname)
    85  			fmt.Fprintf(w, "put %s.%s.std-dev %d %.2f host=%s\n", c.Prefix, name, now, h.StdDev(), shortHostname)
    86  			fmt.Fprintf(w, "put %s.%s.50-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[0], shortHostname)
    87  			fmt.Fprintf(w, "put %s.%s.75-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[1], shortHostname)
    88  			fmt.Fprintf(w, "put %s.%s.95-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[2], shortHostname)
    89  			fmt.Fprintf(w, "put %s.%s.99-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[3], shortHostname)
    90  			fmt.Fprintf(w, "put %s.%s.999-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[4], shortHostname)
    91  		case Meter:
    92  			m := metric.Snapshot()
    93  			fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, m.Count(), shortHostname)
    94  			fmt.Fprintf(w, "put %s.%s.one-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate1(), shortHostname)
    95  			fmt.Fprintf(w, "put %s.%s.five-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate5(), shortHostname)
    96  			fmt.Fprintf(w, "put %s.%s.fifteen-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate15(), shortHostname)
    97  			fmt.Fprintf(w, "put %s.%s.mean %d %.2f host=%s\n", c.Prefix, name, now, m.RateMean(), shortHostname)
    98  		case Timer:
    99  			t := metric.Snapshot()
   100  			ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
   101  			fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, t.Count(), shortHostname)
   102  			fmt.Fprintf(w, "put %s.%s.min %d %d host=%s\n", c.Prefix, name, now, t.Min()/int64(du), shortHostname)
   103  			fmt.Fprintf(w, "put %s.%s.max %d %d host=%s\n", c.Prefix, name, now, t.Max()/int64(du), shortHostname)
   104  			fmt.Fprintf(w, "put %s.%s.mean %d %.2f host=%s\n", c.Prefix, name, now, t.Mean()/du, shortHostname)
   105  			fmt.Fprintf(w, "put %s.%s.std-dev %d %.2f host=%s\n", c.Prefix, name, now, t.StdDev()/du, shortHostname)
   106  			fmt.Fprintf(w, "put %s.%s.50-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[0]/du, shortHostname)
   107  			fmt.Fprintf(w, "put %s.%s.75-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[1]/du, shortHostname)
   108  			fmt.Fprintf(w, "put %s.%s.95-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[2]/du, shortHostname)
   109  			fmt.Fprintf(w, "put %s.%s.99-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[3]/du, shortHostname)
   110  			fmt.Fprintf(w, "put %s.%s.999-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[4]/du, shortHostname)
   111  			fmt.Fprintf(w, "put %s.%s.one-minute %d %.2f host=%s\n", c.Prefix, name, now, t.Rate1(), shortHostname)
   112  			fmt.Fprintf(w, "put %s.%s.five-minute %d %.2f host=%s\n", c.Prefix, name, now, t.Rate5(), shortHostname)
   113  			fmt.Fprintf(w, "put %s.%s.fifteen-minute %d %.2f host=%s\n", c.Prefix, name, now, t.Rate15(), shortHostname)
   114  			fmt.Fprintf(w, "put %s.%s.mean-rate %d %.2f host=%s\n", c.Prefix, name, now, t.RateMean(), shortHostname)
   115  		}
   116  		w.Flush()
   117  	})
   118  	return nil
   119  }