github.com/neatlab/neatio@v1.7.3-0.20220425043230-d903e92fcc75/utilities/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 string = ""
    14  
    15  type OpenTSDBConfig struct {
    16  	Addr          *net.TCPAddr
    17  	Registry      Registry
    18  	FlushInterval time.Duration
    19  	DurationUnit  time.Duration
    20  	Prefix        string
    21  }
    22  
    23  func OpenTSDB(r Registry, d time.Duration, prefix string, addr *net.TCPAddr) {
    24  	OpenTSDBWithConfig(OpenTSDBConfig{
    25  		Addr:          addr,
    26  		Registry:      r,
    27  		FlushInterval: d,
    28  		DurationUnit:  time.Nanosecond,
    29  		Prefix:        prefix,
    30  	})
    31  }
    32  
    33  func OpenTSDBWithConfig(c OpenTSDBConfig) {
    34  	for range time.Tick(c.FlushInterval) {
    35  		if err := openTSDB(&c); nil != err {
    36  			log.Println(err)
    37  		}
    38  	}
    39  }
    40  
    41  func getShortHostname() string {
    42  	if shortHostName == "" {
    43  		host, _ := os.Hostname()
    44  		if index := strings.Index(host, "."); index > 0 {
    45  			shortHostName = host[:index]
    46  		} else {
    47  			shortHostName = host
    48  		}
    49  	}
    50  	return shortHostName
    51  }
    52  
    53  func openTSDB(c *OpenTSDBConfig) error {
    54  	shortHostname := getShortHostname()
    55  	now := time.Now().Unix()
    56  	du := float64(c.DurationUnit)
    57  	conn, err := net.DialTCP("tcp", nil, c.Addr)
    58  	if nil != err {
    59  		return err
    60  	}
    61  	defer conn.Close()
    62  	w := bufio.NewWriter(conn)
    63  	c.Registry.Each(func(name string, i interface{}) {
    64  		switch metric := i.(type) {
    65  		case Counter:
    66  			fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, metric.Count(), shortHostname)
    67  		case Gauge:
    68  			fmt.Fprintf(w, "put %s.%s.value %d %d host=%s\n", c.Prefix, name, now, metric.Value(), shortHostname)
    69  		case GaugeFloat64:
    70  			fmt.Fprintf(w, "put %s.%s.value %d %f host=%s\n", c.Prefix, name, now, metric.Value(), shortHostname)
    71  		case Histogram:
    72  			h := metric.Snapshot()
    73  			ps := h.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
    74  			fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, h.Count(), shortHostname)
    75  			fmt.Fprintf(w, "put %s.%s.min %d %d host=%s\n", c.Prefix, name, now, h.Min(), shortHostname)
    76  			fmt.Fprintf(w, "put %s.%s.max %d %d host=%s\n", c.Prefix, name, now, h.Max(), shortHostname)
    77  			fmt.Fprintf(w, "put %s.%s.mean %d %.2f host=%s\n", c.Prefix, name, now, h.Mean(), shortHostname)
    78  			fmt.Fprintf(w, "put %s.%s.std-dev %d %.2f host=%s\n", c.Prefix, name, now, h.StdDev(), shortHostname)
    79  			fmt.Fprintf(w, "put %s.%s.50-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[0], shortHostname)
    80  			fmt.Fprintf(w, "put %s.%s.75-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[1], shortHostname)
    81  			fmt.Fprintf(w, "put %s.%s.95-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[2], shortHostname)
    82  			fmt.Fprintf(w, "put %s.%s.99-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[3], shortHostname)
    83  			fmt.Fprintf(w, "put %s.%s.999-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[4], shortHostname)
    84  		case Meter:
    85  			m := metric.Snapshot()
    86  			fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, m.Count(), shortHostname)
    87  			fmt.Fprintf(w, "put %s.%s.one-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate1(), shortHostname)
    88  			fmt.Fprintf(w, "put %s.%s.five-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate5(), shortHostname)
    89  			fmt.Fprintf(w, "put %s.%s.fifteen-minute %d %.2f host=%s\n", c.Prefix, name, now, m.Rate15(), shortHostname)
    90  			fmt.Fprintf(w, "put %s.%s.mean %d %.2f host=%s\n", c.Prefix, name, now, m.RateMean(), shortHostname)
    91  		case Timer:
    92  			t := metric.Snapshot()
    93  			ps := t.Percentiles([]float64{0.5, 0.75, 0.95, 0.99, 0.999})
    94  			fmt.Fprintf(w, "put %s.%s.count %d %d host=%s\n", c.Prefix, name, now, t.Count(), shortHostname)
    95  			fmt.Fprintf(w, "put %s.%s.min %d %d host=%s\n", c.Prefix, name, now, t.Min()/int64(du), shortHostname)
    96  			fmt.Fprintf(w, "put %s.%s.max %d %d host=%s\n", c.Prefix, name, now, t.Max()/int64(du), shortHostname)
    97  			fmt.Fprintf(w, "put %s.%s.mean %d %.2f host=%s\n", c.Prefix, name, now, t.Mean()/du, shortHostname)
    98  			fmt.Fprintf(w, "put %s.%s.std-dev %d %.2f host=%s\n", c.Prefix, name, now, t.StdDev()/du, shortHostname)
    99  			fmt.Fprintf(w, "put %s.%s.50-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[0]/du, shortHostname)
   100  			fmt.Fprintf(w, "put %s.%s.75-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[1]/du, shortHostname)
   101  			fmt.Fprintf(w, "put %s.%s.95-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[2]/du, shortHostname)
   102  			fmt.Fprintf(w, "put %s.%s.99-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[3]/du, shortHostname)
   103  			fmt.Fprintf(w, "put %s.%s.999-percentile %d %.2f host=%s\n", c.Prefix, name, now, ps[4]/du, shortHostname)
   104  			fmt.Fprintf(w, "put %s.%s.one-minute %d %.2f host=%s\n", c.Prefix, name, now, t.Rate1(), shortHostname)
   105  			fmt.Fprintf(w, "put %s.%s.five-minute %d %.2f host=%s\n", c.Prefix, name, now, t.Rate5(), shortHostname)
   106  			fmt.Fprintf(w, "put %s.%s.fifteen-minute %d %.2f host=%s\n", c.Prefix, name, now, t.Rate15(), shortHostname)
   107  			fmt.Fprintf(w, "put %s.%s.mean-rate %d %.2f host=%s\n", c.Prefix, name, now, t.RateMean(), shortHostname)
   108  		}
   109  		w.Flush()
   110  	})
   111  	return nil
   112  }