@@ -3,7 +3,9 @@ package datadog
33import (
44 "fmt"
55 "log"
6+ "regexp"
67 "runtime"
8+ "strings"
79 "time"
810
911 "github.com/DataDog/datadog-go/statsd"
@@ -14,6 +16,10 @@ const (
1416 defaultFlushInterval = time .Second * 10
1517)
1618
19+ // Expect the tags in the pattern
20+ // namespace.metricName[tag1:value1,tag2:value2,etc....]
21+ var tagPattern = regexp .MustCompile ("([\\ w\\ .]+)\\ [([\\ w\\ W]+)\\ ]" )
22+
1723// Reporter wraps a metrics registry with a given statsd client.
1824type Reporter struct {
1925 // Registry matrices that need to be reported to the Client
@@ -79,61 +85,63 @@ func (r *Reporter) Flush() {
7985// be used in a loop similarly to FlushWithInterval for custom error handling or
8086// data submission variations.
8187func (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+
8391 switch metric := i .(type ) {
8492 case metrics.Counter :
8593 v := metric .Count ()
8694 l := r .ss [name ]
87- r .Client .Count (name , v - l , r . tags , 1 )
95+ r .Client .Count (name , v - l , tags , 1 )
8896 r .ss [name ] = v
8997
9098 case metrics.Gauge :
91- r .Client .Gauge (name , float64 (metric .Value ()), r . tags , 1 )
99+ r .Client .Gauge (name , float64 (metric .Value ()), tags , 1 )
92100
93101 case metrics.GaugeFloat64 :
94- r .Client .Gauge (name , metric .Value (), r . tags , 1 )
102+ r .Client .Gauge (name , metric .Value (), tags , 1 )
95103
96104 case metrics.Histogram :
97105 ms := metric .Snapshot ()
98106
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 )
106114
107115 if len (r .percentiles ) > 0 {
108116 values := ms .Percentiles (r .percentiles )
109117 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 )
111119 }
112120 }
113121
114122 case metrics.Meter :
115123 ms := metric .Snapshot ()
116124
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 )
122130
123131 case metrics.Timer :
124132 ms := metric .Snapshot ()
125133
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 )
132140
133141 if len (r .percentiles ) > 0 {
134142 values := ms .Percentiles (r .percentiles )
135143 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 )
137145 }
138146 }
139147 }
@@ -153,3 +161,14 @@ func handlePanic(rec interface{}) {
153161 }
154162 log .Printf ("Recovered from panic: %#v \n %v" , rec , callers )
155163}
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