From 4effa79c43a059aa3f1dbd5633197e67b793f84f Mon Sep 17 00:00:00 2001 From: Travis Keep Date: Tue, 5 Oct 2021 15:22:00 -0700 Subject: [PATCH 1/7] [tanzuobservability exporter] Add histogram consumer. --- .../tanzuobservabilityexporter/metrics.go | 212 ++++++++++++- .../metrics_test.go | 291 ++++++++++++++++++ 2 files changed, 498 insertions(+), 5 deletions(-) diff --git a/exporter/tanzuobservabilityexporter/metrics.go b/exporter/tanzuobservabilityexporter/metrics.go index 600330727c26..a147345b6bc0 100644 --- a/exporter/tanzuobservabilityexporter/metrics.go +++ b/exporter/tanzuobservabilityexporter/metrics.go @@ -18,6 +18,7 @@ import ( "context" "errors" "fmt" + "strconv" "sync/atomic" "github.com/wavefronthq/wavefront-sdk-go/senders" @@ -27,14 +28,18 @@ import ( ) const ( - missingValueMetricName = "~sdk.otel.collector.missing_values" - metricNameString = "metric name" - metricTypeString = "metric type" + missingValueMetricName = "~sdk.otel.collector.missing_values" + metricNameString = "metric name" + metricTypeString = "metric type" + malformedHistogramMetricName = "~sdk.otel.collector.malformed_histogram" + leInUseMetricName = "~sdk.otel.collector.le_tag_in_use" + noAggregationTemporalityMetricName = "~sdk.otel.collector.no_aggregation_temporality" ) var ( - typeIsGaugeTags = map[string]string{"type": "gauge"} - typeIsSumTags = map[string]string{"type": "sum"} + typeIsGaugeTags = map[string]string{"type": "gauge"} + typeIsSumTags = map[string]string{"type": "sum"} + typeIsHistogramTags = map[string]string{"type": "histogram"} ) // metricsConsumer instances consume OTEL metrics @@ -345,3 +350,200 @@ func (s *sumConsumer) pushNumberDataPoint( *errs = append(*errs, err) } } + +// histogramReporting takes care of logging and internal metrics for histograms +type histogramReporting struct { + logger *zap.Logger + malformedHistograms counter + leInUse counter + noAggregationTemporality counter +} + +// newHistogramReporting returns a new histogramReporting instance. +// logger is the logger to use. +func newHistogramReporting(logger *zap.Logger) *histogramReporting { + return &histogramReporting{logger: logger} +} + +// Malformed returns the number of malformed histogram data points. +func (r *histogramReporting) Malformed() int64 { + return r.malformedHistograms.Get() +} + +// LeTagInUse returns the number of histogram data points already using the 'le' +// tag. +func (r *histogramReporting) LeTagInUse() int64 { + return r.leInUse.Get() +} + +// NoAggregationTemporality returns the number of histogram metrics that have no +// aggregation temporality. +func (r *histogramReporting) NoAggregationTemporality() int64 { + return r.noAggregationTemporality.Get() +} + +// LogMalformed logs seeing one malformed data point. +func (r *histogramReporting) LogMalformed(metric pdata.Metric) { + namef := zap.String(metricNameString, metric.Name()) + r.logger.Debug("Malformed histogram", namef) + r.malformedHistograms.Inc() +} + +// LogLeTagInUse logs seeing one data point using the 'le' tag +func (r *histogramReporting) LogLeTagInUse(metric pdata.Metric) { + namef := zap.String(metricNameString, metric.Name()) + r.logger.Debug("le tag already in use", namef) + r.leInUse.Inc() +} + +// LogNoAggregationTemporality logs seeing a histogram metric with no aggregation temporality +func (r *histogramReporting) LogNoAggregationTemporality(metric pdata.Metric) { + namef := zap.String(metricNameString, metric.Name()) + r.logger.Debug("histogram metric missing aggregation temporality", namef) + r.noAggregationTemporality.Inc() +} + +// Report sends the counts in this instancce to wavefront. +// sender is what sends to wavefront. Any errors sending get added to errs. +func (r *histogramReporting) Report(sender gaugeSender, errs *[]error) { + r.malformedHistograms.Report(malformedHistogramMetricName, nil, sender, errs) + r.leInUse.Report(leInUseMetricName, nil, sender, errs) + r.noAggregationTemporality.Report( + noAggregationTemporalityMetricName, + typeIsHistogramTags, + sender, + errs) +} + +type histogramConsumer struct { + cumulative histogramDataPointConsumer + delta histogramDataPointConsumer + sender gaugeSender + reporting *histogramReporting + reportInternalMetrics bool +} + +// newHistogramConsumer returns a metricConsumer that consumes histograms. +// cumulative and delta handle cumulative and delta histograms respectively. +// sender sends internal metrics to wavefront. Caller can pass nil for +// options to get the defaults. +func newHistogramConsumer( + cumulative, delta histogramDataPointConsumer, + sender gaugeSender, + options *consumerOptions, +) typedMetricConsumer { + var fixedOptions consumerOptions + if options != nil { + fixedOptions = *options + } + fixedOptions.replaceZeroFieldsWithDefaults() + return &histogramConsumer{ + cumulative: cumulative, + delta: delta, + sender: sender, + reporting: newHistogramReporting(fixedOptions.Logger), + reportInternalMetrics: fixedOptions.ReportInternalMetrics, + } +} + +func (h *histogramConsumer) Type() pdata.MetricDataType { + return pdata.MetricDataTypeHistogram +} + +func (h *histogramConsumer) Consume(metric pdata.Metric, errs *[]error) { + histogram := metric.Histogram() + aggregationTemporality := histogram.AggregationTemporality() + var consumer histogramDataPointConsumer + switch aggregationTemporality { + case pdata.MetricAggregationTemporalityDelta: + if h.delta == nil { + *errs = append(*errs, errors.New("delta histograms not supported")) + return + } + consumer = h.delta + case pdata.MetricAggregationTemporalityCumulative: + if h.cumulative == nil { + *errs = append(*errs, errors.New("cumulative histograms not supported")) + return + } + consumer = h.cumulative + default: + h.reporting.LogNoAggregationTemporality(metric) + return + } + histogramDataPoints := histogram.DataPoints() + for i := 0; i < histogramDataPoints.Len(); i++ { + consumer.Consume(metric, histogramDataPoints.At(i), errs, h.reporting) + } +} + +func (h *histogramConsumer) PushInternalMetrics(errs *[]error) { + if h.reportInternalMetrics { + h.reporting.Report(h.sender, errs) + } +} + +// histogramDataPointConsumer consumes one histogram data point. There is one +// implementation for delta histograms and one for cumulative histograms. +type histogramDataPointConsumer interface { + + // Consume consumes the histogram data point. + // metric is the enclosing metric; histogram is the histogram data point; + // errors get appended to errs; reporting keeps track of special situations + Consume( + metric pdata.Metric, + histogram pdata.HistogramDataPoint, + errs *[]error, + reporting *histogramReporting, + ) +} + +type cumulativeHistogramDataPointConsumer struct { + sender gaugeSender +} + +// newCumulativeHistogramDataPointConsumer returns a consumer for cumulative +// histogram data points. +func newCumulativeHistogramDataPointConsumer(sender gaugeSender) histogramDataPointConsumer { + return &cumulativeHistogramDataPointConsumer{sender: sender} +} + +func (c *cumulativeHistogramDataPointConsumer) Consume( + metric pdata.Metric, + h pdata.HistogramDataPoint, + errs *[]error, + reporting *histogramReporting, +) { + name := metric.Name() + tags := attributesToTags(h.Attributes()) + ts := h.Timestamp().AsTime().Unix() + explicitBounds := h.ExplicitBounds() + bucketCounts := h.BucketCounts() + var abort bool + if len(bucketCounts) != len(explicitBounds)+1 { + reporting.LogMalformed(metric) + abort = true + } + if _, ok := tags["le"]; ok { + reporting.LogLeTagInUse(metric) + abort = true + } + if abort { + return + } + bucketCountLen := len(bucketCounts) + for i := 0; i < bucketCountLen; i++ { + tags["le"] = leTagValue(explicitBounds, i) + err := c.sender.SendMetric(name, float64(bucketCounts[i]), ts, "", tags) + if err != nil { + *errs = append(*errs, err) + } + } +} + +func leTagValue(explicitBounds []float64, idx int) string { + if idx == len(explicitBounds) { + return "+Inf" + } + return strconv.FormatFloat(explicitBounds[idx], 'f', -1, 64) +} diff --git a/exporter/tanzuobservabilityexporter/metrics_test.go b/exporter/tanzuobservabilityexporter/metrics_test.go index a713c7d66b40..f9c052b1497d 100644 --- a/exporter/tanzuobservabilityexporter/metrics_test.go +++ b/exporter/tanzuobservabilityexporter/metrics_test.go @@ -393,6 +393,285 @@ func TestSumConsumerMissingValue(t *testing.T) { assert.Len(t, allLogs, expectedMissingValueCount) } +// Tests that the histogramConsumer correctly delegates to its +// histogramDataPointConsumers. This tests no cumulative histogram +// datapoint consumer. +func TestHistogramConsumerDeltaAggregation(t *testing.T) { + countAttributeForEachDataPoint := []uint64{2, 5, 10} + deltaMetric := newHistogramMetricWithDataPoints( + "delta.metric", + pdata.MetricAggregationTemporalityDelta, + countAttributeForEachDataPoint) + cumulativeMetric := newHistogramMetricWithDataPoints( + "cum.metric", + pdata.MetricAggregationTemporalityCumulative, + countAttributeForEachDataPoint) + sender := &mockGaugeSender{} + deltaConsumer := &mockHistogramDataPointConsumer{} + + // We pass nil for the cumulative histogram data point consumer so + // sending a cumulative histogram metric will generate an error. + consumer := newHistogramConsumer( + nil, deltaConsumer, sender, nil) + var errs []error + + consumer.Consume(deltaMetric, &errs) + consumer.Consume(cumulativeMetric, &errs) // generates an error + consumer.PushInternalMetrics(&errs) // A no-op + + assert.Len(t, errs, 1) + + // We had three datapoints. Our mock just captures the metric name + // of each data point consumed. + assert.Equal( + t, []string{"delta.metric", "delta.metric", "delta.metric"}, deltaConsumer.names) + assert.Equal(t, countAttributeForEachDataPoint, deltaConsumer.counts) +} + +// Tests that the histogramConsumer correctly delegates to its +// histogramDataPointConsumers. This tests no delta histogram +// datapoint consumer. +func TestHistogramConsumerCumulativeAggregation(t *testing.T) { + countAttributeForEachDataPoint := []uint64{2, 5, 10} + deltaMetric := newHistogramMetricWithDataPoints( + "delta.metric", + pdata.MetricAggregationTemporalityDelta, + countAttributeForEachDataPoint) + cumulativeMetric := newHistogramMetricWithDataPoints( + "cum.metric", + pdata.MetricAggregationTemporalityCumulative, + countAttributeForEachDataPoint) + sender := &mockGaugeSender{} + cumulativeConsumer := &mockHistogramDataPointConsumer{} + + // We pass nil for the delta histogram data point consumer so + // sending a delta histogram metric will generate an error. + consumer := newHistogramConsumer( + cumulativeConsumer, nil, sender, nil) + var errs []error + + consumer.Consume(deltaMetric, &errs) // generates an error + consumer.Consume(cumulativeMetric, &errs) + consumer.PushInternalMetrics(&errs) // A no-op + + assert.Len(t, errs, 1) + + // We had three datapoints. Our mock just captures the metric name of + // each data point consumed. + assert.Equal( + t, []string{"cum.metric", "cum.metric", "cum.metric"}, cumulativeConsumer.names) + assert.Equal(t, countAttributeForEachDataPoint, cumulativeConsumer.counts) +} + +// This tests that the histogram consumer correctly counts and logs +// histogram metrics with missing aggregation attribute. +func TestHistogramConsumerNoAggregation(t *testing.T) { + + // Create a histogram metric with missing aggregation attribute + metric := newHistogramMetricWithDataPoints( + "bad.metric", pdata.MetricAggregationTemporalityUnspecified, nil) + sender := &mockGaugeSender{} + observedZapCore, observedLogs := observer.New(zap.DebugLevel) + consumer := newHistogramConsumer( + nil, + nil, + sender, + &consumerOptions{ + Logger: zap.New(observedZapCore), + ReportInternalMetrics: true, + }, + ) + + assert.Equal(t, pdata.MetricDataTypeHistogram, consumer.Type()) + var errs []error + expectedNoAggregationCount := 3 + for i := 0; i < expectedNoAggregationCount; i++ { + consumer.Consume(metric, &errs) + } + consumer.PushInternalMetrics(&errs) + + assert.Len(t, errs, 0) + assert.Contains(t, sender.metrics, tobsMetric{ + Name: noAggregationTemporalityMetricName, + Value: float64(expectedNoAggregationCount), + Tags: map[string]string{"type": "histogram"}}) + allLogs := observedLogs.All() + assert.Len(t, allLogs, expectedNoAggregationCount) +} + +func TestHistogramReporting(t *testing.T) { + observedZapCore, observedLogs := observer.New(zap.DebugLevel) + report := newHistogramReporting(zap.New(observedZapCore)) + metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) + leTagInUseCount := 2 + for i := 0; i < leTagInUseCount; i++ { + report.LogLeTagInUse(metric) + } + malformedCount := 3 + for i := 0; i < malformedCount; i++ { + report.LogMalformed(metric) + } + noAggregationTemporalityCount := 5 + for i := 0; i < noAggregationTemporalityCount; i++ { + report.LogNoAggregationTemporality(metric) + } + + assert.Equal(t, int64(leTagInUseCount), report.LeTagInUse()) + assert.Equal(t, int64(malformedCount), report.Malformed()) + assert.Equal(t, int64(noAggregationTemporalityCount), report.NoAggregationTemporality()) + assert.Equal( + t, + leTagInUseCount+malformedCount+noAggregationTemporalityCount, + observedLogs.Len()) + + sender := &mockGaugeSender{} + var errs []error + + report.Report(sender, &errs) + + assert.Empty(t, errs) + assert.Contains( + t, + sender.metrics, + tobsMetric{ + Name: leInUseMetricName, + Value: float64(leTagInUseCount), + }) + assert.Contains( + t, + sender.metrics, + tobsMetric{ + Name: malformedHistogramMetricName, + Value: float64(malformedCount), + }) + assert.Contains( + t, + sender.metrics, + tobsMetric{ + Name: noAggregationTemporalityMetricName, + Value: float64(noAggregationTemporalityCount), + Tags: typeIsHistogramTags, + }) +} + +func TestHistogramReportingError(t *testing.T) { + report := newHistogramReporting(zap.NewNop()) + sender := &mockGaugeSender{errorOnSend: true} + var errs []error + + report.Report(sender, &errs) + + assert.NotEmpty(t, errs) +} + +func TestCumulativeHistogramDataPointConsumer(t *testing.T) { + verifyCumulativeHistogramDataPointConsumer(t, false) +} + +func TestCumulativeHistogramDataPointConsumerError(t *testing.T) { + verifyCumulativeHistogramDataPointConsumer(t, true) +} + +func TestCumulativeHistogramDataPointConsumerLeInUse(t *testing.T) { + metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) + histogramDataPoint := pdata.NewHistogramDataPoint() + histogramDataPoint.SetBucketCounts([]uint64{4, 12}) + histogramDataPoint.SetExplicitBounds([]float64{10.0}) + setTags(map[string]interface{}{"le": 8}, histogramDataPoint.Attributes()) + sender := &mockGaugeSender{} + report := newHistogramReporting(zap.NewNop()) + consumer := newCumulativeHistogramDataPointConsumer(sender) + var errs []error + + consumer.Consume(metric, histogramDataPoint, &errs, report) + + assert.Empty(t, errs) + assert.Empty(t, sender.metrics) + assert.Equal(t, int64(1), report.LeTagInUse()) + assert.Equal(t, int64(0), report.Malformed()) +} + +func TestCumulativeHistogramDataPointConsumerMissingBuckets(t *testing.T) { + metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) + histogramDataPoint := pdata.NewHistogramDataPoint() + sender := &mockGaugeSender{} + report := newHistogramReporting(zap.NewNop()) + consumer := newCumulativeHistogramDataPointConsumer(sender) + var errs []error + + consumer.Consume(metric, histogramDataPoint, &errs, report) + + assert.Empty(t, errs) + assert.Empty(t, sender.metrics) + assert.Equal(t, int64(1), report.Malformed()) + assert.Equal(t, int64(0), report.LeTagInUse()) +} + +// Creates a histogram metric with len(countAttributeForEachDataPoint) +// datapoints. name is the name of the histogram metric; temporality +// is the temporality of the histogram metric; +// countAttributeForEachDataPoint contains the count attribute for each +// data point. +func newHistogramMetricWithDataPoints( + name string, + temporality pdata.MetricAggregationTemporality, + countAttributeForEachDataPoint []uint64, +) pdata.Metric { + result := newMetric(name, pdata.MetricDataTypeHistogram) + histogram := result.Histogram() + histogram.SetAggregationTemporality(temporality) + histogram.DataPoints().EnsureCapacity(len(countAttributeForEachDataPoint)) + for _, count := range countAttributeForEachDataPoint { + histogram.DataPoints().AppendEmpty().SetCount(count) + } + return result +} + +func verifyCumulativeHistogramDataPointConsumer(t *testing.T, errorOnSend bool) { + metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) + histogramDataPoint := pdata.NewHistogramDataPoint() + histogramDataPoint.SetBucketCounts([]uint64{2, 3, 5, 7}) + histogramDataPoint.SetExplicitBounds([]float64{2.0, 5.0, 10.0}) + setTags(map[string]interface{}{"foo": "bar"}, histogramDataPoint.Attributes()) + sender := &mockGaugeSender{errorOnSend: errorOnSend} + report := newHistogramReporting(zap.NewNop()) + consumer := newCumulativeHistogramDataPointConsumer(sender) + var errs []error + + consumer.Consume(metric, histogramDataPoint, &errs, report) + + if !errorOnSend { + assert.Empty(t, errs) + } else { + assert.Len(t, errs, len(sender.metrics)) + } + assert.Equal( + t, + []tobsMetric{ + { + Name: "a.metric", + Value: 2.0, + Tags: map[string]string{"foo": "bar", "le": "2"}, + }, + { + Name: "a.metric", + Value: 3.0, + Tags: map[string]string{"foo": "bar", "le": "5"}, + }, + { + Name: "a.metric", + Value: 5.0, + Tags: map[string]string{"foo": "bar", "le": "10"}, + }, + { + Name: "a.metric", + Value: 7.0, + Tags: map[string]string{"foo": "bar", "le": "+Inf"}, + }, + }, + sender.metrics) +} + func verifyGaugeConsumer(t *testing.T, errorOnSend bool) { metric := newMetric("test.metric", pdata.MetricDataTypeGauge) dataPoints := metric.Gauge().DataPoints() @@ -583,6 +862,18 @@ func (m *mockFlushCloser) Close() { m.numCloseCalls++ } +type mockHistogramDataPointConsumer struct { + names []string + counts []uint64 +} + +func (m *mockHistogramDataPointConsumer) Consume( + metric pdata.Metric, h pdata.HistogramDataPoint, _ *[]error, _ *histogramReporting, +) { + m.names = append(m.names, metric.Name()) + m.counts = append(m.counts, h.Count()) +} + func copyTags(tags map[string]string) map[string]string { if tags == nil { return nil From be5bca3eca2b813640f7c8c06202d0dd2ab17bb2 Mon Sep 17 00:00:00 2001 From: Travis Keep Date: Wed, 24 Nov 2021 13:10:21 -0800 Subject: [PATCH 2/7] Get rid of support for nil histogramDataPointConsumers. Use for..range where possible. Sum up bucket counts for wavefront. Make tests easier to read. --- .../tanzuobservabilityexporter/metrics.go | 19 +-- .../metrics_test.go | 153 ++++++++---------- 2 files changed, 76 insertions(+), 96 deletions(-) diff --git a/exporter/tanzuobservabilityexporter/metrics.go b/exporter/tanzuobservabilityexporter/metrics.go index a147345b6bc0..519cc0b3d62f 100644 --- a/exporter/tanzuobservabilityexporter/metrics.go +++ b/exporter/tanzuobservabilityexporter/metrics.go @@ -456,16 +456,10 @@ func (h *histogramConsumer) Consume(metric pdata.Metric, errs *[]error) { var consumer histogramDataPointConsumer switch aggregationTemporality { case pdata.MetricAggregationTemporalityDelta: - if h.delta == nil { - *errs = append(*errs, errors.New("delta histograms not supported")) - return - } - consumer = h.delta + // TODO: follow-on pull request will add support for Delta Histograms. + *errs = append(*errs, errors.New("delta histograms not supported")) + return case pdata.MetricAggregationTemporalityCumulative: - if h.cumulative == nil { - *errs = append(*errs, errors.New("cumulative histograms not supported")) - return - } consumer = h.cumulative default: h.reporting.LogNoAggregationTemporality(metric) @@ -531,10 +525,11 @@ func (c *cumulativeHistogramDataPointConsumer) Consume( if abort { return } - bucketCountLen := len(bucketCounts) - for i := 0; i < bucketCountLen; i++ { + var leCount uint64 + for i := range bucketCounts { tags["le"] = leTagValue(explicitBounds, i) - err := c.sender.SendMetric(name, float64(bucketCounts[i]), ts, "", tags) + leCount += bucketCounts[i] + err := c.sender.SendMetric(name, float64(leCount), ts, "", tags) if err != nil { *errs = append(*errs, err) } diff --git a/exporter/tanzuobservabilityexporter/metrics_test.go b/exporter/tanzuobservabilityexporter/metrics_test.go index f9c052b1497d..0901535655c2 100644 --- a/exporter/tanzuobservabilityexporter/metrics_test.go +++ b/exporter/tanzuobservabilityexporter/metrics_test.go @@ -394,67 +394,43 @@ func TestSumConsumerMissingValue(t *testing.T) { } // Tests that the histogramConsumer correctly delegates to its -// histogramDataPointConsumers. This tests no cumulative histogram -// datapoint consumer. +// histogramDataPointConsumers. This tests delta histograms func TestHistogramConsumerDeltaAggregation(t *testing.T) { + // TODO: Change this test when delta histograms are supported. countAttributeForEachDataPoint := []uint64{2, 5, 10} deltaMetric := newHistogramMetricWithDataPoints( "delta.metric", pdata.MetricAggregationTemporalityDelta, countAttributeForEachDataPoint) - cumulativeMetric := newHistogramMetricWithDataPoints( - "cum.metric", - pdata.MetricAggregationTemporalityCumulative, - countAttributeForEachDataPoint) sender := &mockGaugeSender{} - deltaConsumer := &mockHistogramDataPointConsumer{} - - // We pass nil for the cumulative histogram data point consumer so - // sending a cumulative histogram metric will generate an error. + cumulativeConsumer := &mockHistogramDataPointConsumer{} consumer := newHistogramConsumer( - nil, deltaConsumer, sender, nil) + cumulativeConsumer, nil, sender, nil) var errs []error - consumer.Consume(deltaMetric, &errs) - consumer.Consume(cumulativeMetric, &errs) // generates an error - consumer.PushInternalMetrics(&errs) // A no-op - assert.Len(t, errs, 1) - - // We had three datapoints. Our mock just captures the metric name - // of each data point consumed. - assert.Equal( - t, []string{"delta.metric", "delta.metric", "delta.metric"}, deltaConsumer.names) - assert.Equal(t, countAttributeForEachDataPoint, deltaConsumer.counts) + consumer.PushInternalMetrics(&errs) + assert.Len(t, errs, 1) } // Tests that the histogramConsumer correctly delegates to its -// histogramDataPointConsumers. This tests no delta histogram -// datapoint consumer. +// histogramDataPointConsumers. This tests cumulative histograms func TestHistogramConsumerCumulativeAggregation(t *testing.T) { countAttributeForEachDataPoint := []uint64{2, 5, 10} - deltaMetric := newHistogramMetricWithDataPoints( - "delta.metric", - pdata.MetricAggregationTemporalityDelta, - countAttributeForEachDataPoint) cumulativeMetric := newHistogramMetricWithDataPoints( "cum.metric", pdata.MetricAggregationTemporalityCumulative, countAttributeForEachDataPoint) sender := &mockGaugeSender{} cumulativeConsumer := &mockHistogramDataPointConsumer{} - - // We pass nil for the delta histogram data point consumer so - // sending a delta histogram metric will generate an error. consumer := newHistogramConsumer( cumulativeConsumer, nil, sender, nil) var errs []error - consumer.Consume(deltaMetric, &errs) // generates an error consumer.Consume(cumulativeMetric, &errs) - consumer.PushInternalMetrics(&errs) // A no-op + consumer.PushInternalMetrics(&errs) - assert.Len(t, errs, 1) + assert.Empty(t, errs) // We had three datapoints. Our mock just captures the metric name of // each data point consumed. @@ -473,7 +449,7 @@ func TestHistogramConsumerNoAggregation(t *testing.T) { sender := &mockGaugeSender{} observedZapCore, observedLogs := observer.New(zap.DebugLevel) consumer := newHistogramConsumer( - nil, + &mockHistogramDataPointConsumer{}, nil, sender, &consumerOptions{ @@ -481,7 +457,6 @@ func TestHistogramConsumerNoAggregation(t *testing.T) { ReportInternalMetrics: true, }, ) - assert.Equal(t, pdata.MetricDataTypeHistogram, consumer.Type()) var errs []error expectedNoAggregationCount := 3 @@ -494,7 +469,8 @@ func TestHistogramConsumerNoAggregation(t *testing.T) { assert.Contains(t, sender.metrics, tobsMetric{ Name: noAggregationTemporalityMetricName, Value: float64(expectedNoAggregationCount), - Tags: map[string]string{"type": "histogram"}}) + Tags: map[string]string{"type": "histogram"}, + }) allLogs := observedLogs.All() assert.Len(t, allLogs, expectedNoAggregationCount) } @@ -565,18 +541,72 @@ func TestHistogramReportingError(t *testing.T) { } func TestCumulativeHistogramDataPointConsumer(t *testing.T) { - verifyCumulativeHistogramDataPointConsumer(t, false) + metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) + histogramDataPoint := pdata.NewHistogramDataPoint() + + // Creates bounds of -Inf to <=2.0; >2.0 to <=5.0; >5.0 to <=10.0; >10.0 to +Inf + histogramDataPoint.SetExplicitBounds([]float64{2.0, 5.0, 10.0}) + histogramDataPoint.SetBucketCounts([]uint64{5, 1, 3, 2}) + setTags(map[string]interface{}{"foo": "bar"}, histogramDataPoint.Attributes()) + sender := &mockGaugeSender{} + report := newHistogramReporting(zap.NewNop()) + consumer := newCumulativeHistogramDataPointConsumer(sender) + var errs []error + + consumer.Consume(metric, histogramDataPoint, &errs, report) + + assert.Empty(t, errs) + assert.Equal( + t, + []tobsMetric{ + { + Name: "a.metric", + Value: 5.0, + Tags: map[string]string{"foo": "bar", "le": "2"}, + }, + { + Name: "a.metric", + Value: 6.0, + Tags: map[string]string{"foo": "bar", "le": "5"}, + }, + { + Name: "a.metric", + Value: 9.0, + Tags: map[string]string{"foo": "bar", "le": "10"}, + }, + { + Name: "a.metric", + Value: 11.0, + Tags: map[string]string{"foo": "bar", "le": "+Inf"}, + }, + }, + sender.metrics, + ) } func TestCumulativeHistogramDataPointConsumerError(t *testing.T) { - verifyCumulativeHistogramDataPointConsumer(t, true) + metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) + histogramDataPoint := pdata.NewHistogramDataPoint() + + // Creates bounds of -Inf to <=2.0; >2.0 to <=5.0; >5.0 to <=10.0; >10.0 to +Inf + histogramDataPoint.SetExplicitBounds([]float64{2.0, 5.0, 10.0}) + histogramDataPoint.SetBucketCounts([]uint64{5, 1, 3, 2}) + sender := &mockGaugeSender{errorOnSend: true} + report := newHistogramReporting(zap.NewNop()) + consumer := newCumulativeHistogramDataPointConsumer(sender) + var errs []error + + consumer.Consume(metric, histogramDataPoint, &errs, report) + + // We tried to send 4 metrics. We get 4 errors. + assert.Len(t, errs, 4) } func TestCumulativeHistogramDataPointConsumerLeInUse(t *testing.T) { metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) histogramDataPoint := pdata.NewHistogramDataPoint() - histogramDataPoint.SetBucketCounts([]uint64{4, 12}) histogramDataPoint.SetExplicitBounds([]float64{10.0}) + histogramDataPoint.SetBucketCounts([]uint64{4, 12}) setTags(map[string]interface{}{"le": 8}, histogramDataPoint.Attributes()) sender := &mockGaugeSender{} report := newHistogramReporting(zap.NewNop()) @@ -627,51 +657,6 @@ func newHistogramMetricWithDataPoints( return result } -func verifyCumulativeHistogramDataPointConsumer(t *testing.T, errorOnSend bool) { - metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) - histogramDataPoint := pdata.NewHistogramDataPoint() - histogramDataPoint.SetBucketCounts([]uint64{2, 3, 5, 7}) - histogramDataPoint.SetExplicitBounds([]float64{2.0, 5.0, 10.0}) - setTags(map[string]interface{}{"foo": "bar"}, histogramDataPoint.Attributes()) - sender := &mockGaugeSender{errorOnSend: errorOnSend} - report := newHistogramReporting(zap.NewNop()) - consumer := newCumulativeHistogramDataPointConsumer(sender) - var errs []error - - consumer.Consume(metric, histogramDataPoint, &errs, report) - - if !errorOnSend { - assert.Empty(t, errs) - } else { - assert.Len(t, errs, len(sender.metrics)) - } - assert.Equal( - t, - []tobsMetric{ - { - Name: "a.metric", - Value: 2.0, - Tags: map[string]string{"foo": "bar", "le": "2"}, - }, - { - Name: "a.metric", - Value: 3.0, - Tags: map[string]string{"foo": "bar", "le": "5"}, - }, - { - Name: "a.metric", - Value: 5.0, - Tags: map[string]string{"foo": "bar", "le": "10"}, - }, - { - Name: "a.metric", - Value: 7.0, - Tags: map[string]string{"foo": "bar", "le": "+Inf"}, - }, - }, - sender.metrics) -} - func verifyGaugeConsumer(t *testing.T, errorOnSend bool) { metric := newMetric("test.metric", pdata.MetricDataTypeGauge) dataPoints := metric.Gauge().DataPoints() From 54c4dc76049b30f39109a4e7f0f8a04e1f30538e Mon Sep 17 00:00:00 2001 From: Travis Keep Date: Tue, 30 Nov 2021 08:31:57 -0800 Subject: [PATCH 3/7] A few renamings and documentation changes. --- exporter/tanzuobservabilityexporter/metrics.go | 8 ++++---- .../tanzuobservabilityexporter/metrics_test.go | 16 ++++++++++------ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/exporter/tanzuobservabilityexporter/metrics.go b/exporter/tanzuobservabilityexporter/metrics.go index 519cc0b3d62f..e83ab35d0e0c 100644 --- a/exporter/tanzuobservabilityexporter/metrics.go +++ b/exporter/tanzuobservabilityexporter/metrics.go @@ -360,7 +360,7 @@ type histogramReporting struct { } // newHistogramReporting returns a new histogramReporting instance. -// logger is the logger to use. +// log messages are sent to logger. func newHistogramReporting(logger *zap.Logger) *histogramReporting { return &histogramReporting{logger: logger} } @@ -536,9 +536,9 @@ func (c *cumulativeHistogramDataPointConsumer) Consume( } } -func leTagValue(explicitBounds []float64, idx int) string { - if idx == len(explicitBounds) { +func leTagValue(explicitBounds []float64, bucketIndex int) string { + if bucketIndex == len(explicitBounds) { return "+Inf" } - return strconv.FormatFloat(explicitBounds[idx], 'f', -1, 64) + return strconv.FormatFloat(explicitBounds[bucketIndex], 'f', -1, 64) } diff --git a/exporter/tanzuobservabilityexporter/metrics_test.go b/exporter/tanzuobservabilityexporter/metrics_test.go index 0901535655c2..397a9bc2961d 100644 --- a/exporter/tanzuobservabilityexporter/metrics_test.go +++ b/exporter/tanzuobservabilityexporter/metrics_test.go @@ -133,7 +133,7 @@ func TestGaugeConsumerErrorSending(t *testing.T) { } func TestGaugeConsumerMissingValueNoLogging(t *testing.T) { - metric := newMetric("bad.metric", pdata.MetricDataTypeGauge) + metric := newMetric("missing.value.metric", pdata.MetricDataTypeGauge) dataPoints := metric.Gauge().DataPoints() dataPoints.EnsureCapacity(1) addDataPoint( @@ -154,7 +154,7 @@ func TestGaugeConsumerMissingValueNoLogging(t *testing.T) { } func TestGaugeConsumerMissingValue(t *testing.T) { - metric := newMetric("bad.metric", pdata.MetricDataTypeGauge) + metric := newMetric("missing.value.metric", pdata.MetricDataTypeGauge) dataPoints := metric.Gauge().DataPoints() dataPoints.EnsureCapacity(1) addDataPoint( @@ -357,7 +357,7 @@ func TestSumConsumerUnspecified(t *testing.T) { } func TestSumConsumerMissingValue(t *testing.T) { - metric := newMetric("bad.metric", pdata.MetricDataTypeSum) + metric := newMetric("missing.value.metric", pdata.MetricDataTypeSum) sum := metric.Sum() sum.SetAggregationTemporality(pdata.MetricAggregationTemporalityDelta) dataPoints := sum.DataPoints() @@ -418,7 +418,7 @@ func TestHistogramConsumerDeltaAggregation(t *testing.T) { func TestHistogramConsumerCumulativeAggregation(t *testing.T) { countAttributeForEachDataPoint := []uint64{2, 5, 10} cumulativeMetric := newHistogramMetricWithDataPoints( - "cum.metric", + "cumulative.metric", pdata.MetricAggregationTemporalityCumulative, countAttributeForEachDataPoint) sender := &mockGaugeSender{} @@ -435,7 +435,9 @@ func TestHistogramConsumerCumulativeAggregation(t *testing.T) { // We had three datapoints. Our mock just captures the metric name of // each data point consumed. assert.Equal( - t, []string{"cum.metric", "cum.metric", "cum.metric"}, cumulativeConsumer.names) + t, + []string{"cumulative.metric", "cumulative.metric", "cumulative.metric"}, + cumulativeConsumer.names) assert.Equal(t, countAttributeForEachDataPoint, cumulativeConsumer.counts) } @@ -445,7 +447,9 @@ func TestHistogramConsumerNoAggregation(t *testing.T) { // Create a histogram metric with missing aggregation attribute metric := newHistogramMetricWithDataPoints( - "bad.metric", pdata.MetricAggregationTemporalityUnspecified, nil) + "missing.aggregation.metric", + pdata.MetricAggregationTemporalityUnspecified, + nil) sender := &mockGaugeSender{} observedZapCore, observedLogs := observer.New(zap.DebugLevel) consumer := newHistogramConsumer( From 55e863fb7b52496aeb2d5a62c9ce740dc3cd7a56 Mon Sep 17 00:00:00 2001 From: Travis Keep Date: Tue, 14 Dec 2021 11:18:34 -0800 Subject: [PATCH 4/7] Fix misspelled word in documentation. --- exporter/tanzuobservabilityexporter/metrics.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/tanzuobservabilityexporter/metrics.go b/exporter/tanzuobservabilityexporter/metrics.go index e83ab35d0e0c..f52a16c12003 100644 --- a/exporter/tanzuobservabilityexporter/metrics.go +++ b/exporter/tanzuobservabilityexporter/metrics.go @@ -403,7 +403,7 @@ func (r *histogramReporting) LogNoAggregationTemporality(metric pdata.Metric) { r.noAggregationTemporality.Inc() } -// Report sends the counts in this instancce to wavefront. +// Report sends the counts in this instance to wavefront. // sender is what sends to wavefront. Any errors sending get added to errs. func (r *histogramReporting) Report(sender gaugeSender, errs *[]error) { r.malformedHistograms.Report(malformedHistogramMetricName, nil, sender, errs) From dfd7791d523280fbf685b3b3f738a0cd8b52f2f2 Mon Sep 17 00:00:00 2001 From: Travis Keep Date: Tue, 14 Dec 2021 14:33:31 -0800 Subject: [PATCH 5/7] Get rid of consumerOptions type. --- .../tanzuobservabilityexporter/metrics.go | 65 +++++++------------ .../metrics_test.go | 15 +---- 2 files changed, 28 insertions(+), 52 deletions(-) diff --git a/exporter/tanzuobservabilityexporter/metrics.go b/exporter/tanzuobservabilityexporter/metrics.go index f52a16c12003..fb368a48d80c 100644 --- a/exporter/tanzuobservabilityexporter/metrics.go +++ b/exporter/tanzuobservabilityexporter/metrics.go @@ -227,22 +227,6 @@ type gaugeSender interface { SendMetric(name string, value float64, ts int64, source string, tags map[string]string) error } -// consumerOptions is general options for consumers -type consumerOptions struct { - - // The zap logger to use, nil means no logging - Logger *zap.Logger - - // If true, report internal metrics to wavefront - ReportInternalMetrics bool -} - -func (c *consumerOptions) replaceZeroFieldsWithDefaults() { - if c.Logger == nil { - c.Logger = zap.NewNop() - } -} - type gaugeConsumer struct { sender gaugeSender logger *zap.Logger @@ -251,17 +235,17 @@ type gaugeConsumer struct { } // newGaugeConsumer returns a typedMetricConsumer that consumes gauge metrics -// by sending them to tanzu observability. Caller can pass nil for options to get the defaults. -func newGaugeConsumer(sender gaugeSender, options *consumerOptions) typedMetricConsumer { - var fixedOptions consumerOptions - if options != nil { - fixedOptions = *options +// by sending them to tanzu observability. +func newGaugeConsumer(sender gaugeSender, logger *zap.Logger) typedMetricConsumer { + reportInternalMetrics := true + if logger == nil { + logger = zap.NewNop() + reportInternalMetrics = false } - fixedOptions.replaceZeroFieldsWithDefaults() return &gaugeConsumer{ sender: sender, - logger: fixedOptions.Logger, - reportInternalMetrics: fixedOptions.ReportInternalMetrics, + logger: logger, + reportInternalMetrics: reportInternalMetrics, } } @@ -296,16 +280,18 @@ type sumConsumer struct { reportInternalMetrics bool } -func newSumConsumer(sender senders.MetricSender, options *consumerOptions) typedMetricConsumer { - var fixedOptions consumerOptions - if options != nil { - fixedOptions = *options +// newSumConsumer returns a typedMetricConsumer that consumes sum metrics +// by sending them to tanzu observability. +func newSumConsumer(sender senders.MetricSender, logger *zap.Logger) typedMetricConsumer { + reportInternalMetrics := true + if logger == nil { + logger = zap.NewNop() + reportInternalMetrics = false } - fixedOptions.replaceZeroFieldsWithDefaults() return &sumConsumer{ sender: sender, - logger: fixedOptions.Logger, - reportInternalMetrics: fixedOptions.ReportInternalMetrics, + logger: logger, + reportInternalMetrics: reportInternalMetrics, } } @@ -425,24 +411,23 @@ type histogramConsumer struct { // newHistogramConsumer returns a metricConsumer that consumes histograms. // cumulative and delta handle cumulative and delta histograms respectively. -// sender sends internal metrics to wavefront. Caller can pass nil for -// options to get the defaults. +// sender sends internal metrics to wavefront. func newHistogramConsumer( cumulative, delta histogramDataPointConsumer, sender gaugeSender, - options *consumerOptions, + logger *zap.Logger, ) typedMetricConsumer { - var fixedOptions consumerOptions - if options != nil { - fixedOptions = *options + reportInternalMetrics := true + if logger == nil { + logger = zap.NewNop() + reportInternalMetrics = false } - fixedOptions.replaceZeroFieldsWithDefaults() return &histogramConsumer{ cumulative: cumulative, delta: delta, sender: sender, - reporting: newHistogramReporting(fixedOptions.Logger), - reportInternalMetrics: fixedOptions.ReportInternalMetrics, + reporting: newHistogramReporting(logger), + reportInternalMetrics: reportInternalMetrics, } } diff --git a/exporter/tanzuobservabilityexporter/metrics_test.go b/exporter/tanzuobservabilityexporter/metrics_test.go index 397a9bc2961d..e1f4e037ee3f 100644 --- a/exporter/tanzuobservabilityexporter/metrics_test.go +++ b/exporter/tanzuobservabilityexporter/metrics_test.go @@ -166,10 +166,7 @@ func TestGaugeConsumerMissingValue(t *testing.T) { // Sending to tanzu observability should fail sender := &mockGaugeSender{errorOnSend: true} observedZapCore, observedLogs := observer.New(zap.DebugLevel) - consumer := newGaugeConsumer(sender, &consumerOptions{ - Logger: zap.New(observedZapCore), - ReportInternalMetrics: true, - }) + consumer := newGaugeConsumer(sender, zap.New(observedZapCore)) var errs []error expectedMissingValueCount := 2 for i := 0; i < expectedMissingValueCount; i++ { @@ -370,10 +367,7 @@ func TestSumConsumerMissingValue(t *testing.T) { ) sender := &mockSumSender{} observedZapCore, observedLogs := observer.New(zap.DebugLevel) - consumer := newSumConsumer(sender, &consumerOptions{ - Logger: zap.New(observedZapCore), - ReportInternalMetrics: true, - }) + consumer := newSumConsumer(sender, zap.New(observedZapCore)) var errs []error expectedMissingValueCount := 2 @@ -456,10 +450,7 @@ func TestHistogramConsumerNoAggregation(t *testing.T) { &mockHistogramDataPointConsumer{}, nil, sender, - &consumerOptions{ - Logger: zap.New(observedZapCore), - ReportInternalMetrics: true, - }, + zap.New(observedZapCore), ) assert.Equal(t, pdata.MetricDataTypeHistogram, consumer.Type()) var errs []error From 3bc766237d95fe2d32a54698e05de38c9d393c44 Mon Sep 17 00:00:00 2001 From: Travis Keep Date: Wed, 15 Dec 2021 14:17:55 -0800 Subject: [PATCH 6/7] Move pre-existing "le" tag to "_le" --- .../tanzuobservabilityexporter/metrics.go | 27 ++------------- .../metrics_test.go | 34 +++++++++---------- 2 files changed, 20 insertions(+), 41 deletions(-) diff --git a/exporter/tanzuobservabilityexporter/metrics.go b/exporter/tanzuobservabilityexporter/metrics.go index fb368a48d80c..103a2029792b 100644 --- a/exporter/tanzuobservabilityexporter/metrics.go +++ b/exporter/tanzuobservabilityexporter/metrics.go @@ -32,7 +32,6 @@ const ( metricNameString = "metric name" metricTypeString = "metric type" malformedHistogramMetricName = "~sdk.otel.collector.malformed_histogram" - leInUseMetricName = "~sdk.otel.collector.le_tag_in_use" noAggregationTemporalityMetricName = "~sdk.otel.collector.no_aggregation_temporality" ) @@ -341,7 +340,6 @@ func (s *sumConsumer) pushNumberDataPoint( type histogramReporting struct { logger *zap.Logger malformedHistograms counter - leInUse counter noAggregationTemporality counter } @@ -356,12 +354,6 @@ func (r *histogramReporting) Malformed() int64 { return r.malformedHistograms.Get() } -// LeTagInUse returns the number of histogram data points already using the 'le' -// tag. -func (r *histogramReporting) LeTagInUse() int64 { - return r.leInUse.Get() -} - // NoAggregationTemporality returns the number of histogram metrics that have no // aggregation temporality. func (r *histogramReporting) NoAggregationTemporality() int64 { @@ -375,13 +367,6 @@ func (r *histogramReporting) LogMalformed(metric pdata.Metric) { r.malformedHistograms.Inc() } -// LogLeTagInUse logs seeing one data point using the 'le' tag -func (r *histogramReporting) LogLeTagInUse(metric pdata.Metric) { - namef := zap.String(metricNameString, metric.Name()) - r.logger.Debug("le tag already in use", namef) - r.leInUse.Inc() -} - // LogNoAggregationTemporality logs seeing a histogram metric with no aggregation temporality func (r *histogramReporting) LogNoAggregationTemporality(metric pdata.Metric) { namef := zap.String(metricNameString, metric.Name()) @@ -393,7 +378,6 @@ func (r *histogramReporting) LogNoAggregationTemporality(metric pdata.Metric) { // sender is what sends to wavefront. Any errors sending get added to errs. func (r *histogramReporting) Report(sender gaugeSender, errs *[]error) { r.malformedHistograms.Report(malformedHistogramMetricName, nil, sender, errs) - r.leInUse.Report(leInUseMetricName, nil, sender, errs) r.noAggregationTemporality.Report( noAggregationTemporalityMetricName, typeIsHistogramTags, @@ -498,18 +482,13 @@ func (c *cumulativeHistogramDataPointConsumer) Consume( ts := h.Timestamp().AsTime().Unix() explicitBounds := h.ExplicitBounds() bucketCounts := h.BucketCounts() - var abort bool if len(bucketCounts) != len(explicitBounds)+1 { reporting.LogMalformed(metric) - abort = true - } - if _, ok := tags["le"]; ok { - reporting.LogLeTagInUse(metric) - abort = true - } - if abort { return } + if leTag, ok := tags["le"]; ok { + tags["_le"] = leTag + } var leCount uint64 for i := range bucketCounts { tags["le"] = leTagValue(explicitBounds, i) diff --git a/exporter/tanzuobservabilityexporter/metrics_test.go b/exporter/tanzuobservabilityexporter/metrics_test.go index e1f4e037ee3f..18b7bbfe0ca6 100644 --- a/exporter/tanzuobservabilityexporter/metrics_test.go +++ b/exporter/tanzuobservabilityexporter/metrics_test.go @@ -474,10 +474,6 @@ func TestHistogramReporting(t *testing.T) { observedZapCore, observedLogs := observer.New(zap.DebugLevel) report := newHistogramReporting(zap.New(observedZapCore)) metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) - leTagInUseCount := 2 - for i := 0; i < leTagInUseCount; i++ { - report.LogLeTagInUse(metric) - } malformedCount := 3 for i := 0; i < malformedCount; i++ { report.LogMalformed(metric) @@ -487,12 +483,11 @@ func TestHistogramReporting(t *testing.T) { report.LogNoAggregationTemporality(metric) } - assert.Equal(t, int64(leTagInUseCount), report.LeTagInUse()) assert.Equal(t, int64(malformedCount), report.Malformed()) assert.Equal(t, int64(noAggregationTemporalityCount), report.NoAggregationTemporality()) assert.Equal( t, - leTagInUseCount+malformedCount+noAggregationTemporalityCount, + malformedCount+noAggregationTemporalityCount, observedLogs.Len()) sender := &mockGaugeSender{} @@ -501,13 +496,6 @@ func TestHistogramReporting(t *testing.T) { report.Report(sender, &errs) assert.Empty(t, errs) - assert.Contains( - t, - sender.metrics, - tobsMetric{ - Name: leInUseMetricName, - Value: float64(leTagInUseCount), - }) assert.Contains( t, sender.metrics, @@ -611,9 +599,22 @@ func TestCumulativeHistogramDataPointConsumerLeInUse(t *testing.T) { consumer.Consume(metric, histogramDataPoint, &errs, report) assert.Empty(t, errs) - assert.Empty(t, sender.metrics) - assert.Equal(t, int64(1), report.LeTagInUse()) - assert.Equal(t, int64(0), report.Malformed()) + assert.Equal( + t, + []tobsMetric{ + { + Name: "a.metric", + Value: 4.0, + Tags: map[string]string{"_le": "8", "le": "10"}, + }, + { + Name: "a.metric", + Value: 16.0, + Tags: map[string]string{"_le": "8", "le": "+Inf"}, + }, + }, + sender.metrics, + ) } func TestCumulativeHistogramDataPointConsumerMissingBuckets(t *testing.T) { @@ -629,7 +630,6 @@ func TestCumulativeHistogramDataPointConsumerMissingBuckets(t *testing.T) { assert.Empty(t, errs) assert.Empty(t, sender.metrics) assert.Equal(t, int64(1), report.Malformed()) - assert.Equal(t, int64(0), report.LeTagInUse()) } // Creates a histogram metric with len(countAttributeForEachDataPoint) From f210af052405a0dee1044f5761ec17815b5e5f4a Mon Sep 17 00:00:00 2001 From: Travis Keep Date: Thu, 16 Dec 2021 11:29:04 -0800 Subject: [PATCH 7/7] Use component.TelemetrySettings instead of logger. --- .../tanzuobservabilityexporter/metrics.go | 132 ++++++++---------- .../metrics_test.go | 125 +++++++++-------- 2 files changed, 121 insertions(+), 136 deletions(-) diff --git a/exporter/tanzuobservabilityexporter/metrics.go b/exporter/tanzuobservabilityexporter/metrics.go index 103a2029792b..52c5a9d093ad 100644 --- a/exporter/tanzuobservabilityexporter/metrics.go +++ b/exporter/tanzuobservabilityexporter/metrics.go @@ -22,6 +22,7 @@ import ( "sync/atomic" "github.com/wavefronthq/wavefront-sdk-go/senders" + "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/model/pdata" "go.uber.org/multierr" "go.uber.org/zap" @@ -43,16 +44,22 @@ var ( // metricsConsumer instances consume OTEL metrics type metricsConsumer struct { - consumerMap map[pdata.MetricDataType]typedMetricConsumer - sender flushCloser + consumerMap map[pdata.MetricDataType]typedMetricConsumer + sender flushCloser + reportInternalMetrics bool } // newMetricsConsumer returns a new metricsConsumer. consumers are the -// consumers responsible for consuming each type metric. The Consume method +// consumers responsible for consuming each type of metric. The Consume method // of returned consumer calls the Flush method on sender after consuming // all the metrics. Calling Close on the returned metricsConsumer calls Close -// on sender. sender can be nil. -func newMetricsConsumer(consumers []typedMetricConsumer, sender flushCloser) *metricsConsumer { +// on sender. sender can be nil. reportInternalMetrics controls whether +// returned metricsConsumer reports internal metrics. +func newMetricsConsumer( + consumers []typedMetricConsumer, + sender flushCloser, + reportInternalMetrics bool, +) *metricsConsumer { consumerMap := make(map[pdata.MetricDataType]typedMetricConsumer, len(consumers)) for _, consumer := range consumers { if consumerMap[consumer.Type()] != nil { @@ -61,8 +68,9 @@ func newMetricsConsumer(consumers []typedMetricConsumer, sender flushCloser) *me consumerMap[consumer.Type()] = consumer } return &metricsConsumer{ - consumerMap: consumerMap, - sender: sender, + consumerMap: consumerMap, + sender: sender, + reportInternalMetrics: reportInternalMetrics, } } @@ -88,7 +96,9 @@ func (c *metricsConsumer) Consume(ctx context.Context, md pdata.Metrics) error { } } } - c.pushInternalMetrics(&errs) + if c.reportInternalMetrics { + c.pushInternalMetrics(&errs) + } if c.sender != nil { if err := c.sender.Flush(); err != nil { errs = append(errs, err) @@ -174,12 +184,12 @@ func (c *counter) Get() int64 { } // logMissingValue keeps track of metrics with missing values. metric is the -// metric with the missing value. logger is the logger. count counts +// metric with the missing value. settings logs the missing value. count counts // metrics with missing values. -func logMissingValue(metric pdata.Metric, logger *zap.Logger, count *counter) { +func logMissingValue(metric pdata.Metric, settings component.TelemetrySettings, count *counter) { namef := zap.String(metricNameString, metric.Name()) typef := zap.String(metricTypeString, metric.DataType().String()) - logger.Debug("Metric missing value", namef, typef) + settings.Logger.Debug("Metric missing value", namef, typef) count.Inc() } @@ -198,21 +208,21 @@ func getValue(numberDataPoint pdata.NumberDataPoint) (float64, error) { // pushGaugeNumberDataPoint sends a metric as a gauge metric to tanzu // observability. metric is the metric to send. numberDataPoint is the value // of the metric. Any errors get appended to errs. sender is what sends the -// gauge metric to tanzu observability. logger is the logger. missingValues +// gauge metric to tanzu observability. settings logs problems. missingValues // keeps track of metrics with missing values. func pushGaugeNumberDataPoint( metric pdata.Metric, numberDataPoint pdata.NumberDataPoint, errs *[]error, sender gaugeSender, - logger *zap.Logger, + settings component.TelemetrySettings, missingValues *counter, ) { tags := attributesToTags(numberDataPoint.Attributes()) ts := numberDataPoint.Timestamp().AsTime().Unix() value, err := getValue(numberDataPoint) if err != nil { - logMissingValue(metric, logger, missingValues) + logMissingValue(metric, settings, missingValues) return } err = sender.SendMetric(metric.Name(), value, ts, "", tags) @@ -227,24 +237,18 @@ type gaugeSender interface { } type gaugeConsumer struct { - sender gaugeSender - logger *zap.Logger - missingValues counter - reportInternalMetrics bool + sender gaugeSender + settings component.TelemetrySettings + missingValues counter } // newGaugeConsumer returns a typedMetricConsumer that consumes gauge metrics // by sending them to tanzu observability. -func newGaugeConsumer(sender gaugeSender, logger *zap.Logger) typedMetricConsumer { - reportInternalMetrics := true - if logger == nil { - logger = zap.NewNop() - reportInternalMetrics = false - } +func newGaugeConsumer( + sender gaugeSender, settings component.TelemetrySettings) typedMetricConsumer { return &gaugeConsumer{ - sender: sender, - logger: logger, - reportInternalMetrics: reportInternalMetrics, + sender: sender, + settings: settings, } } @@ -261,36 +265,28 @@ func (g *gaugeConsumer) Consume(metric pdata.Metric, errs *[]error) { numberDataPoints.At(i), errs, g.sender, - g.logger, + g.settings, &g.missingValues) } } func (g *gaugeConsumer) PushInternalMetrics(errs *[]error) { - if g.reportInternalMetrics { - g.missingValues.Report(missingValueMetricName, typeIsGaugeTags, g.sender, errs) - } + g.missingValues.Report(missingValueMetricName, typeIsGaugeTags, g.sender, errs) } type sumConsumer struct { - sender senders.MetricSender - logger *zap.Logger - missingValues counter - reportInternalMetrics bool + sender senders.MetricSender + settings component.TelemetrySettings + missingValues counter } // newSumConsumer returns a typedMetricConsumer that consumes sum metrics // by sending them to tanzu observability. -func newSumConsumer(sender senders.MetricSender, logger *zap.Logger) typedMetricConsumer { - reportInternalMetrics := true - if logger == nil { - logger = zap.NewNop() - reportInternalMetrics = false - } +func newSumConsumer( + sender senders.MetricSender, settings component.TelemetrySettings) typedMetricConsumer { return &sumConsumer{ - sender: sender, - logger: logger, - reportInternalMetrics: reportInternalMetrics, + sender: sender, + settings: settings, } } @@ -310,15 +306,13 @@ func (s *sumConsumer) Consume(metric pdata.Metric, errs *[]error) { s.pushNumberDataPoint(metric, numberDataPoints.At(i), errs) } else { pushGaugeNumberDataPoint( - metric, numberDataPoints.At(i), errs, s.sender, s.logger, &s.missingValues) + metric, numberDataPoints.At(i), errs, s.sender, s.settings, &s.missingValues) } } } func (s *sumConsumer) PushInternalMetrics(errs *[]error) { - if s.reportInternalMetrics { - s.missingValues.Report(missingValueMetricName, typeIsSumTags, s.sender, errs) - } + s.missingValues.Report(missingValueMetricName, typeIsSumTags, s.sender, errs) } func (s *sumConsumer) pushNumberDataPoint( @@ -327,7 +321,7 @@ func (s *sumConsumer) pushNumberDataPoint( tags := attributesToTags(numberDataPoint.Attributes()) value, err := getValue(numberDataPoint) if err != nil { - logMissingValue(metric, s.logger, &s.missingValues) + logMissingValue(metric, s.settings, &s.missingValues) return } err = s.sender.SendDeltaCounter(metric.Name(), value, "", tags) @@ -338,15 +332,14 @@ func (s *sumConsumer) pushNumberDataPoint( // histogramReporting takes care of logging and internal metrics for histograms type histogramReporting struct { - logger *zap.Logger + settings component.TelemetrySettings malformedHistograms counter noAggregationTemporality counter } // newHistogramReporting returns a new histogramReporting instance. -// log messages are sent to logger. -func newHistogramReporting(logger *zap.Logger) *histogramReporting { - return &histogramReporting{logger: logger} +func newHistogramReporting(settings component.TelemetrySettings) *histogramReporting { + return &histogramReporting{settings: settings} } // Malformed returns the number of malformed histogram data points. @@ -363,14 +356,14 @@ func (r *histogramReporting) NoAggregationTemporality() int64 { // LogMalformed logs seeing one malformed data point. func (r *histogramReporting) LogMalformed(metric pdata.Metric) { namef := zap.String(metricNameString, metric.Name()) - r.logger.Debug("Malformed histogram", namef) + r.settings.Logger.Debug("Malformed histogram", namef) r.malformedHistograms.Inc() } // LogNoAggregationTemporality logs seeing a histogram metric with no aggregation temporality func (r *histogramReporting) LogNoAggregationTemporality(metric pdata.Metric) { namef := zap.String(metricNameString, metric.Name()) - r.logger.Debug("histogram metric missing aggregation temporality", namef) + r.settings.Logger.Debug("histogram metric missing aggregation temporality", namef) r.noAggregationTemporality.Inc() } @@ -386,11 +379,10 @@ func (r *histogramReporting) Report(sender gaugeSender, errs *[]error) { } type histogramConsumer struct { - cumulative histogramDataPointConsumer - delta histogramDataPointConsumer - sender gaugeSender - reporting *histogramReporting - reportInternalMetrics bool + cumulative histogramDataPointConsumer + delta histogramDataPointConsumer + sender gaugeSender + reporting *histogramReporting } // newHistogramConsumer returns a metricConsumer that consumes histograms. @@ -399,19 +391,13 @@ type histogramConsumer struct { func newHistogramConsumer( cumulative, delta histogramDataPointConsumer, sender gaugeSender, - logger *zap.Logger, + settings component.TelemetrySettings, ) typedMetricConsumer { - reportInternalMetrics := true - if logger == nil { - logger = zap.NewNop() - reportInternalMetrics = false - } return &histogramConsumer{ - cumulative: cumulative, - delta: delta, - sender: sender, - reporting: newHistogramReporting(logger), - reportInternalMetrics: reportInternalMetrics, + cumulative: cumulative, + delta: delta, + sender: sender, + reporting: newHistogramReporting(settings), } } @@ -441,9 +427,7 @@ func (h *histogramConsumer) Consume(metric pdata.Metric, errs *[]error) { } func (h *histogramConsumer) PushInternalMetrics(errs *[]error) { - if h.reportInternalMetrics { - h.reporting.Report(h.sender, errs) - } + h.reporting.Report(h.sender, errs) } // histogramDataPointConsumer consumes one histogram data point. There is one diff --git a/exporter/tanzuobservabilityexporter/metrics_test.go b/exporter/tanzuobservabilityexporter/metrics_test.go index 18b7bbfe0ca6..d36a7c9e9f84 100644 --- a/exporter/tanzuobservabilityexporter/metrics_test.go +++ b/exporter/tanzuobservabilityexporter/metrics_test.go @@ -21,7 +21,7 @@ import ( "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/model/pdata" "go.uber.org/zap" "go.uber.org/zap/zaptest/observer" @@ -36,7 +36,8 @@ func TestMetricsConsumerNormal(t *testing.T) { mockSumConsumer := &mockTypedMetricConsumer{typ: pdata.MetricDataTypeSum} sender := &mockFlushCloser{} metrics := constructMetrics(gauge1, sum1, gauge2, sum2) - consumer := newMetricsConsumer([]typedMetricConsumer{mockGaugeConsumer, mockSumConsumer}, sender) + consumer := newMetricsConsumer( + []typedMetricConsumer{mockGaugeConsumer, mockSumConsumer}, sender, true) assert.NoError(t, consumer.Consume(context.Background(), metrics)) @@ -52,7 +53,7 @@ func TestMetricsConsumerNormal(t *testing.T) { } func TestMetricsConsumerNone(t *testing.T) { - consumer := newMetricsConsumer(nil, nil) + consumer := newMetricsConsumer(nil, nil, true) metrics := constructMetrics() assert.NoError(t, consumer.Consume(context.Background(), metrics)) @@ -65,14 +66,17 @@ func TestNewMetricsConsumerPanicsWithDuplicateMetricType(t *testing.T) { mockGaugeConsumer2 := &mockTypedMetricConsumer{typ: pdata.MetricDataTypeGauge} assert.Panics(t, func() { - newMetricsConsumer([]typedMetricConsumer{mockGaugeConsumer1, mockGaugeConsumer2}, nil) + newMetricsConsumer( + []typedMetricConsumer{mockGaugeConsumer1, mockGaugeConsumer2}, + nil, + true) }) } func TestMetricsConsumerPropagatesErrorsOnFlush(t *testing.T) { sender := &mockFlushCloser{errorOnFlush: true} metrics := constructMetrics() - consumer := newMetricsConsumer(nil, sender) + consumer := newMetricsConsumer(nil, sender, true) assert.Error(t, consumer.Consume(context.Background(), metrics)) assert.Equal(t, 1, sender.numFlushCalls) @@ -81,28 +85,43 @@ func TestMetricsConsumerPropagatesErrorsOnFlush(t *testing.T) { func TestMetricsConsumerErrorsWithUnregisteredMetricType(t *testing.T) { gauge1 := newMetric("gauge1", pdata.MetricDataTypeGauge) metrics := constructMetrics(gauge1) - consumer := newMetricsConsumer(nil, nil) + consumer := newMetricsConsumer(nil, nil, true) assert.Error(t, consumer.Consume(context.Background(), metrics)) } func TestMetricsConsumerErrorConsuming(t *testing.T) { gauge1 := newMetric("gauge1", pdata.MetricDataTypeGauge) - mockGaugeConsumer := &mockTypedMetricConsumer{typ: pdata.MetricDataTypeGauge, errorOnConsume: true} + mockGaugeConsumer := &mockTypedMetricConsumer{ + typ: pdata.MetricDataTypeGauge, + errorOnConsume: true} metrics := constructMetrics(gauge1) - consumer := newMetricsConsumer([]typedMetricConsumer{mockGaugeConsumer}, nil) + consumer := newMetricsConsumer( + []typedMetricConsumer{mockGaugeConsumer}, nil, true) assert.Error(t, consumer.Consume(context.Background(), metrics)) assert.Len(t, mockGaugeConsumer.names, 1) assert.Equal(t, 1, mockGaugeConsumer.pushInternalMetricsCallCount) } +func TestMetricsConsumerNoReportingInternalMetrics(t *testing.T) { + gauge1 := newMetric("gauge1", pdata.MetricDataTypeGauge) + mockGaugeConsumer := &mockTypedMetricConsumer{typ: pdata.MetricDataTypeGauge} + metrics := constructMetrics(gauge1) + consumer := newMetricsConsumer( + []typedMetricConsumer{mockGaugeConsumer}, nil, false) + assert.NoError(t, consumer.Consume(context.Background(), metrics)) + assert.Len(t, mockGaugeConsumer.names, 1) + assert.Equal(t, 0, mockGaugeConsumer.pushInternalMetricsCallCount) +} + func TestMetricsConsumerErrorConsumingInternal(t *testing.T) { gauge1 := newMetric("gauge1", pdata.MetricDataTypeGauge) mockGaugeConsumer := &mockTypedMetricConsumer{ typ: pdata.MetricDataTypeGauge, errorOnPushInternalMetrics: true} metrics := constructMetrics(gauge1) - consumer := newMetricsConsumer([]typedMetricConsumer{mockGaugeConsumer}, nil) + consumer := newMetricsConsumer( + []typedMetricConsumer{mockGaugeConsumer}, nil, true) assert.Error(t, consumer.Consume(context.Background(), metrics)) assert.Len(t, mockGaugeConsumer.names, 1) @@ -113,7 +132,8 @@ func TestMetricsConsumerRespectContext(t *testing.T) { sender := &mockFlushCloser{} gauge1 := newMetric("gauge1", pdata.MetricDataTypeGauge) mockGaugeConsumer := &mockTypedMetricConsumer{typ: pdata.MetricDataTypeGauge} - consumer := newMetricsConsumer([]typedMetricConsumer{mockGaugeConsumer}, sender) + consumer := newMetricsConsumer( + []typedMetricConsumer{mockGaugeConsumer}, sender, true) ctx, cancel := context.WithCancel(context.Background()) cancel() @@ -132,27 +152,6 @@ func TestGaugeConsumerErrorSending(t *testing.T) { verifyGaugeConsumer(t, true) } -func TestGaugeConsumerMissingValueNoLogging(t *testing.T) { - metric := newMetric("missing.value.metric", pdata.MetricDataTypeGauge) - dataPoints := metric.Gauge().DataPoints() - dataPoints.EnsureCapacity(1) - addDataPoint( - nil, - 1633123456, - nil, - dataPoints, - ) - sender := &mockGaugeSender{} - consumer := newGaugeConsumer(sender, nil) - var errs []error - - consumer.Consume(metric, &errs) - consumer.PushInternalMetrics(&errs) - - assert.Empty(t, errs) - assert.Empty(t, sender.metrics) -} - func TestGaugeConsumerMissingValue(t *testing.T) { metric := newMetric("missing.value.metric", pdata.MetricDataTypeGauge) dataPoints := metric.Gauge().DataPoints() @@ -166,7 +165,9 @@ func TestGaugeConsumerMissingValue(t *testing.T) { // Sending to tanzu observability should fail sender := &mockGaugeSender{errorOnSend: true} observedZapCore, observedLogs := observer.New(zap.DebugLevel) - consumer := newGaugeConsumer(sender, zap.New(observedZapCore)) + settings := componenttest.NewNopTelemetrySettings() + settings.Logger = zap.New(observedZapCore) + consumer := newGaugeConsumer(sender, settings) var errs []error expectedMissingValueCount := 2 for i := 0; i < expectedMissingValueCount; i++ { @@ -182,13 +183,15 @@ func TestGaugeConsumerMissingValue(t *testing.T) { // One error from emitting the internal metric assert.Len(t, errs, 1) - // Only the internal metric was sent - require.Len(t, sender.metrics, 1) - assert.Equal(t, tobsMetric{ - Name: missingValueMetricName, - Value: float64(expectedMissingValueCount), - Tags: map[string]string{"type": "gauge"}}, - sender.metrics[0]) + assert.Contains( + t, + sender.metrics, + tobsMetric{ + Name: missingValueMetricName, + Value: float64(expectedMissingValueCount), + Tags: map[string]string{"type": "gauge"}, + }, + ) allLogs := observedLogs.All() assert.Len(t, allLogs, expectedMissingValueCount) } @@ -218,13 +221,12 @@ func TestSumConsumerDelta(t *testing.T) { ) sender := &mockSumSender{} - consumer := newSumConsumer(sender, nil) + consumer := newSumConsumer(sender, componenttest.NewNopTelemetrySettings()) assert.Equal(t, pdata.MetricDataTypeSum, consumer.Type()) var errs []error // delta sums get treated as delta counters consumer.Consume(deltaMetric, &errs) - consumer.PushInternalMetrics(&errs) expected := []tobsMetric{ { @@ -268,13 +270,12 @@ func TestSumConsumerErrorOnSend(t *testing.T) { ) sender := &mockSumSender{errorOnSend: true} - consumer := newSumConsumer(sender, nil) + consumer := newSumConsumer(sender, componenttest.NewNopTelemetrySettings()) assert.Equal(t, pdata.MetricDataTypeSum, consumer.Type()) var errs []error // delta sums get treated as delta counters consumer.Consume(deltaMetric, &errs) - consumer.PushInternalMetrics(&errs) assert.Len(t, errs, 2) } @@ -295,13 +296,12 @@ func TestSumConsumerCumulative(t *testing.T) { dataPoints, ) sender := &mockSumSender{} - consumer := newSumConsumer(sender, nil) + consumer := newSumConsumer(sender, componenttest.NewNopTelemetrySettings()) assert.Equal(t, pdata.MetricDataTypeSum, consumer.Type()) var errs []error // cumulative sums get treated as regular wavefront metrics consumer.Consume(cumulativeMetric, &errs) - consumer.PushInternalMetrics(&errs) expected := []tobsMetric{ { @@ -332,13 +332,12 @@ func TestSumConsumerUnspecified(t *testing.T) { dataPoints, ) sender := &mockSumSender{} - consumer := newSumConsumer(sender, nil) + consumer := newSumConsumer(sender, componenttest.NewNopTelemetrySettings()) assert.Equal(t, pdata.MetricDataTypeSum, consumer.Type()) var errs []error // unspecified sums get treated as regular wavefront metrics consumer.Consume(cumulativeMetric, &errs) - consumer.PushInternalMetrics(&errs) expected := []tobsMetric{ { @@ -367,7 +366,9 @@ func TestSumConsumerMissingValue(t *testing.T) { ) sender := &mockSumSender{} observedZapCore, observedLogs := observer.New(zap.DebugLevel) - consumer := newSumConsumer(sender, zap.New(observedZapCore)) + settings := componenttest.NewNopTelemetrySettings() + settings.Logger = zap.New(observedZapCore) + consumer := newSumConsumer(sender, settings) var errs []error expectedMissingValueCount := 2 @@ -399,12 +400,10 @@ func TestHistogramConsumerDeltaAggregation(t *testing.T) { sender := &mockGaugeSender{} cumulativeConsumer := &mockHistogramDataPointConsumer{} consumer := newHistogramConsumer( - cumulativeConsumer, nil, sender, nil) + cumulativeConsumer, nil, sender, componenttest.NewNopTelemetrySettings()) var errs []error consumer.Consume(deltaMetric, &errs) assert.Len(t, errs, 1) - consumer.PushInternalMetrics(&errs) - assert.Len(t, errs, 1) } // Tests that the histogramConsumer correctly delegates to its @@ -418,11 +417,10 @@ func TestHistogramConsumerCumulativeAggregation(t *testing.T) { sender := &mockGaugeSender{} cumulativeConsumer := &mockHistogramDataPointConsumer{} consumer := newHistogramConsumer( - cumulativeConsumer, nil, sender, nil) + cumulativeConsumer, nil, sender, componenttest.NewNopTelemetrySettings()) var errs []error consumer.Consume(cumulativeMetric, &errs) - consumer.PushInternalMetrics(&errs) assert.Empty(t, errs) @@ -446,11 +444,13 @@ func TestHistogramConsumerNoAggregation(t *testing.T) { nil) sender := &mockGaugeSender{} observedZapCore, observedLogs := observer.New(zap.DebugLevel) + settings := componenttest.NewNopTelemetrySettings() + settings.Logger = zap.New(observedZapCore) consumer := newHistogramConsumer( &mockHistogramDataPointConsumer{}, nil, sender, - zap.New(observedZapCore), + settings, ) assert.Equal(t, pdata.MetricDataTypeHistogram, consumer.Type()) var errs []error @@ -472,7 +472,9 @@ func TestHistogramConsumerNoAggregation(t *testing.T) { func TestHistogramReporting(t *testing.T) { observedZapCore, observedLogs := observer.New(zap.DebugLevel) - report := newHistogramReporting(zap.New(observedZapCore)) + settings := componenttest.NewNopTelemetrySettings() + settings.Logger = zap.New(observedZapCore) + report := newHistogramReporting(settings) metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) malformedCount := 3 for i := 0; i < malformedCount; i++ { @@ -514,7 +516,7 @@ func TestHistogramReporting(t *testing.T) { } func TestHistogramReportingError(t *testing.T) { - report := newHistogramReporting(zap.NewNop()) + report := newHistogramReporting(componenttest.NewNopTelemetrySettings()) sender := &mockGaugeSender{errorOnSend: true} var errs []error @@ -532,7 +534,7 @@ func TestCumulativeHistogramDataPointConsumer(t *testing.T) { histogramDataPoint.SetBucketCounts([]uint64{5, 1, 3, 2}) setTags(map[string]interface{}{"foo": "bar"}, histogramDataPoint.Attributes()) sender := &mockGaugeSender{} - report := newHistogramReporting(zap.NewNop()) + report := newHistogramReporting(componenttest.NewNopTelemetrySettings()) consumer := newCumulativeHistogramDataPointConsumer(sender) var errs []error @@ -575,7 +577,7 @@ func TestCumulativeHistogramDataPointConsumerError(t *testing.T) { histogramDataPoint.SetExplicitBounds([]float64{2.0, 5.0, 10.0}) histogramDataPoint.SetBucketCounts([]uint64{5, 1, 3, 2}) sender := &mockGaugeSender{errorOnSend: true} - report := newHistogramReporting(zap.NewNop()) + report := newHistogramReporting(componenttest.NewNopTelemetrySettings()) consumer := newCumulativeHistogramDataPointConsumer(sender) var errs []error @@ -592,7 +594,7 @@ func TestCumulativeHistogramDataPointConsumerLeInUse(t *testing.T) { histogramDataPoint.SetBucketCounts([]uint64{4, 12}) setTags(map[string]interface{}{"le": 8}, histogramDataPoint.Attributes()) sender := &mockGaugeSender{} - report := newHistogramReporting(zap.NewNop()) + report := newHistogramReporting(componenttest.NewNopTelemetrySettings()) consumer := newCumulativeHistogramDataPointConsumer(sender) var errs []error @@ -621,7 +623,7 @@ func TestCumulativeHistogramDataPointConsumerMissingBuckets(t *testing.T) { metric := newMetric("a.metric", pdata.MetricDataTypeHistogram) histogramDataPoint := pdata.NewHistogramDataPoint() sender := &mockGaugeSender{} - report := newHistogramReporting(zap.NewNop()) + report := newHistogramReporting(componenttest.NewNopTelemetrySettings()) consumer := newCumulativeHistogramDataPointConsumer(sender) var errs []error @@ -683,12 +685,11 @@ func verifyGaugeConsumer(t *testing.T, errorOnSend bool) { }, } sender := &mockGaugeSender{errorOnSend: errorOnSend} - consumer := newGaugeConsumer(sender, nil) + consumer := newGaugeConsumer(sender, componenttest.NewNopTelemetrySettings()) assert.Equal(t, pdata.MetricDataTypeGauge, consumer.Type()) var errs []error consumer.Consume(metric, &errs) - consumer.PushInternalMetrics(&errs) assert.ElementsMatch(t, expected, sender.metrics) if errorOnSend { assert.Len(t, errs, len(expected))