Path: blob/main/component/otelcol/exporter/prometheus/internal/convert/convert_test.go
4100 views
package convert_test12import (3"context"4"testing"56"github.com/grafana/agent/component/otelcol/exporter/prometheus/internal/convert"7"github.com/grafana/agent/pkg/util"8"github.com/grafana/agent/pkg/util/testappender"9"github.com/prometheus/prometheus/storage"10"github.com/stretchr/testify/require"11"go.opentelemetry.io/collector/pdata/pmetric"12)1314func TestConverter(t *testing.T) {15tt := []struct {16name string17input string18expect string1920showTimestamps bool21includeTargetInfo bool22includeScopeInfo bool23}{24{25name: "Gauge",26input: `{27"resource_metrics": [{28"scope_metrics": [{29"metrics": [{30"name": "test_metric_seconds",31"gauge": {32"data_points": [{33"start_time_unix_nano": 1000000000,34"time_unix_nano": 1000000000,35"as_double": 1234.5636}]37}38}]39}]40}]41}`,42expect: `43# TYPE test_metric_seconds gauge44test_metric_seconds 1234.5645`,46},47{48name: "Monotonic sum",49input: `{50"resource_metrics": [{51"scope_metrics": [{52"metrics": [{53"name": "test_metric_seconds_total",54"sum": {55"aggregation_temporality": 2,56"is_monotonic": true,57"data_points": [{58"start_time_unix_nano": 1000000000,59"time_unix_nano": 1000000000,60"as_double": 1561}]62}63}]64}]65}]66}`,67expect: `68# TYPE test_metric_seconds counter69test_metric_seconds_total 15.070`,71},72{73name: "Non-monotonic sum",74input: `{75"resource_metrics": [{76"scope_metrics": [{77"metrics": [{78"name": "test_metric_seconds",79"sum": {80"aggregation_temporality": 2,81"is_monotonic": false,82"data_points": [{83"start_time_unix_nano": 1000000000,84"time_unix_nano": 1000000000,85"as_double": 1586}]87}88}]89}]90}]91}`,92expect: `93# TYPE test_metric_seconds gauge94test_metric_seconds 15.095`,96},97{98name: "Histogram",99input: `{100"resource_metrics": [{101"scope_metrics": [{102"metrics": [{103"name": "test_metric_seconds",104"histogram": {105"aggregation_temporality": 2,106"data_points": [{107"start_time_unix_nano": 1000000000,108"time_unix_nano": 1000000000,109"count": 333,110"sum": 100,111"bucket_counts": [0, 111, 0, 222],112"explicit_bounds": [0.25, 0.5, 0.75, 1.0]113}]114}115}]116}]117}]118}`,119expect: `120# TYPE test_metric_seconds histogram121test_metric_seconds_bucket{le="0.25"} 0122test_metric_seconds_bucket{le="0.5"} 111123test_metric_seconds_bucket{le="0.75"} 0124test_metric_seconds_bucket{le="1.0"} 222125test_metric_seconds_bucket{le="+Inf"} 333126test_metric_seconds_sum 100.0127test_metric_seconds_count 333128`,129},130{131name: "Summary",132input: `{133"resource_metrics": [{134"scope_metrics": [{135"metrics": [{136"name": "test_metric_seconds",137"summary": {138"data_points": [{139"start_time_unix_nano": 1000000000,140"time_unix_nano": 1000000000,141"count": 333,142"sum": 100,143"quantile_values": [144{ "quantile": 0, "value": 100 },145{ "quantile": 0.25, "value": 200 },146{ "quantile": 0.5, "value": 300 },147{ "quantile": 0.75, "value": 400 },148{ "quantile": 1, "value": 500 }149]150}]151}152}]153}]154}]155}`,156expect: `157# TYPE test_metric_seconds summary158test_metric_seconds{quantile="0.0"} 100.0159test_metric_seconds{quantile="0.25"} 200.0160test_metric_seconds{quantile="0.5"} 300.0161test_metric_seconds{quantile="0.75"} 400.0162test_metric_seconds{quantile="1.0"} 500.0163test_metric_seconds_sum 100.0164test_metric_seconds_count 333165`,166},167{168name: "Timestamps",169input: `{170"resource_metrics": [{171"scope_metrics": [{172"metrics": [{173"name": "test_metric_seconds",174"gauge": {175"data_points": [{176"start_time_unix_nano": 1000000000,177"time_unix_nano": 1000000000,178"as_double": 1234.56179}]180}181}]182}]183}]184}`,185showTimestamps: true,186expect: `187# TYPE test_metric_seconds gauge188test_metric_seconds 1234.56 1.0189`,190},191{192name: "Labels from resource attributes",193input: `{194"resource_metrics": [{195"resource": {196"attributes": [{197"key": "service.name",198"value": { "stringValue": "myservice" }199}, {200"key": "service.instance.id",201"value": { "stringValue": "instance" }202}, {203"key": "do_not_display",204"value": { "stringValue": "test" }205}]206},207"scope_metrics": [{208"metrics": [{209"name": "test_metric_seconds",210"gauge": {211"data_points": [{212"as_double": 1234.56213}]214}215}]216}]217}]218}`,219expect: `220# TYPE test_metric_seconds gauge221test_metric_seconds{instance="instance",job="myservice"} 1234.56222`,223},224{225name: "Labels from scope name and version",226input: `{227"resource_metrics": [{228"scope_metrics": [{229"scope": {230"name": "a-name",231"version": "a-version",232"attributes": [{233"key": "something.extra",234"value": { "stringValue": "zzz-extra-value" }235}]236},237"metrics": [{238"name": "test_metric_seconds",239"gauge": {240"data_points": [{241"as_double": 1234.56242}]243}244}]245}]246}]247}`,248includeScopeInfo: true,249expect: `250# TYPE otel_scope_info gauge251otel_scope_info{name="a-name",version="a-version",something_extra="zzz-extra-value"} 1.0252# TYPE test_metric_seconds gauge253test_metric_seconds{otel_scope_name="a-name",otel_scope_version="a-version"} 1234.56254`,255},256{257name: "Labels from data point",258input: `{259"resource_metrics": [{260"scope_metrics": [{261"metrics": [{262"name": "test_metric_seconds",263"gauge": {264"data_points": [{265"attributes": [{266"key": "foo",267"value": { "stringValue": "bar" }268}],269"as_double": 1234.56270}]271}272}]273}]274}]275}`,276expect: `277# TYPE test_metric_seconds gauge278test_metric_seconds{foo="bar"} 1234.56279`,280},281{282name: "Target info metric",283input: `{284"resource_metrics": [{285"resource": {286"attributes": [{287"key": "service.name",288"value": { "stringValue": "myservice" }289}, {290"key": "service.instance.id",291"value": { "stringValue": "instance" }292}, {293"key": "custom_attr",294"value": { "stringValue": "test" }295}]296},297"scope_metrics": [{298"metrics": [{299"name": "test_metric_seconds",300"gauge": {301"data_points": [{302"as_double": 1234.56303}]304}305}]306}]307}]308}`,309includeTargetInfo: true,310expect: `311# HELP target_info Target metadata312# TYPE target_info gauge313target_info{instance="instance",job="myservice",custom_attr="test"} 1.0314# TYPE test_metric_seconds gauge315test_metric_seconds{instance="instance",job="myservice"} 1234.56316`,317},318}319320decoder := &pmetric.JSONUnmarshaler{}321for _, tc := range tt {322t.Run(tc.name, func(t *testing.T) {323payload, err := decoder.UnmarshalMetrics([]byte(tc.input))324require.NoError(t, err)325326var app testappender.Appender327app.HideTimestamps = !tc.showTimestamps328329l := util.TestLogger(t)330conv := convert.New(l, appenderAppendable{Inner: &app}, convert.Options{331IncludeTargetInfo: tc.includeTargetInfo,332IncludeScopeInfo: tc.includeScopeInfo,333})334require.NoError(t, conv.ConsumeMetrics(context.Background(), payload))335336families, err := app.MetricFamilies()337require.NoError(t, err)338339c := testappender.Comparer{OpenMetrics: true}340require.NoError(t, c.Compare(families, tc.expect))341})342}343}344345// appenderAppendable always returns the same Appender.346type appenderAppendable struct {347Inner storage.Appender348}349350var _ storage.Appendable = appenderAppendable{}351352func (aa appenderAppendable) Appender(context.Context) storage.Appender {353return aa.Inner354}355356357