diff --git a/comp/otelcol/otlp/components/exporter/serializerexporter/consumer.go b/comp/otelcol/otlp/components/exporter/serializerexporter/consumer.go index 945b743771e894..e4a8bed35a223c 100644 --- a/comp/otelcol/otlp/components/exporter/serializerexporter/consumer.go +++ b/comp/otelcol/otlp/components/exporter/serializerexporter/consumer.go @@ -25,6 +25,52 @@ import ( "github.com/tinylib/msgp/msgp" ) +var metricOriginsMappings = map[otlpmetrics.OriginProductDetail]metrics.MetricSource{ + otlpmetrics.OriginProductDetailUnknown: metrics.MetricSourceOpenTelemetryCollectorUnknown, + otlpmetrics.OriginProductDetailDockerStatsReceiver: metrics.MetricSourceOpenTelemetryCollectorDockerstatsReceiver, + otlpmetrics.OriginProductDetailElasticsearchReceiver: metrics.MetricSourceOpenTelemetryCollectorElasticsearchReceiver, + otlpmetrics.OriginProductDetailExpVarReceiver: metrics.MetricSourceOpenTelemetryCollectorExpvarReceiver, + otlpmetrics.OriginProductDetailFileStatsReceiver: metrics.MetricSourceOpenTelemetryCollectorFilestatsReceiver, + otlpmetrics.OriginProductDetailFlinkMetricsReceiver: metrics.MetricSourceOpenTelemetryCollectorFlinkmetricsReceiver, + otlpmetrics.OriginProductDetailGitProviderReceiver: metrics.MetricSourceOpenTelemetryCollectorGitproviderReceiver, + otlpmetrics.OriginProductDetailHAProxyReceiver: metrics.MetricSourceOpenTelemetryCollectorHaproxyReceiver, + otlpmetrics.OriginProductDetailHostMetricsReceiver: metrics.MetricSourceOpenTelemetryCollectorHostmetricsReceiver, + otlpmetrics.OriginProductDetailHTTPCheckReceiver: metrics.MetricSourceOpenTelemetryCollectorHttpcheckReceiver, + otlpmetrics.OriginProductDetailIISReceiver: metrics.MetricSourceOpenTelemetryCollectorIisReceiver, + otlpmetrics.OriginProductDetailK8SClusterReceiver: metrics.MetricSourceOpenTelemetryCollectorK8sclusterReceiver, + otlpmetrics.OriginProductDetailKafkaMetricsReceiver: metrics.MetricSourceOpenTelemetryCollectorKafkametricsReceiver, + otlpmetrics.OriginProductDetailKubeletStatsReceiver: metrics.MetricSourceOpenTelemetryCollectorKubeletstatsReceiver, + otlpmetrics.OriginProductDetailMemcachedReceiver: metrics.MetricSourceOpenTelemetryCollectorMemcachedReceiver, + otlpmetrics.OriginProductDetailMongoDBAtlasReceiver: metrics.MetricSourceOpenTelemetryCollectorMongodbatlasReceiver, + otlpmetrics.OriginProductDetailMongoDBReceiver: metrics.MetricSourceOpenTelemetryCollectorMongodbReceiver, + otlpmetrics.OriginProductDetailMySQLReceiver: metrics.MetricSourceOpenTelemetryCollectorMysqlReceiver, + otlpmetrics.OriginProductDetailNginxReceiver: metrics.MetricSourceOpenTelemetryCollectorNginxReceiver, + otlpmetrics.OriginProductDetailNSXTReceiver: metrics.MetricSourceOpenTelemetryCollectorNsxtReceiver, + otlpmetrics.OriginProductDetailOracleDBReceiver: metrics.MetricSourceOpenTelemetryCollectorOracledbReceiver, + otlpmetrics.OriginProductDetailPostgreSQLReceiver: metrics.MetricSourceOpenTelemetryCollectorPostgresqlReceiver, + otlpmetrics.OriginProductDetailPrometheusReceiver: metrics.MetricSourceOpenTelemetryCollectorPrometheusReceiver, + otlpmetrics.OriginProductDetailRabbitMQReceiver: metrics.MetricSourceOpenTelemetryCollectorRabbitmqReceiver, + otlpmetrics.OriginProductDetailRedisReceiver: metrics.MetricSourceOpenTelemetryCollectorRedisReceiver, + otlpmetrics.OriginProductDetailRiakReceiver: metrics.MetricSourceOpenTelemetryCollectorRiakReceiver, + otlpmetrics.OriginProductDetailSAPHANAReceiver: metrics.MetricSourceOpenTelemetryCollectorSaphanaReceiver, + otlpmetrics.OriginProductDetailSNMPReceiver: metrics.MetricSourceOpenTelemetryCollectorSnmpReceiver, + otlpmetrics.OriginProductDetailSnowflakeReceiver: metrics.MetricSourceOpenTelemetryCollectorSnowflakeReceiver, + otlpmetrics.OriginProductDetailSplunkEnterpriseReceiver: metrics.MetricSourceOpenTelemetryCollectorSplunkenterpriseReceiver, + otlpmetrics.OriginProductDetailSQLServerReceiver: metrics.MetricSourceOpenTelemetryCollectorSqlserverReceiver, + otlpmetrics.OriginProductDetailSSHCheckReceiver: metrics.MetricSourceOpenTelemetryCollectorSshcheckReceiver, + otlpmetrics.OriginProductDetailStatsDReceiver: metrics.MetricSourceOpenTelemetryCollectorStatsdReceiver, + otlpmetrics.OriginProductDetailVCenterReceiver: metrics.MetricSourceOpenTelemetryCollectorVcenterReceiver, + otlpmetrics.OriginProductDetailZookeeperReceiver: metrics.MetricSourceOpenTelemetryCollectorZookeeperReceiver, + otlpmetrics.OriginProductDetailActiveDirectoryDSReceiver: metrics.MetricSourceOpenTelemetryCollectorActiveDirectorydsReceiver, + otlpmetrics.OriginProductDetailAerospikeReceiver: metrics.MetricSourceOpenTelemetryCollectorAerospikeReceiver, + otlpmetrics.OriginProductDetailApacheReceiver: metrics.MetricSourceOpenTelemetryCollectorApacheReceiver, + otlpmetrics.OriginProductDetailApacheSparkReceiver: metrics.MetricSourceOpenTelemetryCollectorApachesparkReceiver, + otlpmetrics.OriginProductDetailAzureMonitorReceiver: metrics.MetricSourceOpenTelemetryCollectorAzuremonitorReceiver, + otlpmetrics.OriginProductDetailBigIPReceiver: metrics.MetricSourceOpenTelemetryCollectorBigipReceiver, + otlpmetrics.OriginProductDetailChronyReceiver: metrics.MetricSourceOpenTelemetryCollectorChronyReceiver, + otlpmetrics.OriginProductDetailCouchDBReceiver: metrics.MetricSourceOpenTelemetryCollectorCouchdbReceiver, +} + var _ otlpmetrics.Consumer = (*serializerConsumer)(nil) type serializerConsumer struct { @@ -48,6 +94,10 @@ func (c *serializerConsumer) ConsumeAPMStats(ss *pb.ClientStatsPayload) { } func (c *serializerConsumer) ConsumeSketch(ctx context.Context, dimensions *otlpmetrics.Dimensions, ts uint64, qsketch *quantile.Sketch) { + msrc, ok := metricOriginsMappings[dimensions.OriginProductDetail()] + if !ok { + msrc = metrics.MetricSourceOpenTelemetryCollectorUnknown + } c.sketches = append(c.sketches, &metrics.SketchSeries{ Name: dimensions.Name(), Tags: tagset.CompositeTagsFromSlice(c.enricher.Enrich(ctx, c.extraTags, dimensions)), @@ -57,6 +107,7 @@ func (c *serializerConsumer) ConsumeSketch(ctx context.Context, dimensions *otlp Ts: int64(ts / 1e9), Sketch: qsketch, }}, + Source: msrc, }) } @@ -71,6 +122,10 @@ func apiTypeFromTranslatorType(typ otlpmetrics.DataType) metrics.APIMetricType { } func (c *serializerConsumer) ConsumeTimeSeries(ctx context.Context, dimensions *otlpmetrics.Dimensions, typ otlpmetrics.DataType, ts uint64, value float64) { + msrc, ok := metricOriginsMappings[dimensions.OriginProductDetail()] + if !ok { + msrc = metrics.MetricSourceOpenTelemetryCollectorUnknown + } c.series = append(c.series, &metrics.Serie{ Name: dimensions.Name(), @@ -79,6 +134,7 @@ func (c *serializerConsumer) ConsumeTimeSeries(ctx context.Context, dimensions * Host: dimensions.Host(), MType: apiTypeFromTranslatorType(typ), Interval: 0, // OTLP metrics do not have an interval. + Source: msrc, }, ) } diff --git a/comp/otelcol/otlp/components/exporter/serializerexporter/exporter_test.go b/comp/otelcol/otlp/components/exporter/serializerexporter/exporter_test.go index d5588e36cadbee..9b78b6a002632b 100644 --- a/comp/otelcol/otlp/components/exporter/serializerexporter/exporter_test.go +++ b/comp/otelcol/otlp/components/exporter/serializerexporter/exporter_test.go @@ -54,13 +54,14 @@ func (r *metricRecorder) SendIterableSeries(s metrics.SerieSource) error { return nil } +const ( + histogramMetricName = "test.histogram" + numberMetricName = "test.gauge" + histogramRuntimeMetricName = "process.runtime.dotnet.exceptions.count" + numberRuntimeMetricName = "process.runtime.go.goroutines" +) + func Test_ConsumeMetrics_Tags(t *testing.T) { - const ( - histogramMetricName = "test.histogram" - numberMetricName = "test.gauge" - histogramRuntimeMetricName = "process.runtime.dotnet.exceptions.count" - numberRuntimeMetricName = "process.runtime.go.goroutines" - ) tests := []struct { name string genMetrics func(t *testing.T) pmetric.Metrics @@ -218,6 +219,110 @@ func Test_ConsumeMetrics_Tags(t *testing.T) { } } +func Test_ConsumeMetrics_MetricOrigins(t *testing.T) { + tests := []struct { + name string + genMetrics func(t *testing.T) pmetric.Metrics + msrc metrics.MetricSource + }{ + { + name: "metric origin in sketches", + genMetrics: func(_ *testing.T) pmetric.Metrics { + md := pmetric.NewMetrics() + rms := md.ResourceMetrics() + rm := rms.AppendEmpty() + ilms := rm.ScopeMetrics() + ilm := ilms.AppendEmpty() + ilm.Scope().SetName("otelcol/hostmetricsreceiver/memory") + metricsArray := ilm.Metrics() + met := metricsArray.AppendEmpty() + met.SetName(histogramMetricName) + met.SetEmptyHistogram() + met.Histogram().SetAggregationTemporality(pmetric.AggregationTemporalityDelta) + hdps := met.Histogram().DataPoints() + hdp := hdps.AppendEmpty() + hdp.BucketCounts().FromRaw([]uint64{100}) + hdp.SetCount(100) + hdp.SetSum(0) + return md + }, + msrc: metrics.MetricSourceOpenTelemetryCollectorHostmetricsReceiver, + }, + { + name: "metric origin in timeseries", + genMetrics: func(_ *testing.T) pmetric.Metrics { + md := pmetric.NewMetrics() + rms := md.ResourceMetrics() + rm := rms.AppendEmpty() + ilms := rm.ScopeMetrics() + ilm := ilms.AppendEmpty() + ilm.Scope().SetName("otelcol/kubeletstatsreceiver") + metricsArray := ilm.Metrics() + met := metricsArray.AppendEmpty() + met.SetName(numberMetricName) + met.SetEmptyGauge() + gdps := met.Gauge().DataPoints() + gdp := gdps.AppendEmpty() + gdp.SetIntValue(100) + return md + }, + msrc: metrics.MetricSourceOpenTelemetryCollectorKubeletstatsReceiver, + }, + { + name: "unknown metric origin", + genMetrics: func(_ *testing.T) pmetric.Metrics { + md := pmetric.NewMetrics() + rms := md.ResourceMetrics() + rm := rms.AppendEmpty() + ilms := rm.ScopeMetrics() + ilm := ilms.AppendEmpty() + ilm.Scope().SetName("otelcol/myreceiver") + metricsArray := ilm.Metrics() + met := metricsArray.AppendEmpty() + met.SetName(numberMetricName) + met.SetEmptyGauge() + gdps := met.Gauge().DataPoints() + gdp := gdps.AppendEmpty() + gdp.SetIntValue(100) + return md + }, + msrc: metrics.MetricSourceOpenTelemetryCollectorUnknown, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rec := &metricRecorder{} + ctx := context.Background() + f := NewFactory(rec, &MockTagEnricher{}, func(context.Context) (string, error) { + return "", nil + }, nil, nil) + cfg := f.CreateDefaultConfig().(*ExporterConfig) + exp, err := f.CreateMetrics( + ctx, + exportertest.NewNopSettings(), + cfg, + ) + require.NoError(t, err) + require.NoError(t, exp.Start(ctx, componenttest.NewNopHost())) + require.NoError(t, exp.ConsumeMetrics(ctx, tt.genMetrics(t))) + require.NoError(t, exp.Shutdown(ctx)) + + for _, serie := range rec.series { + if serie.Name != numberMetricName { + continue + } + assert.Equal(t, serie.Source, tt.msrc) + } + for _, sketch := range rec.sketchSeriesList { + if sketch.Name != histogramMetricName { + continue + } + assert.Equal(t, sketch.Source, tt.msrc) + } + }) + } +} + func newMetrics( histogramMetricName string, histogramDataPoint pmetric.HistogramDataPoint,