Skip to content

Commit f7e839e

Browse files
authored
Merge pull request #2 from vimeo/add-find-metric-for-testing
added a find metric helper; useful for testing
2 parents a42777c + 2ec2de2 commit f7e839e

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

otmetricreader/find.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package otmetricreader
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"go.opentelemetry.io/otel/attribute"
8+
otsdkmetric "go.opentelemetry.io/otel/sdk/metric"
9+
"go.opentelemetry.io/otel/sdk/metric/metricdata"
10+
)
11+
12+
// FindVal is a testing utility to find the value of a specific metric
13+
// collected by the sdk [metric.ManualReader].
14+
//
15+
// It searches for a metric matching the provided metricName and [attribute.Set].
16+
// The type parameter V specifies the expected value type, which must be
17+
// either int64 or float64.
18+
//
19+
// An error is returned if a metric matching the name and attributes is not found,
20+
// or if the found metric's value type does not match V.
21+
func FindVal[V int64 | float64](ctx context.Context, r *otsdkmetric.ManualReader, metricName string, kvs attribute.Set) (V, error) {
22+
var zv V
23+
res := metricdata.ResourceMetrics{}
24+
if err := r.Collect(ctx, &res); err != nil {
25+
return zv, err
26+
}
27+
28+
for _, sm := range res.ScopeMetrics {
29+
for _, m := range sm.Metrics {
30+
if m.Name != metricName {
31+
continue
32+
}
33+
switch vs := m.Data.(type) {
34+
case metricdata.Gauge[V]:
35+
for _, d := range vs.DataPoints {
36+
if !kvs.Equals(&d.Attributes) {
37+
continue
38+
}
39+
return d.Value, nil
40+
}
41+
case metricdata.Sum[V]:
42+
for _, d := range vs.DataPoints {
43+
if !kvs.Equals(&d.Attributes) {
44+
continue
45+
}
46+
return d.Value, nil
47+
}
48+
default:
49+
// wrong metric-type (or histogram, which we'll have to implement later)
50+
continue
51+
}
52+
}
53+
}
54+
return zv, fmt.Errorf("metric %s not found", metricName)
55+
}

otmetricreader/find_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package otmetricreader
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"go.opentelemetry.io/otel/attribute"
8+
"go.opentelemetry.io/otel/metric"
9+
otsdkmetric "go.opentelemetry.io/otel/sdk/metric"
10+
)
11+
12+
func TestFindMetricVal(t *testing.T) {
13+
ctx := context.Background()
14+
15+
r := otsdkmetric.NewManualReader()
16+
mp := otsdkmetric.NewMeterProvider(otsdkmetric.WithReader(r))
17+
18+
otM := mp.Meter("foobar")
19+
attrSet := attribute.NewSet(attribute.String("fizzlebit", "foobar"), attribute.String("ouch", "icky"))
20+
21+
// read an int64 counter
22+
counter, countErr := otM.Int64Counter("a_counter_int")
23+
if countErr != nil {
24+
t.Fatalf("failed to register counter metric: %s", countErr)
25+
}
26+
counter.Add(ctx, 2, metric.WithAttributeSet(attrSet))
27+
28+
counterVal, counterValErr := FindVal[int64](ctx, r, "a_counter_int", attrSet)
29+
if counterValErr != nil {
30+
t.Errorf("failed to fetch counter metric value: %s", counterValErr)
31+
}
32+
if counterVal != 2 {
33+
t.Errorf("unexpected counter metric value: want %d; got %d", 2, counterVal)
34+
}
35+
36+
// read an int64 gauge
37+
gauge, gaugeErr := otM.Int64Gauge("a_gauge_int")
38+
if gaugeErr != nil {
39+
t.Fatalf("failed to register gauge metric: %s", gaugeErr)
40+
}
41+
gauge.Record(ctx, 3, metric.WithAttributeSet(attrSet))
42+
43+
gaugeVal, gaugeValErr := FindVal[int64](ctx, r, "a_gauge_int", attrSet)
44+
if gaugeValErr != nil {
45+
t.Errorf("failed to fetch gauge metric value: %s", gaugeValErr)
46+
}
47+
if gaugeVal != 3 {
48+
t.Errorf("unexpected gauge metric value: want %d; got %d", 3, gaugeVal)
49+
}
50+
}

0 commit comments

Comments
 (0)