-
Notifications
You must be signed in to change notification settings - Fork 9
/
statsd_output.go
70 lines (59 loc) · 1.45 KB
/
statsd_output.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package shh
import (
"fmt"
"net"
"strconv"
"github.com/heroku/slog"
)
type Statsd struct {
measurements <-chan Measurement
last map[string]CounterMeasurement
Proto string
Host string
prefix string
source string
}
func NewStatsdOutputter(measurements <-chan Measurement, config Config) *Statsd {
return &Statsd{
measurements: measurements,
last: make(map[string]CounterMeasurement),
Proto: config.StatsdProto,
Host: config.StatsdHost,
prefix: config.Prefix,
source: config.Source, // TODO: unused?
}
}
func (out *Statsd) Start() {
go out.Output()
}
func (out *Statsd) Connect(host string) net.Conn {
ctx := slog.Context{"fn": "Connect", "outputter": "statsd"}
conn, err := net.Dial(out.Proto, host)
if err != nil {
FatalError(ctx, err, "Connecting to statsd host")
}
return conn
}
func (s *Statsd) Encode(mm Measurement) string {
switch mm.Type() {
case CounterType:
key := mm.Name(s.prefix)
last, ok := s.last[key]
s.last[key] = mm.(CounterMeasurement)
if ok {
return fmt.Sprintf("%s:%s|c", key, strconv.FormatUint(
mm.(CounterMeasurement).Difference(last), 10))
}
case FloatGaugeType, GaugeType:
return fmt.Sprintf("%s:%s|g", mm.Name(s.prefix), mm.StrValue())
}
return ""
}
func (out *Statsd) Output() {
conn := out.Connect(out.Host)
for mm := range out.measurements {
if ms := out.Encode(mm); ms != "" {
fmt.Fprintf(conn, ms)
}
}
}