forked from vmware-archive/atc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dogstatsd.go
114 lines (95 loc) · 2.62 KB
/
dogstatsd.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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package emitter
import (
"errors"
"fmt"
"log"
"regexp"
"strings"
"code.cloudfoundry.org/lager"
"github.com/DataDog/datadog-go/statsd"
"github.com/concourse/atc/metric"
)
type DogstatsdEmitter struct {
client *statsd.Client
}
type DogstatsDBConfig struct {
Host string `long:"datadog-agent-host" description:"Datadog agent host to expose dogstatsd metrics"`
Port string `long:"datadog-agent-port" description:"Datadog agent port to expose dogstatsd metrics"`
Prefix string `long:"datadog-prefix" description:"Prefix for all metrics to easily find them in Datadog"`
}
func getFloatHelper(value interface{}) (f float64, err error) {
switch value.(type) {
case int:
f = float64(value.(int))
case int8:
f = float64(value.(int8))
case int16:
f = float64(value.(int16))
case int32:
f = float64(value.(int32))
case int64:
f = float64(value.(int64))
case uint:
f = float64(value.(uint))
case uint8:
f = float64(value.(uint8))
case uint16:
f = float64(value.(uint16))
case uint32:
f = float64(value.(uint32))
case uint64:
f = float64(value.(uint64))
case float32:
f = float64(value.(float32))
case float64:
f = value.(float64)
default:
err = errors.New("type not supported")
}
return f, err
}
func init() {
metric.RegisterEmitter(&DogstatsDBConfig{})
}
func (config *DogstatsDBConfig) Description() string { return "Datadog" }
func (config *DogstatsDBConfig) IsConfigured() bool { return config.Host != "" && config.Port != "" }
func (config *DogstatsDBConfig) NewEmitter() (metric.Emitter, error) {
client, err := statsd.New(fmt.Sprintf("%s:%s", config.Host, config.Port))
if err != nil {
log.Fatal(err)
return &DogstatsdEmitter{}, err
}
if config.Prefix != "" {
if strings.HasSuffix(config.Prefix, ".") {
client.Namespace = config.Prefix
} else {
client.Namespace = fmt.Sprintf("%s.", config.Prefix)
}
}
return &DogstatsdEmitter{
client: client,
}, nil
}
var specialChars = regexp.MustCompile("[^a-zA-Z0-9_]+")
func (emitter *DogstatsdEmitter) Emit(logger lager.Logger, event metric.Event) {
name := specialChars.ReplaceAllString(strings.Replace(strings.ToLower(event.Name), " ", "_", -1), "")
tags := []string{
fmt.Sprintf("host:%s", event.Host),
fmt.Sprintf("state:%s", event.State),
}
for k, v := range event.Attributes {
tags = append(tags, fmt.Sprintf("%s:%s", k, v))
}
value, err := getFloatHelper(event.Value)
if err != nil {
logger.Error("failed-to-convert-metric-for-dogstatsd", nil, lager.Data{
"metric-name": name,
})
return
}
err = emitter.client.Gauge(name, value, tags, 1)
if err != nil {
logger.Error("failed-to-send-metric", err)
return
}
}