diff --git a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md index 45bc04f69c..b82f35ee58 100644 --- a/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Geneva/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +* Add support for exporting `UpDownCounter` and `ObservableUpDownCounter`. + [#685](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/685) + ## 1.4.0-beta.2 Released 2022-Oct-17 diff --git a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs index 56eee227d3..068f8388c2 100644 --- a/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs +++ b/src/OpenTelemetry.Exporter.Geneva/Metrics/GenevaMetricExporter.cs @@ -148,7 +148,25 @@ public override ExportResult Export(in Batch batch) break; } + // The value here could be negative hence we have to use `MetricEventType.DoubleMetric` + case MetricType.LongSumNonMonotonic: + { + // potential for minor precision loss implicitly going from long->double + // see: https://docs.microsoft.com/dotnet/csharp/language-reference/builtin-types/numeric-conversions#implicit-numeric-conversions + var doubleSum = Convert.ToDouble(metricPoint.GetSumLong()); + var metricData = new MetricData { DoubleValue = doubleSum }; + var bodyLength = this.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + this.metricDataTransport.Send(MetricEventType.DoubleMetric, this.bufferForNonHistogramMetrics, bodyLength); + break; + } + case MetricType.DoubleSum: + case MetricType.DoubleSumNonMonotonic: { var doubleSum = metricPoint.GetSumDouble(); var metricData = new MetricData { DoubleValue = doubleSum }; diff --git a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj index 57236f7a96..5112523ae7 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Benchmark/OpenTelemetry.Exporter.Geneva.Benchmark.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1;net6.0 + net6.0 $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1201,SA1202,SA1204,SA1311,SA1123 @@ -11,7 +11,6 @@ - diff --git a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj index 36d6642f07..0ef8e9d09d 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Stress/OpenTelemetry.Exporter.Geneva.Stress.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1;net6.0 + net6.0 $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1308,SA1201 diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs index 28f881e557..37c351e1dd 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/GenevaMetricExporterTests.cs @@ -102,6 +102,8 @@ public void SuccessfulSerialization(bool testMaxLimits) using var meter = new Meter("SuccessfulSerialization", "0.0.1"); var longCounter = meter.CreateCounter("longCounter"); var doubleCounter = meter.CreateCounter("doubleCounter"); + var longUpDownCounter = meter.CreateUpDownCounter("longUpDownCounter"); + var doubleUpDownCounter = meter.CreateUpDownCounter("doubleUpDownCounter"); var histogram = meter.CreateHistogram("histogram"); var exportedItems = new List(); using var inMemoryReader = new BaseExportingMetricReader(new InMemoryExporter(exportedItems)) @@ -129,6 +131,12 @@ public void SuccessfulSerialization(bool testMaxLimits) doubleCounter.Add( doubleValue, new("tag1", "value1"), new("tag2", "value2")); + longUpDownCounter.Add( + longValue, new("tag1", "value1"), new("tag2", "value2")); + + doubleUpDownCounter.Add( + longValue, new("tag1", "value1"), new("tag2", "value2")); + meter.CreateObservableCounter( "observableLongCounter", () => new List>() @@ -157,6 +165,20 @@ public void SuccessfulSerialization(bool testMaxLimits) new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), }); + meter.CreateObservableUpDownCounter( + "observableUpDownLongCounter", + () => new List>() + { + new(longValue, new("tag1", "value1"), new("tag2", "value2")), + }); + + meter.CreateObservableUpDownCounter( + "observableUpDownDoubleCounter", + () => new List>() + { + new(doubleValue, new("tag1", "value1"), new("tag2", "value2")), + }); + if (testMaxLimits) { // only testing the max value allowed for sum @@ -221,7 +243,7 @@ public void SuccessfulSerialization(bool testMaxLimits) inMemoryReader.Collect(); - Assert.Equal(7, exportedItems.Count); + Assert.Equal(11, exportedItems.Count); // check serialization for longCounter this.CheckSerializationForSingleMetricPoint(exportedItems[0], exporter, exporterOptions); @@ -229,20 +251,32 @@ public void SuccessfulSerialization(bool testMaxLimits) // check serialization for doubleCounter this.CheckSerializationForSingleMetricPoint(exportedItems[1], exporter, exporterOptions); - // check serialization for histogram + // check serialization for longUpDownCounter this.CheckSerializationForSingleMetricPoint(exportedItems[2], exporter, exporterOptions); - // check serialization for observableLongCounter + // check serialization for doubleUpDownCounter this.CheckSerializationForSingleMetricPoint(exportedItems[3], exporter, exporterOptions); - // check serialization for observableDoubleCounter + // check serialization for histogram this.CheckSerializationForSingleMetricPoint(exportedItems[4], exporter, exporterOptions); - // check serialization for observableLongGauge + // check serialization for observableLongCounter this.CheckSerializationForSingleMetricPoint(exportedItems[5], exporter, exporterOptions); - // check serialization for observableDoubleGauge + // check serialization for observableDoubleCounter this.CheckSerializationForSingleMetricPoint(exportedItems[6], exporter, exporterOptions); + + // check serialization for observableLongGauge + this.CheckSerializationForSingleMetricPoint(exportedItems[7], exporter, exporterOptions); + + // check serialization for observableDoubleGauge + this.CheckSerializationForSingleMetricPoint(exportedItems[8], exporter, exporterOptions); + + // check serialization for observableUpDownLongCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[9], exporter, exporterOptions); + + // check serialization for observableUpDownDoubleCounter + this.CheckSerializationForSingleMetricPoint(exportedItems[10], exporter, exporterOptions); } finally { @@ -653,6 +687,27 @@ private void CheckSerializationForSingleMetricPoint(Metric metric, GenevaMetricE Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); Assert.Equal(bodyLength, data.LenBody); } + else if (metricType == MetricType.LongSumNonMonotonic || metricType == MetricType.DoubleSumNonMonotonic) + { + var metricDataValue = metricType == MetricType.LongSumNonMonotonic ? + Convert.ToDouble(metricPoint.GetSumLong()) : + Convert.ToDouble(metricPoint.GetSumDouble()); + var metricData = new MetricData { DoubleValue = metricDataValue }; + var bodyLength = exporter.SerializeMetric( + MetricEventType.DoubleMetric, + metric.Name, + metricPoint.EndTime.ToFileTime(), + metricPoint.Tags, + metricData); + var buffer = typeof(GenevaMetricExporter).GetField("bufferForNonHistogramMetrics", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(exporter) as byte[]; + var stream = new KaitaiStream(buffer); + data = new MetricsContract(stream); + var valueSection = data.Body.ValueSection as SingleDoubleValue; + Assert.Equal(metricDataValue, valueSection.Value); + Assert.Equal((ulong)metricPoint.EndTime.ToFileTime(), valueSection.Timestamp); + Assert.Equal((ushort)MetricEventType.DoubleMetric, data.EventId); + Assert.Equal(bodyLength, data.LenBody); + } else if (metricType == MetricType.Histogram) { var sum = new MetricData { UInt64Value = Convert.ToUInt64(metricPoint.GetHistogramSum()) }; diff --git a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj index c7115ee052..ddbb67ecd0 100644 --- a/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj +++ b/test/OpenTelemetry.Exporter.Geneva.Tests/OpenTelemetry.Exporter.Geneva.Tests.csproj @@ -2,7 +2,7 @@ Unit test project for Geneva Exporters for OpenTelemetry - netcoreapp3.1;net6.0 + net6.0 $(TargetFrameworks);net462;net47;net471;net472;net48 $(NoWarn),SA1311,SA1312,SA1313,SA1123,SA1202 @@ -31,7 +31,7 @@ - +