@@ -3,7 +3,9 @@ package datadog
3
3
import (
4
4
"fmt"
5
5
"log"
6
+ "regexp"
6
7
"runtime"
8
+ "strings"
7
9
"time"
8
10
9
11
"github.com/DataDog/datadog-go/statsd"
@@ -14,6 +16,10 @@ const (
14
16
defaultFlushInterval = time .Second * 10
15
17
)
16
18
19
+ // Expect the tags in the pattern
20
+ // namespace.metricName[tag1:value1,tag2:value2,etc....]
21
+ var tagPattern = regexp .MustCompile ("([\\ w\\ .]+)\\ [([\\ w\\ W]+)\\ ]" )
22
+
17
23
// Reporter wraps a metrics registry with a given statsd client.
18
24
type Reporter struct {
19
25
// Registry matrices that need to be reported to the Client
@@ -79,61 +85,63 @@ func (r *Reporter) Flush() {
79
85
// be used in a loop similarly to FlushWithInterval for custom error handling or
80
86
// data submission variations.
81
87
func (r * Reporter ) FlushOnce () error {
82
- r .Registry .Each (func (name string , i interface {}) {
88
+ r .Registry .Each (func (metricName string , i interface {}) {
89
+ name , tags := r .splitNameAndTags (metricName )
90
+
83
91
switch metric := i .(type ) {
84
92
case metrics.Counter :
85
93
v := metric .Count ()
86
94
l := r .ss [name ]
87
- r .Client .Count (name , v - l , r . tags , 1 )
95
+ r .Client .Count (name , v - l , tags , 1 )
88
96
r .ss [name ] = v
89
97
90
98
case metrics.Gauge :
91
- r .Client .Gauge (name , float64 (metric .Value ()), r . tags , 1 )
99
+ r .Client .Gauge (name , float64 (metric .Value ()), tags , 1 )
92
100
93
101
case metrics.GaugeFloat64 :
94
- r .Client .Gauge (name , metric .Value (), r . tags , 1 )
102
+ r .Client .Gauge (name , metric .Value (), tags , 1 )
95
103
96
104
case metrics.Histogram :
97
105
ms := metric .Snapshot ()
98
106
99
- r .Client .Gauge (name + ".count" , float64 (ms .Count ()), r . tags , 1 )
100
- r .Client .Gauge (name + ".max" , float64 (ms .Max ()), r . tags , 1 )
101
- r .Client .Gauge (name + ".min" , float64 (ms .Min ()), r . tags , 1 )
102
- r .Client .Gauge (name + ".mean" , ms .Mean (), r . tags , 1 )
103
- r .Client .Gauge (name + ".stddev" , ms .StdDev (), r . tags , 1 )
104
- r .Client .Gauge (name + ".sum" , float64 (ms .Sum ()), r . tags , 1 )
105
- r .Client .Gauge (name + ".var" , ms .Variance (), r . tags , 1 )
107
+ r .Client .Gauge (name + ".count" , float64 (ms .Count ()), tags , 1 )
108
+ r .Client .Gauge (name + ".max" , float64 (ms .Max ()), tags , 1 )
109
+ r .Client .Gauge (name + ".min" , float64 (ms .Min ()), tags , 1 )
110
+ r .Client .Gauge (name + ".mean" , ms .Mean (), tags , 1 )
111
+ r .Client .Gauge (name + ".stddev" , ms .StdDev (), tags , 1 )
112
+ r .Client .Gauge (name + ".sum" , float64 (ms .Sum ()), tags , 1 )
113
+ r .Client .Gauge (name + ".var" , ms .Variance (), tags , 1 )
106
114
107
115
if len (r .percentiles ) > 0 {
108
116
values := ms .Percentiles (r .percentiles )
109
117
for i , p := range r .p {
110
- r .Client .Gauge (name + p , values [i ], r . tags , 1 )
118
+ r .Client .Gauge (name + p , values [i ], tags , 1 )
111
119
}
112
120
}
113
121
114
122
case metrics.Meter :
115
123
ms := metric .Snapshot ()
116
124
117
- r .Client .Gauge (name + ".count" , float64 (ms .Count ()), r . tags , 1 )
118
- r .Client .Gauge (name + ".rate1" , ms .Rate1 (), r . tags , 1 )
119
- r .Client .Gauge (name + ".rate5" , ms .Rate5 (), r . tags , 1 )
120
- r .Client .Gauge (name + ".rate15" , ms .Rate15 (), r . tags , 1 )
121
- r .Client .Gauge (name + ".mean" , ms .RateMean (), r . tags , 1 )
125
+ r .Client .Gauge (name + ".count" , float64 (ms .Count ()), tags , 1 )
126
+ r .Client .Gauge (name + ".rate1" , ms .Rate1 (), tags , 1 )
127
+ r .Client .Gauge (name + ".rate5" , ms .Rate5 (), tags , 1 )
128
+ r .Client .Gauge (name + ".rate15" , ms .Rate15 (), tags , 1 )
129
+ r .Client .Gauge (name + ".mean" , ms .RateMean (), tags , 1 )
122
130
123
131
case metrics.Timer :
124
132
ms := metric .Snapshot ()
125
133
126
- r .Client .Gauge (name + ".count" , float64 (ms .Count ()), r . tags , 1 )
127
- r .Client .Gauge (name + ".max" , time .Duration (ms .Max ()).Seconds ()* 1000 , r . tags , 1 )
128
- r .Client .Gauge (name + ".min" , time .Duration (ms .Min ()).Seconds ()* 1000 , r . tags , 1 )
129
- r .Client .Gauge (name + ".mean" , time .Duration (ms .Mean ()).Seconds ()* 1000 , r . tags , 1 )
130
- r .Client .Gauge (name + ".stddev" , time .Duration (ms .StdDev ()).Seconds ()* 1000 , r . tags , 1 )
131
- r .Client .Gauge (name + ".sum" , float64 (ms .Sum ()), r . tags , 1 )
134
+ r .Client .Gauge (name + ".count" , float64 (ms .Count ()), tags , 1 )
135
+ r .Client .Gauge (name + ".max" , time .Duration (ms .Max ()).Seconds ()* 1000 , tags , 1 )
136
+ r .Client .Gauge (name + ".min" , time .Duration (ms .Min ()).Seconds ()* 1000 , tags , 1 )
137
+ r .Client .Gauge (name + ".mean" , time .Duration (ms .Mean ()).Seconds ()* 1000 , tags , 1 )
138
+ r .Client .Gauge (name + ".stddev" , time .Duration (ms .StdDev ()).Seconds ()* 1000 , tags , 1 )
139
+ r .Client .Gauge (name + ".sum" , float64 (ms .Sum ()), tags , 1 )
132
140
133
141
if len (r .percentiles ) > 0 {
134
142
values := ms .Percentiles (r .percentiles )
135
143
for i , p := range r .p {
136
- r .Client .Gauge (name + p , time .Duration (values [i ]).Seconds ()* 1000 , r . tags , 1 )
144
+ r .Client .Gauge (name + p , time .Duration (values [i ]).Seconds ()* 1000 , tags , 1 )
137
145
}
138
146
}
139
147
}
@@ -153,3 +161,14 @@ func handlePanic(rec interface{}) {
153
161
}
154
162
log .Printf ("Recovered from panic: %#v \n %v" , rec , callers )
155
163
}
164
+
165
+ func (r * Reporter ) splitNameAndTags (metric string ) (string , []string ) {
166
+ if res := tagPattern .FindStringSubmatch (metric ); len (res ) == 3 {
167
+ if r .tags == nil {
168
+ return res [1 ], append (strings .Split (res [2 ], "," ))
169
+ } else {
170
+ return res [1 ], append (strings .Split (res [2 ], "," ), r .tags ... )
171
+ }
172
+ }
173
+ return metric , r .tags
174
+ }
0 commit comments