/
collection_server.go
72 lines (56 loc) · 1.46 KB
/
collection_server.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
71
72
package main
import (
"bytes"
"log"
"net"
"strconv"
)
type CollectionServer struct {
metrics *Metrics
}
func NewCollectionServer(metrics *Metrics) *CollectionServer {
return &CollectionServer{metrics: metrics}
}
func (server *CollectionServer) ListenAndServe(address string) {
conn, err := net.ListenPacket("udp", address)
if err != nil {
log.Fatalf("CollectionServer.ListenAndServe: %s", err.Error())
}
log.Println("server is up")
for {
packet := make([]byte, 512)
n, _, err := conn.ReadFrom(packet)
if err != nil {
return
}
server.handlePacket(packet[:n])
}
}
func (server *CollectionServer) handlePacket(packet []byte) {
server.metrics.UpdateCounter("statsd.packets_received", 1, 1)
metrics := bytes.Split(packet, []byte("\n"))
for _, metric := range metrics {
parts := bytes.Split(metric, []byte(":"))
key := string(parts[0])
for _, bit := range parts[1:] {
fields := bytes.Split(bit, []byte("|"))
if len(fields) == 1 {
server.metrics.UpdateCounter("statsd.bad_lines_seen", 1, 1)
continue
}
sampleRate := float64(1)
value, _ := strconv.ParseFloat(string(fields[0]), 64)
if len(fields) == 3 {
sampleRate, _ = strconv.ParseFloat(string(fields[2]), 64)
}
switch {
case string(fields[1]) == "ms":
server.metrics.UpdateTimer(key, value)
case string(fields[1]) == "g":
server.metrics.UpdateGauge(key, value)
default:
server.metrics.UpdateCounter(key, value, sampleRate)
}
}
}
}