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