Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support OTEL_METRIC_EXPORT_INTERVAL and OTEL_METRIC_EXPORT_TIMEOUT #3424

Merged
merged 7 commits into from
Jul 15, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/OpenTelemetry.Exporter.Console/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

* The `MetricReaderOptions` defaults can be overridden using
`OTEL_METRIC_EXPORT_INTERVAL` and `OTEL_METRIC_EXPORT_TIMEOUT`
environmental variables as defined in the
[specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).
([#3424](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3424))

## 1.3.0

Released 2022-Jun-03
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</ItemGroup>

<ItemGroup>
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\EnvironmentVariableHelper.cs" Link="Includes\EnvironmentVariableHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\OpenTelemetrySdkEventSource.cs" Link="Includes\OpenTelemetrySdkEventSource.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\PeriodicExportingMetricReaderHelper.cs" Link="Includes\PeriodicExportingMetricReaderHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\ServiceProviderExtensions.cs" Link="Includes\ServiceProviderExtensions.cs" />
Expand Down
24 changes: 24 additions & 0 deletions src/OpenTelemetry.Exporter.Console/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,30 @@ used:
* [Metrics](../../docs/metrics/getting-started/Program.cs)
* [Traces](../../docs/trace/getting-started/Program.cs)

## Configuration

See the
[`TestConsoleExporter.cs`](../../examples/Console/TestConsoleExporter.cs) for
an example of how to use the exporter for exporting traces to a collection.

You can configure the `ConsoleExporter` through `Options` types properties
and environment variables.
The `Options` type setters take precedence over the environment variables.

## Environment Variables

The following environment variables can be used to override the default
values of the `PeriodicExportingMetricReaderOptions`
(following the [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).

| Environment variable | `PeriodicExportingMetricReaderOptions` property |
| ------------------------------| ------------------------------------------------|
| `OTEL_METRIC_EXPORT_INTERVAL` | `ExportIntervalMilliseconds` |
| `OTEL_METRIC_EXPORT_TIMEOUT` | `ExportTimeoutMilliseconds` |

`FormatException` is thrown in case of an invalid value for any of the
supported environment variables.

## References

* [OpenTelemetry Project](https://opentelemetry.io/)
6 changes: 6 additions & 0 deletions src/OpenTelemetry.Exporter.InMemory/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
* `InMemoryExporter` will now buffer scopes when exporting `LogRecord`
([#3360](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3360))

* The `MetricReaderOptions` defaults can be overridden using
`OTEL_METRIC_EXPORT_INTERVAL` and `OTEL_METRIC_EXPORT_TIMEOUT`
environmental variables as defined in the
[specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).
([#3424](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3424))

## 1.3.0

Released 2022-Jun-03
Expand Down
18 changes: 18 additions & 0 deletions src/OpenTelemetry.Exporter.InMemory/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ See the
[`TestInMemoryExporter.cs`](../../examples/Console/TestInMemoryExporter.cs) for
an example of how to use the exporter for exporting traces to a collection.

You can configure the `InMemoryExporter` through `Options` types properties
and environment variables.
The `Options` type setters take precedence over the environment variables.

## Environment Variables

The following environment variables can be used to override the default
values of the `PeriodicExportingMetricReaderOptions`
(following the [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).

| Environment variable | `PeriodicExportingMetricReaderOptions` property |
| ------------------------------| ------------------------------------------------|
| `OTEL_METRIC_EXPORT_INTERVAL` | `ExportIntervalMilliseconds` |
| `OTEL_METRIC_EXPORT_TIMEOUT` | `ExportTimeoutMilliseconds` |

`FormatException` is thrown in case of an invalid value for any of the
supported environment variables.

## References

* [OpenTelemetry Project](https://opentelemetry.io/)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Unreleased

* The `MetricReaderOptions` defaults can be overridden using
`OTEL_METRIC_EXPORT_INTERVAL` and `OTEL_METRIC_EXPORT_TIMEOUT`
environmental variables as defined in the
[specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).
([#3424](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3424))

## 1.3.0

Released 2022-Jun-03
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ namespace OpenTelemetry.Metrics
/// </summary>
public static class OtlpMetricExporterExtensions
{
private const int DefaultExportIntervalMilliseconds = 60000;
private const int DefaultExportTimeoutMilliseconds = 30000;

/// <summary>
/// Adds <see cref="OtlpMetricExporter"/> to the <see cref="MeterProviderBuilder"/> using default options.
/// </summary>
Expand Down Expand Up @@ -111,9 +108,7 @@ internal static MeterProviderBuilder AddOtlpExporter(

var metricReader = PeriodicExportingMetricReaderHelper.CreatePeriodicExportingMetricReader(
metricExporter,
metricReaderOptions,
DefaultExportIntervalMilliseconds,
DefaultExportTimeoutMilliseconds);
metricReaderOptions);

return builder.AddReader(metricReader);
}
Expand Down
15 changes: 12 additions & 3 deletions src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ dotnet add package OpenTelemetry.Exporter.OpenTelemetryProtocol

## Configuration

You can configure the `OtlpExporter` through `OtlpExporterOptions`
properties and environment variables. The `OtlpExporterOptions`
setters take precedence over the environment variables.
You can configure the `OtlpExporter` through `Options` types properties
pellared marked this conversation as resolved.
Show resolved Hide resolved
and environment variables.
The `Options` type setters take precedence over the environment variables.

## Options Properties

Expand Down Expand Up @@ -63,6 +63,15 @@ values of the `OtlpExporterOptions`
| `OTEL_EXPORTER_OTLP_TIMEOUT` | `TimeoutMilliseconds` |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | `Protocol` (`grpc` or `http/protobuf`)|

The following environment variables can be used to override the default
values of the `PeriodicExportingMetricReaderOptions`
(following the [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.12.0/specification/sdk-environment-variables.md#periodic-exporting-metricreader).

| Environment variable | `PeriodicExportingMetricReaderOptions` property |
| ------------------------------| ------------------------------------------------|
| `OTEL_METRIC_EXPORT_INTERVAL` | `ExportIntervalMilliseconds` |
| `OTEL_METRIC_EXPORT_TIMEOUT` | `ExportTimeoutMilliseconds` |

`FormatException` is thrown in case of an invalid value for any of the
supported environment variables.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,32 @@
// limitations under the License.
// </copyright>

using OpenTelemetry.Internal;

namespace OpenTelemetry.Metrics;

internal static class PeriodicExportingMetricReaderHelper
{
internal const string OTelMetricExportIntervalEnvVarKey = "OTEL_METRIC_EXPORT_INTERVAL";
internal const int DefaultExportIntervalMilliseconds = 60000;
internal const string OTelMetricExportTimeoutEnvVarKey = "OTEL_METRIC_EXPORT_TIMEOUT";
internal const int DefaultExportTimeoutMilliseconds = 30000;

internal static PeriodicExportingMetricReader CreatePeriodicExportingMetricReader(
BaseExporter<Metric> exporter,
MetricReaderOptions options,
int defaultExportIntervalMilliseconds,
int defaultExportTimeoutMilliseconds)
int defaultExportIntervalMilliseconds = DefaultExportIntervalMilliseconds,
int defaultExportTimeoutMilliseconds = DefaultExportTimeoutMilliseconds)
{
var exportInterval =
options.PeriodicExportingMetricReaderOptions?.ExportIntervalMilliseconds
?? defaultExportIntervalMilliseconds;
var exportInterval = GetValue(
options.PeriodicExportingMetricReaderOptions?.ExportIntervalMilliseconds,
OTelMetricExportIntervalEnvVarKey,
defaultExportIntervalMilliseconds);

var exportTimeout =
options.PeriodicExportingMetricReaderOptions?.ExportTimeoutMilliseconds
?? defaultExportTimeoutMilliseconds;
var exportTimeout = GetValue(
options.PeriodicExportingMetricReaderOptions?.ExportTimeoutMilliseconds,
OTelMetricExportTimeoutEnvVarKey,
defaultExportTimeoutMilliseconds);

var metricReader = new PeriodicExportingMetricReader(exporter, exportInterval, exportTimeout)
{
Expand All @@ -39,4 +48,19 @@ internal static PeriodicExportingMetricReader CreatePeriodicExportingMetricReade

return metricReader;
}

private static int GetValue(int? optionsValue, string envVarKey, int defaultValue)
pellared marked this conversation as resolved.
Show resolved Hide resolved
{
if (optionsValue.HasValue)
{
return optionsValue.Value;
}

if (EnvironmentVariableHelper.LoadNumeric(envVarKey, out var envVarValue))
{
return envVarValue;
}

return defaultValue;
}
}
10 changes: 5 additions & 5 deletions src/OpenTelemetry/Metrics/PeriodicExportingMetricReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class PeriodicExportingMetricReader : BaseExportingMetricReader
internal const int DefaultExportTimeoutMilliseconds = 30000;

internal readonly int ExportIntervalMilliseconds;
private readonly int exportTimeoutMilliseconds;
internal readonly int ExportTimeoutMilliseconds;
private readonly Thread exporterThread;
private readonly AutoResetEvent exportTrigger = new(false);
private readonly ManualResetEvent shutdownTrigger = new(false);
Expand Down Expand Up @@ -60,7 +60,7 @@ public PeriodicExportingMetricReader(
}

this.ExportIntervalMilliseconds = exportIntervalMilliseconds;
this.exportTimeoutMilliseconds = exportTimeoutMilliseconds;
this.ExportTimeoutMilliseconds = exportTimeoutMilliseconds;

this.exporterThread = new Thread(new ThreadStart(this.ExporterProc))
{
Expand Down Expand Up @@ -141,15 +141,15 @@ private void ExporterProc()
{
case 0: // export
OpenTelemetrySdkEventSource.Log.MetricReaderEvent("PeriodicExportingMetricReader calling MetricReader.Collect because Export was triggered.");
this.Collect(this.exportTimeoutMilliseconds);
this.Collect(this.ExportTimeoutMilliseconds);
break;
case 1: // shutdown
OpenTelemetrySdkEventSource.Log.MetricReaderEvent("PeriodicExportingMetricReader calling MetricReader.Collect because Shutdown was triggered.");
this.Collect(this.exportTimeoutMilliseconds); // TODO: do we want to use the shutdown timeout here?
this.Collect(this.ExportTimeoutMilliseconds); // TODO: do we want to use the shutdown timeout here?
return;
case WaitHandle.WaitTimeout: // timer
OpenTelemetrySdkEventSource.Log.MetricReaderEvent("PeriodicExportingMetricReader calling MetricReader.Collect because the export interval has elapsed.");
this.Collect(this.exportTimeoutMilliseconds);
this.Collect(this.ExportTimeoutMilliseconds);
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// <copyright file="PeriodicExportingMetricReaderHelperTests.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using System;
using OpenTelemetry.Exporter;
using OpenTelemetry.Metrics;
using Xunit;

namespace OpenTelemetry.Internal.Tests
{
public class PeriodicExportingMetricReaderHelperTests : IDisposable
{
public PeriodicExportingMetricReaderHelperTests()
{
ClearEnvVars();
}

public void Dispose()
{
ClearEnvVars();
}

[Fact]
public void CreatePeriodicExportingMetricReader_Defaults()
{
var reader = CreatePeriodicExportingMetricReader();

Assert.Equal(60000, reader.ExportIntervalMilliseconds);
Assert.Equal(30000, reader.ExportTimeoutMilliseconds);
Assert.Equal(MetricReaderTemporalityPreference.Cumulative, reader.TemporalityPreference);
}

[Fact]
public void CreatePeriodicExportingMetricReader_TemporalityPreference_FromOptions()
{
var value = MetricReaderTemporalityPreference.Delta;
var reader = CreatePeriodicExportingMetricReader(new()
{
TemporalityPreference = value,
});

Assert.Equal(value, reader.TemporalityPreference);
}

[Fact]
public void CreatePeriodicExportingMetricReader_ExportIntervalMilliseconds_FromOptions()
{
Environment.SetEnvironmentVariable(PeriodicExportingMetricReaderHelper.OTelMetricExportIntervalEnvVarKey, "88888"); // should be ignored, as value set via options has higher priority
var value = 123;
var reader = CreatePeriodicExportingMetricReader(new()
{
PeriodicExportingMetricReaderOptions = new()
{
ExportIntervalMilliseconds = value,
},
});

Assert.Equal(value, reader.ExportIntervalMilliseconds);
}

[Fact]
public void CreatePeriodicExportingMetricReader_ExportTimeoutMilliseconds_FromOptions()
{
Environment.SetEnvironmentVariable(PeriodicExportingMetricReaderHelper.OTelMetricExportTimeoutEnvVarKey, "99999"); // should be ignored, as value set via options has higher priority
var value = 456;
var reader = CreatePeriodicExportingMetricReader(new()
{
PeriodicExportingMetricReaderOptions = new()
{
ExportTimeoutMilliseconds = value,
},
});

Assert.Equal(value, reader.ExportTimeoutMilliseconds);
}

[Fact]
public void CreatePeriodicExportingMetricReader_ExportIntervalMilliseconds_FromEnvVar()
{
var value = 789;
Environment.SetEnvironmentVariable(PeriodicExportingMetricReaderHelper.OTelMetricExportIntervalEnvVarKey, value.ToString());
var reader = CreatePeriodicExportingMetricReader();

Assert.Equal(value, reader.ExportIntervalMilliseconds);
}

[Fact]
public void CreatePeriodicExportingMetricReader_ExportTimeoutMilliseconds_FromEnvVar()
{
var value = 246;
Environment.SetEnvironmentVariable(PeriodicExportingMetricReaderHelper.OTelMetricExportTimeoutEnvVarKey, value.ToString());
var reader = CreatePeriodicExportingMetricReader();

Assert.Equal(value, reader.ExportTimeoutMilliseconds);
}

[Fact]
public void EnvironmentVariableNames()
{
Assert.Equal("OTEL_METRIC_EXPORT_INTERVAL", PeriodicExportingMetricReaderHelper.OTelMetricExportIntervalEnvVarKey);
Assert.Equal("OTEL_METRIC_EXPORT_TIMEOUT", PeriodicExportingMetricReaderHelper.OTelMetricExportTimeoutEnvVarKey);
}

private static void ClearEnvVars()
{
Environment.SetEnvironmentVariable(PeriodicExportingMetricReaderHelper.OTelMetricExportIntervalEnvVarKey, null);
Environment.SetEnvironmentVariable(PeriodicExportingMetricReaderHelper.OTelMetricExportTimeoutEnvVarKey, null);
}

private static PeriodicExportingMetricReader CreatePeriodicExportingMetricReader(
MetricReaderOptions options = null)
{
if (options == null)
{
options = new();
}

var dummyMetricExporter = new InMemoryExporter<Metric>(new Metric[0]);
return PeriodicExportingMetricReaderHelper.CreatePeriodicExportingMetricReader(dummyMetricExporter, options);
}
}
}