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
16
17 type OpenTSDBConfig struct {
18 Addr *net.TCPAddr
19 Registry Registry
20 FlushInterval time.Duration
21 DurationUnit time.Duration
22 Prefix string
23 }
24
25
26
27
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
39
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 }
120
View as plain text