Skip to content

Commit

Permalink
Add support for OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE env…
Browse files Browse the repository at this point in the history
…ironment variable (#4667)
  • Loading branch information
utpilla committed Jul 19, 2023
1 parent e7f7cd6 commit 4edd9b6
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/OpenTelemetry.Exporter.OpenTelemetryProtocol/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

* Added support for configuring the metric exporter's temporality using the
environment variable `OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE` as
defined in the
[specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.23.0/specification/metrics/sdk_exporters/otlp.md#additional-configuration).
([#4667](https://github.com/open-telemetry/opentelemetry-dotnet/pull/4667))

## 1.6.0-alpha.1

Released 2023-Jul-12
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// limitations under the License.
// </copyright>

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenTelemetry.Exporter;
Expand All @@ -26,6 +27,8 @@ namespace OpenTelemetry.Metrics
/// </summary>
public static class OtlpMetricExporterExtensions
{
internal const string OtlpMetricExporterTemporalityPreferenceEnvVarKey = "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE";

/// <summary>
/// Adds <see cref="OtlpMetricExporter"/> to the <see cref="MeterProviderBuilder"/> using default options.
/// </summary>
Expand Down Expand Up @@ -69,6 +72,17 @@ public static MeterProviderBuilder AddOtlpExporter(this MeterProviderBuilder bui
}
OtlpExporterOptions.RegisterOtlpExporterOptionsFactory(services);
services.AddOptions<MetricReaderOptions>(finalOptionsName).Configure<IConfiguration>(
(readerOptions, config) =>
{
var otlpTemporalityPreference = config[OtlpMetricExporterTemporalityPreferenceEnvVarKey];
if (!string.IsNullOrWhiteSpace(otlpTemporalityPreference)
&& Enum.TryParse<MetricReaderTemporalityPreference>(otlpTemporalityPreference, ignoreCase: true, out var enumValue))
{
readerOptions.TemporalityPreference = enumValue;
}
});
});

return builder.AddReader(sp =>
Expand Down Expand Up @@ -135,6 +149,17 @@ public static MeterProviderBuilder AddOtlpExporter(this MeterProviderBuilder bui
builder.ConfigureServices(services =>
{
OtlpExporterOptions.RegisterOtlpExporterOptionsFactory(services);
services.AddOptions<MetricReaderOptions>(name).Configure<IConfiguration>(
(readerOptions, config) =>
{
var otlpTemporalityPreference = config[OtlpMetricExporterTemporalityPreferenceEnvVarKey];
if (!string.IsNullOrWhiteSpace(otlpTemporalityPreference)
&& Enum.TryParse<MetricReaderTemporalityPreference>(otlpTemporalityPreference, ignoreCase: true, out var enumValue))
{
readerOptions.TemporalityPreference = enumValue;
}
});
});

return builder.AddReader(sp =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
// </copyright>

using System.Diagnostics.Metrics;
using System.Reflection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Exporter.OpenTelemetryProtocol.Implementation;
using OpenTelemetry.Metrics;
Expand Down Expand Up @@ -704,6 +706,50 @@ public void TestHistogramToOtlpMetric(string name, string description, string un
Assert.Empty(dataPoint.Exemplars);
}

[Theory]
[InlineData("cumulative", MetricReaderTemporalityPreference.Cumulative)]
[InlineData("Cumulative", MetricReaderTemporalityPreference.Cumulative)]
[InlineData("CUMULATIVE", MetricReaderTemporalityPreference.Cumulative)]
[InlineData("delta", MetricReaderTemporalityPreference.Delta)]
[InlineData("Delta", MetricReaderTemporalityPreference.Delta)]
[InlineData("DELTA", MetricReaderTemporalityPreference.Delta)]
public void TestTemporalityPreferenceConfiguration(string configValue, MetricReaderTemporalityPreference expectedTemporality)
{
var configData = new Dictionary<string, string> { ["OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE"] = configValue };
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(configData)
.Build();

// Check for both the code paths:
// 1. The final extension method which accepts `Action<OtlpExporterOptions>`.
// 2. The final extension method which accepts `Action<OtlpExporterOptions, MetricReaderOptions>`.

// Test 1st code path
using var meterProvider1 = Sdk.CreateMeterProviderBuilder()
.ConfigureServices(services => services.AddSingleton<IConfiguration>(configuration))
.AddOtlpExporter() // This would in turn call the extension method which accepts `Action<OtlpExporterOptions>`
.Build();

var assembly = typeof(Sdk).Assembly;
var type = assembly.GetType("OpenTelemetry.Metrics.MeterProviderSdk");
var fieldInfo = type.GetField("reader", BindingFlags.Instance | BindingFlags.NonPublic);
var reader = fieldInfo.GetValue(meterProvider1) as MetricReader;
var temporality = reader.TemporalityPreference;

Assert.Equal(expectedTemporality, temporality);

// Test 2nd code path
using var meterProvider2 = Sdk.CreateMeterProviderBuilder()
.ConfigureServices(services => services.AddSingleton<IConfiguration>(configuration))
.AddOtlpExporter((_, _) => { }) // This would in turn call the extension method which accepts `Action<OtlpExporterOptions, MetricReaderOptions>`
.Build();

reader = fieldInfo.GetValue(meterProvider2) as MetricReader;
temporality = reader.TemporalityPreference;

Assert.Equal(expectedTemporality, temporality);
}

private static IEnumerable<KeyValuePair<string, object>> ToAttributes(object[] keysValues)
{
var keys = keysValues?.Where((_, index) => index % 2 == 0).ToArray();
Expand Down

0 comments on commit 4edd9b6

Please sign in to comment.