@@ -13,12 +13,11 @@ import (
1313 "time"
1414)
1515
16- // metricsClient emits timing and gauge metrics to a backend.
16+ // metricsClient emits distribution metrics to a backend.
17+ // All metrics are submitted as distributions to support percentile aggregation.
1718type metricsClient interface {
18- // timing records a duration metric in milliseconds.
19- timing (name string , ms int64 , tags ... string )
20- // gauge records a point-in-time value.
21- gauge (name string , value int64 , tags ... string )
19+ // distribution records a single sample for a distribution metric.
20+ distribution (name string , value float64 , tags ... string )
2221 // close flushes any pending data.
2322 close ()
2423}
@@ -27,9 +26,8 @@ type metricsClient interface {
2726// It exists because kong cannot bind a nil interface value.
2827type noopMetrics struct {}
2928
30- func (noopMetrics ) timing (string , int64 , ... string ) {}
31- func (noopMetrics ) gauge (string , int64 , ... string ) {}
32- func (noopMetrics ) close () {}
29+ func (noopMetrics ) distribution (string , float64 , ... string ) {}
30+ func (noopMetrics ) close () {}
3331
3432// metricsFlags are CLI flags for configuring metrics emission.
3533type metricsFlags struct {
@@ -94,12 +92,8 @@ func newStatsdClient(addr string, baseTags []string) *statsdClient {
9492 return & statsdClient {conn : conn , tags : baseTags }
9593}
9694
97- func (s * statsdClient ) timing (name string , ms int64 , tags ... string ) {
98- s .send (fmt .Sprintf ("%s:%d|d" , name , ms ), tags ) // |d = distribution for DD percentile support
99- }
100-
101- func (s * statsdClient ) gauge (name string , value int64 , tags ... string ) {
102- s .send (fmt .Sprintf ("%s:%d|g" , name , value ), tags )
95+ func (s * statsdClient ) distribution (name string , value float64 , tags ... string ) {
96+ s .send (fmt .Sprintf ("%s:%g|d" , name , value ), tags )
10397}
10498
10599func (s * statsdClient ) send (stat string , extraTags []string ) {
@@ -114,9 +108,9 @@ func (s *statsdClient) close() {
114108 s .conn .Close () //nolint:errcheck,gosec
115109}
116110
117- // ── DataDog HTTP API ───────────────────────── ───────────────────────────────
111+ // ── DataDog HTTP API (v1 distribution_points) ───────────────────────────────
118112
119- const datadogSeriesURL = "https://api.datadoghq.com/api/v2/series "
113+ const datadogDistURL = "https://api.datadoghq.com/api/v1/distribution_points "
120114
121115type datadogAPIClient struct {
122116 apiKey string
@@ -132,34 +126,17 @@ func newDatadogAPIClient(apiKey string, baseTags []string) *datadogAPIClient {
132126 }
133127}
134128
135- // Datadog v2 metric type enum values.
136- const (
137- ddMetricTypeGauge = 3
138- ddMetricTypeCount = 1
139- )
140-
141- func (d * datadogAPIClient ) timing (name string , ms int64 , tags ... string ) {
142- d .submit (name , float64 (ms ), ddMetricTypeGauge , tags )
143- }
144-
145- func (d * datadogAPIClient ) gauge (name string , value int64 , tags ... string ) {
146- d .submit (name , float64 (value ), ddMetricTypeGauge , tags )
147- }
148-
149- func (d * datadogAPIClient ) submit (name string , value float64 , metricType int , extraTags []string ) {
150- allTags := append (d .tags , extraTags ... )
129+ func (d * datadogAPIClient ) distribution (name string , value float64 , tags ... string ) {
130+ allTags := append (d .tags , tags ... )
151131 now := time .Now ().Unix ()
152132
133+ // v1 distribution_points format: points is [[timestamp, [value, ...]]]
153134 payload := map [string ]interface {}{
154135 "series" : []map [string ]interface {}{
155136 {
156137 "metric" : name ,
157- "type" : metricType ,
158- "points" : []map [string ]interface {}{
159- {
160- "timestamp" : now ,
161- "value" : value ,
162- },
138+ "points" : []interface {}{
139+ []interface {}{now , []float64 {value }},
163140 },
164141 "tags" : allTags ,
165142 },
@@ -172,7 +149,7 @@ func (d *datadogAPIClient) submit(name string, value float64, metricType int, ex
172149 return
173150 }
174151
175- req , err := http .NewRequest ("POST" , datadogSeriesURL , bytes .NewReader (body ))
152+ req , err := http .NewRequest ("POST" , datadogDistURL , bytes .NewReader (body ))
176153 if err != nil {
177154 slog .Warn ("metrics: failed to create request" , "error" , err )
178155 return
@@ -193,11 +170,3 @@ func (d *datadogAPIClient) submit(name string, value float64, metricType int, ex
193170}
194171
195172func (d * datadogAPIClient ) close () {}
196-
197- func emitTiming (m metricsClient , name string , ms int64 , tags ... string ) {
198- m .timing (name , ms , tags ... )
199- }
200-
201- func emitGauge (m metricsClient , name string , value int64 , tags ... string ) {
202- m .gauge (name , value , tags ... )
203- }
0 commit comments