-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstatsd.go
154 lines (128 loc) · 4.46 KB
/
statsd.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package tools
import (
"fmt"
"os"
"errors"
"github.com/DataDog/datadog-go/v5/statsd"
)
// Disable the linter because it complains about the field names, which shouldn't be changed.
//
//revive:disable
const (
statsdRate = 1
dummyFmtString1 = "%s: name: %s, value: %f, tags: %v"
dummyFmtString2 = "%s: name: %s, tags: %v"
dummyFmtString3 = "%s: name: %s, value: %d, tags: %v"
HttpClientResponseCodeAllKey = "http_client.response_code.all"
HttpClientResponseTimeKey = "http_client.response_time_ms"
HttpClientResponseErrorKey = "http_client.response_error"
HttpClientResponseSuccessKey = "http_client.response_success"
HttpClientResponseCodeFormatKey = "http_client.response_code.%d"
WebResponseTimeKey = "web.response_time"
WebResponseCodeFormatKey = "web.response_code.%d"
WebResponseCodeAllKey = "web.response_code.all"
)
//revive:enable
// StatsD is the interface for the all the DataDog StatsD methods used by
// mergermarket. Please extend it as needed to record other types of metric.
type StatsD interface {
Histogram(name string, value float64, tags ...string)
Gauge(name string, value float64, tags ...string)
Incr(name string, tags ...string)
Count(name string, value int64, tags ...string)
}
// StatsDConfig provides configuration for metrics recording
type StatsDConfig struct {
isProduction bool
log Logger
host string
port string
}
func NewStatsDConfig(isProduction bool, log Logger) StatsDConfig {
return StatsDConfig{
isProduction: isProduction,
log: log,
host: os.Getenv("STATSD_HOST"),
port: os.Getenv("STATSD_PORT"),
}
}
// NewStatsD provides a new StatsD metrics recorder
func NewStatsD(config StatsDConfig) (StatsD, error) {
if !config.isProduction || config.port == "" || config.host == "" {
return &dummyStatsD{config.log}, nil
}
return newMMStatsD(config)
}
func newMMStatsD(config StatsDConfig) (*mmStatsD, error) {
if config.port == "" || config.host == "" {
return nil, errors.New("Port and Host are required fields")
}
sd, err := statsd.New(config.host+":"+config.port, withGlobalNamespace(), withGlobalTags())
if err != nil {
return nil, err
}
return &mmStatsD{sd, config.log}, nil
}
func withGlobalNamespace() statsd.Option {
return statsd.WithNamespace("app.")
}
func withGlobalTags() statsd.Option {
return statsd.WithTags(globalTags())
}
func globalTags() []string {
return []string{
"env:" + getEnv(),
"component:" + getComponentName(),
}
}
type mmStatsD struct {
ddstatsd *statsd.Client
log Logger
}
const statsDErrMsg = "Failed to send"
const statsDErrFmt = "%s %s %v"
func (mmsd *mmStatsD) Histogram(name string, value float64, tags ...string) {
if err := mmsd.ddstatsd.Histogram(name, value, tags, statsdRate); err != nil {
errMsg := fmt.Sprintf(statsDErrFmt, statsDErrMsg, name, err)
mmsd.log.Error(errMsg)
}
}
func (mmsd *mmStatsD) Gauge(name string, value float64, tags ...string) {
if err := mmsd.ddstatsd.Gauge(name, value, tags, statsdRate); err != nil {
errMsg := fmt.Sprintf(statsDErrFmt, statsDErrMsg, name, err)
mmsd.log.Error(errMsg)
}
}
func (mmsd *mmStatsD) Incr(name string, tags ...string) {
if err := mmsd.ddstatsd.Incr(name, tags, statsdRate); err != nil {
errMsg := fmt.Sprintf(statsDErrFmt, statsDErrMsg, name, err)
mmsd.log.Error(errMsg)
}
}
func (mmsd *mmStatsD) Count(name string, value int64, tags ...string) {
if err := mmsd.ddstatsd.Count(name, value, tags, statsdRate); err != nil {
errMsg := fmt.Sprintf(statsDErrFmt, statsDErrMsg, name, err)
mmsd.log.Error(errMsg)
}
}
// dummyStatsD is returned when StatsDConfig.isDevelopment is set to true. It
// stubs out the DataDog methods and sends them to the supplied logger
type dummyStatsD struct {
Logger
}
func (dsd dummyStatsD) Histogram(name string, value float64, tags ...string) {
logString := fmt.Sprintf(dummyFmtString1, "Histogram", name, value, tags)
dsd.Info(logString)
}
func (dsd dummyStatsD) Gauge(name string, value float64, tags ...string) {
logString := fmt.Sprintf(dummyFmtString1, "Gauge", name, value, tags)
dsd.Info(logString)
}
func (dsd dummyStatsD) Incr(name string, tags ...string) {
logString := fmt.Sprintf(dummyFmtString2, "Increment", name, tags)
dsd.Info(logString)
}
func (dsd dummyStatsD) Count(name string, value int64, tags ...string) {
logString := fmt.Sprintf(dummyFmtString3, "Count", name, value, tags)
dsd.Info(logString)
}