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 }