diff --git a/README.md b/README.md index 62d0730..2cc68b3 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,17 @@ directly to [Dynatrace](https://www.dynatrace.com). More information on exporting OpenTelemetry metrics to Dynatrace can be found in the [Dynatrace documentation](https://www.dynatrace.com/support/help/extend-dynatrace/opentelemetry/opentelemetry-metrics). -This exporter is built against the OpenTelemetry .NET -SDK [v1.2.0](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/core-1.2.0) which is the first stable -release for the metrics SDK and should be compatible with this and later versions. +This exporter is built against the OpenTelemetry .NET SDK +[v1.2.0](https://github.com/open-telemetry/opentelemetry-dotnet/releases/tag/core-1.2.0). +It should be compatible with applications targeting OpenTelemetry .NET SDK version 1.2.0 and higher. + +> It is highly recommended to update the OpenTelemetry .NET SDK in your applications to version `1.3.1` or later +> to avoid being impacted by this issue: +> [Possible app crash for OpenTelemetry .NET versions 1.3.0 and prior](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3629) ## Getting started -The general setup of OpenTelemetry .NET is explained in the official [Getting Started Guide](https://github.com/open-telemetry/opentelemetry-dotnet/blob/core-1.2.0/docs/metrics/getting-started/README.md). +The general setup of OpenTelemetry .NET is explained in the official [Getting Started Guide](https://github.com/open-telemetry/opentelemetry-dotnet/blob/core-1.3.2/docs/metrics/getting-started/README.md). To add the exporter to your project, install the [Dynatrace.OpenTelemetry.Exporter.Metrics](https://www.nuget.org/packages/Dynatrace.OpenTelemetry.Exporter.Metrics) package to your project. This can be done through the NuGet package manager in Visual Studio or by running the following command in your project folder: @@ -21,13 +25,19 @@ This can be done through the NuGet package manager in Visual Studio or by runnin dotnet add package Dynatrace.OpenTelemetry.Exporter.Metrics ``` -This exporter package targets [.NET Standard 2.0](https://docs.microsoft.com/en-us/dotnet/standard/net-standard) and can therefore be included on .NET Core 2.0 and above, as well as .NET Framework 4.6.1 and above. +This exporter package targets [.NET Standard 2.0](https://docs.microsoft.com/en-us/dotnet/standard/net-standard) and can therefore be included on .NET Core 2.0 and above, as well as .NET Framework 4.6.2 and above. ### Setup To set up a Dynatrace metrics exporter, add the following code to your project: ```csharp +using System.Diagnostics; +using System.Diagnostics.Metrics; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using Dynatrace.OpenTelemetry.Exporter.Metrics; + // A Meter instance is obtained via the System.Diagnostics.DiagnosticSource package var meter = new Meter("my_meter", "0.0.1"); @@ -59,6 +69,13 @@ and it is recommended to restrict the token access to that scope. More information about the token setup can be found [here](#dynatrace-api-token). ```csharp +using System.Diagnostics; +using System.Diagnostics.Metrics; +using Microsoft.Extensions.Logging; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using Dynatrace.OpenTelemetry.Exporter.Metrics; + // Not required, but potentially helpful. // The exporter logs information about preparing and exporting metrics. var loggerFactory = LoggerFactory.Create(builder => @@ -96,6 +113,13 @@ configured in the `DynatraceExporterOptions`. Read the [Configuration section](#configuration) to learn more about each of them. ```csharp +using System.Diagnostics; +using System.Diagnostics.Metrics; +using Microsoft.Extensions.Logging; +using OpenTelemetry; +using OpenTelemetry.Metrics; +using Dynatrace.OpenTelemetry.Exporter.Metrics; + using var provider = Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) .AddDynatraceExporter(cfg => diff --git a/src/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests.csproj b/src/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests.csproj index 762254b..e494598 100644 --- a/src/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests.csproj +++ b/src/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests.csproj @@ -9,8 +9,7 @@ - - + diff --git a/src/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests/DynatraceMetricsExporterTests.cs b/src/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests/DynatraceMetricsExporterTests.cs index 41787cf..7eaa987 100644 --- a/src/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests/DynatraceMetricsExporterTests.cs +++ b/src/Dynatrace.OpenTelemetry.Exporter.Metrics.Tests/DynatraceMetricsExporterTests.cs @@ -18,6 +18,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Metrics; +using System.Globalization; using System.Linq; using System.Net; using System.Net.Http; @@ -728,6 +729,67 @@ public async Task Export_Histogram_ShouldSetMinAndMaxCorrectly(MinMaxEstimationD AssertExportRequest(actualRequestMessage); } + [Theory] + [InlineData("en-US")] + [InlineData("en-GB")] + [InlineData("pt-BR")] + [InlineData("de-AT")] + [InlineData("fi-FI")] + public async Task TestAllInstrumentsWithCulture(string locale) + { + var originalCulture = Thread.CurrentThread.CurrentCulture; + Thread.CurrentThread.CurrentCulture = new CultureInfo(locale); + + // Arrange + HttpRequestMessage actualRequestMessage = null!; + var mockMessageHandler = SetupHttpMock(r => actualRequestMessage = r); + + var sut = new DynatraceMetricsExporter(null, null, new HttpClient(mockMessageHandler.Object)); + + var longCounter = _meter.CreateCounter("counter"); + longCounter.Add(10); + + var doubleCounter = _meter.CreateCounter("double_counter"); + doubleCounter.Add(10.3); + + _meter.CreateObservableCounter("obs_counter", + () => new List> { new(1 * 10) }); + + _meter.CreateObservableCounter("double_obs_counter", + () => new List> { new(1 * 10.3, _attributes) }); + + var longHistogram = _meter.CreateHistogram("histogram"); + longHistogram.Record(1); + longHistogram.Record(6); + longHistogram.Record(11); + longHistogram.Record(21); + + var doubleHistogram = _meter.CreateHistogram("double_histogram"); + doubleHistogram.Record(1.1); + doubleHistogram.Record(6.2); + doubleHistogram.Record(11.3); + doubleHistogram.Record(21.23); + + // Act + _meterProvider.ForceFlush(); + sut.Export(new Batch(_exportedMetrics.ToArray(), _exportedMetrics.Count)); + + // Assert + var point = MetricTest.FromMetricPoints(_exportedMetrics.First().GetMetricPoints()).First(); + + var expected = @$"counter,dt.metrics.source=opentelemetry count,delta=10 {point.TimeStamp} +double_counter,dt.metrics.source=opentelemetry count,delta=10.3 {point.TimeStamp} +obs_counter,dt.metrics.source=opentelemetry count,delta=10 {point.TimeStamp} +double_obs_counter,attr1=v1,attr2=v2,dt.metrics.source=opentelemetry count,delta=10.3 {point.TimeStamp} +histogram,dt.metrics.source=opentelemetry gauge,min=0,max=25,sum=39,count=4 {point.TimeStamp} +double_histogram,dt.metrics.source=opentelemetry gauge,min=0,max=25,sum=39.83,count=4 {point.TimeStamp}"; + + var actualMetricString = await actualRequestMessage.Content!.ReadAsStringAsync(); + Assert.Equal(expected, actualMetricString); + + Thread.CurrentThread.CurrentCulture = originalCulture; + } + private static Mock SetupHttpMock( Action? setter = null, HttpStatusCode? statusCode = null, diff --git a/src/Dynatrace.OpenTelemetry.Exporter.Metrics/Dynatrace.OpenTelemetry.Exporter.Metrics.csproj b/src/Dynatrace.OpenTelemetry.Exporter.Metrics/Dynatrace.OpenTelemetry.Exporter.Metrics.csproj index 3a69782..752abde 100644 --- a/src/Dynatrace.OpenTelemetry.Exporter.Metrics/Dynatrace.OpenTelemetry.Exporter.Metrics.csproj +++ b/src/Dynatrace.OpenTelemetry.Exporter.Metrics/Dynatrace.OpenTelemetry.Exporter.Metrics.csproj @@ -6,7 +6,7 @@ Dynatrace Dynatrace OpenTelemetry Metrics Exporter for .NET Dynatrace.OpenTelemetry.Exporter.Metrics - 1.0.0 + 1.0.1 See https://github.com/dynatrace-oss/opentelemetry-metric-dotnet to learn more. Apache-2.0 Copyright 2020 Dynatrace LLC; Licensed under the Apache License, Version 2.0 @@ -19,7 +19,7 @@ - + diff --git a/src/Dynatrace.OpenTelemetry.Exporter.Metrics/DynatraceMetricsExporterExtensions.cs b/src/Dynatrace.OpenTelemetry.Exporter.Metrics/DynatraceMetricsExporterExtensions.cs index a90b0d3..6f223f6 100644 --- a/src/Dynatrace.OpenTelemetry.Exporter.Metrics/DynatraceMetricsExporterExtensions.cs +++ b/src/Dynatrace.OpenTelemetry.Exporter.Metrics/DynatraceMetricsExporterExtensions.cs @@ -62,8 +62,10 @@ private static MeterProviderBuilder AddDynatraceExporter( } var metricExporter = new DynatraceMetricsExporter(options, logger); - var metricReader = new PeriodicExportingMetricReader(metricExporter, options.MetricExportIntervalMilliseconds); - metricReader.TemporalityPreference = MetricReaderTemporalityPreference.Delta; + var metricReader = new PeriodicExportingMetricReader(metricExporter, options.MetricExportIntervalMilliseconds) + { + TemporalityPreference = MetricReaderTemporalityPreference.Delta + }; return builder.AddReader(metricReader); } } diff --git a/src/Examples.Console/Examples.Console.csproj b/src/Examples.Console/Examples.Console.csproj index ff0f6ef..6aad683 100644 --- a/src/Examples.Console/Examples.Console.csproj +++ b/src/Examples.Console/Examples.Console.csproj @@ -7,6 +7,7 @@ +