Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/component/otelcol/exporter/prometheus/internal/convert/convert_test.go
4100 views
1
package convert_test
2
3
import (
4
"context"
5
"testing"
6
7
"github.com/grafana/agent/component/otelcol/exporter/prometheus/internal/convert"
8
"github.com/grafana/agent/pkg/util"
9
"github.com/grafana/agent/pkg/util/testappender"
10
"github.com/prometheus/prometheus/storage"
11
"github.com/stretchr/testify/require"
12
"go.opentelemetry.io/collector/pdata/pmetric"
13
)
14
15
func TestConverter(t *testing.T) {
16
tt := []struct {
17
name string
18
input string
19
expect string
20
21
showTimestamps bool
22
includeTargetInfo bool
23
includeScopeInfo bool
24
}{
25
{
26
name: "Gauge",
27
input: `{
28
"resource_metrics": [{
29
"scope_metrics": [{
30
"metrics": [{
31
"name": "test_metric_seconds",
32
"gauge": {
33
"data_points": [{
34
"start_time_unix_nano": 1000000000,
35
"time_unix_nano": 1000000000,
36
"as_double": 1234.56
37
}]
38
}
39
}]
40
}]
41
}]
42
}`,
43
expect: `
44
# TYPE test_metric_seconds gauge
45
test_metric_seconds 1234.56
46
`,
47
},
48
{
49
name: "Monotonic sum",
50
input: `{
51
"resource_metrics": [{
52
"scope_metrics": [{
53
"metrics": [{
54
"name": "test_metric_seconds_total",
55
"sum": {
56
"aggregation_temporality": 2,
57
"is_monotonic": true,
58
"data_points": [{
59
"start_time_unix_nano": 1000000000,
60
"time_unix_nano": 1000000000,
61
"as_double": 15
62
}]
63
}
64
}]
65
}]
66
}]
67
}`,
68
expect: `
69
# TYPE test_metric_seconds counter
70
test_metric_seconds_total 15.0
71
`,
72
},
73
{
74
name: "Non-monotonic sum",
75
input: `{
76
"resource_metrics": [{
77
"scope_metrics": [{
78
"metrics": [{
79
"name": "test_metric_seconds",
80
"sum": {
81
"aggregation_temporality": 2,
82
"is_monotonic": false,
83
"data_points": [{
84
"start_time_unix_nano": 1000000000,
85
"time_unix_nano": 1000000000,
86
"as_double": 15
87
}]
88
}
89
}]
90
}]
91
}]
92
}`,
93
expect: `
94
# TYPE test_metric_seconds gauge
95
test_metric_seconds 15.0
96
`,
97
},
98
{
99
name: "Histogram",
100
input: `{
101
"resource_metrics": [{
102
"scope_metrics": [{
103
"metrics": [{
104
"name": "test_metric_seconds",
105
"histogram": {
106
"aggregation_temporality": 2,
107
"data_points": [{
108
"start_time_unix_nano": 1000000000,
109
"time_unix_nano": 1000000000,
110
"count": 333,
111
"sum": 100,
112
"bucket_counts": [0, 111, 0, 222],
113
"explicit_bounds": [0.25, 0.5, 0.75, 1.0]
114
}]
115
}
116
}]
117
}]
118
}]
119
}`,
120
expect: `
121
# TYPE test_metric_seconds histogram
122
test_metric_seconds_bucket{le="0.25"} 0
123
test_metric_seconds_bucket{le="0.5"} 111
124
test_metric_seconds_bucket{le="0.75"} 0
125
test_metric_seconds_bucket{le="1.0"} 222
126
test_metric_seconds_bucket{le="+Inf"} 333
127
test_metric_seconds_sum 100.0
128
test_metric_seconds_count 333
129
`,
130
},
131
{
132
name: "Summary",
133
input: `{
134
"resource_metrics": [{
135
"scope_metrics": [{
136
"metrics": [{
137
"name": "test_metric_seconds",
138
"summary": {
139
"data_points": [{
140
"start_time_unix_nano": 1000000000,
141
"time_unix_nano": 1000000000,
142
"count": 333,
143
"sum": 100,
144
"quantile_values": [
145
{ "quantile": 0, "value": 100 },
146
{ "quantile": 0.25, "value": 200 },
147
{ "quantile": 0.5, "value": 300 },
148
{ "quantile": 0.75, "value": 400 },
149
{ "quantile": 1, "value": 500 }
150
]
151
}]
152
}
153
}]
154
}]
155
}]
156
}`,
157
expect: `
158
# TYPE test_metric_seconds summary
159
test_metric_seconds{quantile="0.0"} 100.0
160
test_metric_seconds{quantile="0.25"} 200.0
161
test_metric_seconds{quantile="0.5"} 300.0
162
test_metric_seconds{quantile="0.75"} 400.0
163
test_metric_seconds{quantile="1.0"} 500.0
164
test_metric_seconds_sum 100.0
165
test_metric_seconds_count 333
166
`,
167
},
168
{
169
name: "Timestamps",
170
input: `{
171
"resource_metrics": [{
172
"scope_metrics": [{
173
"metrics": [{
174
"name": "test_metric_seconds",
175
"gauge": {
176
"data_points": [{
177
"start_time_unix_nano": 1000000000,
178
"time_unix_nano": 1000000000,
179
"as_double": 1234.56
180
}]
181
}
182
}]
183
}]
184
}]
185
}`,
186
showTimestamps: true,
187
expect: `
188
# TYPE test_metric_seconds gauge
189
test_metric_seconds 1234.56 1.0
190
`,
191
},
192
{
193
name: "Labels from resource attributes",
194
input: `{
195
"resource_metrics": [{
196
"resource": {
197
"attributes": [{
198
"key": "service.name",
199
"value": { "stringValue": "myservice" }
200
}, {
201
"key": "service.instance.id",
202
"value": { "stringValue": "instance" }
203
}, {
204
"key": "do_not_display",
205
"value": { "stringValue": "test" }
206
}]
207
},
208
"scope_metrics": [{
209
"metrics": [{
210
"name": "test_metric_seconds",
211
"gauge": {
212
"data_points": [{
213
"as_double": 1234.56
214
}]
215
}
216
}]
217
}]
218
}]
219
}`,
220
expect: `
221
# TYPE test_metric_seconds gauge
222
test_metric_seconds{instance="instance",job="myservice"} 1234.56
223
`,
224
},
225
{
226
name: "Labels from scope name and version",
227
input: `{
228
"resource_metrics": [{
229
"scope_metrics": [{
230
"scope": {
231
"name": "a-name",
232
"version": "a-version",
233
"attributes": [{
234
"key": "something.extra",
235
"value": { "stringValue": "zzz-extra-value" }
236
}]
237
},
238
"metrics": [{
239
"name": "test_metric_seconds",
240
"gauge": {
241
"data_points": [{
242
"as_double": 1234.56
243
}]
244
}
245
}]
246
}]
247
}]
248
}`,
249
includeScopeInfo: true,
250
expect: `
251
# TYPE otel_scope_info gauge
252
otel_scope_info{name="a-name",version="a-version",something_extra="zzz-extra-value"} 1.0
253
# TYPE test_metric_seconds gauge
254
test_metric_seconds{otel_scope_name="a-name",otel_scope_version="a-version"} 1234.56
255
`,
256
},
257
{
258
name: "Labels from data point",
259
input: `{
260
"resource_metrics": [{
261
"scope_metrics": [{
262
"metrics": [{
263
"name": "test_metric_seconds",
264
"gauge": {
265
"data_points": [{
266
"attributes": [{
267
"key": "foo",
268
"value": { "stringValue": "bar" }
269
}],
270
"as_double": 1234.56
271
}]
272
}
273
}]
274
}]
275
}]
276
}`,
277
expect: `
278
# TYPE test_metric_seconds gauge
279
test_metric_seconds{foo="bar"} 1234.56
280
`,
281
},
282
{
283
name: "Target info metric",
284
input: `{
285
"resource_metrics": [{
286
"resource": {
287
"attributes": [{
288
"key": "service.name",
289
"value": { "stringValue": "myservice" }
290
}, {
291
"key": "service.instance.id",
292
"value": { "stringValue": "instance" }
293
}, {
294
"key": "custom_attr",
295
"value": { "stringValue": "test" }
296
}]
297
},
298
"scope_metrics": [{
299
"metrics": [{
300
"name": "test_metric_seconds",
301
"gauge": {
302
"data_points": [{
303
"as_double": 1234.56
304
}]
305
}
306
}]
307
}]
308
}]
309
}`,
310
includeTargetInfo: true,
311
expect: `
312
# HELP target_info Target metadata
313
# TYPE target_info gauge
314
target_info{instance="instance",job="myservice",custom_attr="test"} 1.0
315
# TYPE test_metric_seconds gauge
316
test_metric_seconds{instance="instance",job="myservice"} 1234.56
317
`,
318
},
319
}
320
321
decoder := &pmetric.JSONUnmarshaler{}
322
for _, tc := range tt {
323
t.Run(tc.name, func(t *testing.T) {
324
payload, err := decoder.UnmarshalMetrics([]byte(tc.input))
325
require.NoError(t, err)
326
327
var app testappender.Appender
328
app.HideTimestamps = !tc.showTimestamps
329
330
l := util.TestLogger(t)
331
conv := convert.New(l, appenderAppendable{Inner: &app}, convert.Options{
332
IncludeTargetInfo: tc.includeTargetInfo,
333
IncludeScopeInfo: tc.includeScopeInfo,
334
})
335
require.NoError(t, conv.ConsumeMetrics(context.Background(), payload))
336
337
families, err := app.MetricFamilies()
338
require.NoError(t, err)
339
340
c := testappender.Comparer{OpenMetrics: true}
341
require.NoError(t, c.Compare(families, tc.expect))
342
})
343
}
344
}
345
346
// appenderAppendable always returns the same Appender.
347
type appenderAppendable struct {
348
Inner storage.Appender
349
}
350
351
var _ storage.Appendable = appenderAppendable{}
352
353
func (aa appenderAppendable) Appender(context.Context) storage.Appender {
354
return aa.Inner
355
}
356
357