Skip to content
Merged
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ This component adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.h
- Environment variables `OTEL_DOTNET_AUTO_TRACES_CONSOLE_EXPORTER_ENABLED`,
`OTEL_DOTNET_AUTO_METRICS_CONSOLE_EXPORTER_ENABLED`, and
`OTEL_DOTNET_AUTO_LOGS_CONSOLE_EXPORTER_ENABLED` are now marked as deprecated.
- Support signal specific OTLP exporter variables (See [docs](/docs/config.md#otlp)):
- `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`,
- `OTEL_EXPORTER_OTLP_TRACES_HEADERS`,
- `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT`,
- `OTEL_EXPORTER_OTLP_TRACES_PROTOCOL`,
- `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`,
- `OTEL_EXPORTER_OTLP_METRICS_HEADERS`,
- `OTEL_EXPORTER_OTLP_METRICS_TIMEOUT`,
- `OTEL_EXPORTER_OTLP_METRICS_PROTOCOL`,
- `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`,
- `OTEL_EXPORTER_OTLP_LOGS_HEADERS`,
- `OTEL_EXPORTER_OTLP_LOGS_TIMEOUT`,
- `OTEL_EXPORTER_OTLP_LOGS_PROTOCOL`.

### Changed

Expand Down
42 changes: 27 additions & 15 deletions docs/config.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,23 @@ public Configuration(bool failFast, params IConfigurationSource[] sources)
return _sources.Select(source => source.GetBool(key))
.FirstOrDefault(value => value.HasValue);
}

/// <summary>
/// Gets the <see cref="Uri"/> value of the first setting found with
/// the specified key from the current list of configuration sources.
/// Sources are queried in the order in which they were added.
/// </summary>
/// <param name="key">The key that identifies the setting.</param>
/// <returns>The value of the setting, or <c>null</c> if not found.</returns>
public Uri? GetUri(string key)
{
var value = GetString(key);

if (Uri.TryCreate(value, UriKind.Absolute, out var uri))
{
return uri;
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ internal partial class ConfigurationKeys
public const string ProfilingEnabled = "CORECLR_ENABLE_PROFILING";
#endif

/// <summary>
/// Configuration key for the OTLP protocol to be used.
/// Default is <c>"http/protobuf"</c>.
/// </summary>
public const string ExporterOtlpProtocol = "OTEL_EXPORTER_OTLP_PROTOCOL";

/// <summary>
/// Configuration key for enabling the flushing of telemetry data when an unhandled exception occurs.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,8 @@ public static MeterProviderBuilder AddOtlpExporter(MeterProviderBuilder builder,
{
return builder.AddOtlpExporter((options, metricReaderOptions) =>
{
if (settings.OtlpExportProtocol.HasValue)
{
options.Protocol = settings.OtlpExportProtocol.Value;
}
// Copy Auto settings to SDK settings
settings.OtlpSettings?.CopyTo(options);

pluginManager.ConfigureMetricsOptions(options);
pluginManager.ConfigureMetricsOptions(metricReaderOptions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,8 @@ public static TracerProviderBuilder AddOtlpExporter(TracerProviderBuilder builde
{
return builder.AddOtlpExporter(options =>
{
if (settings.OtlpExportProtocol.HasValue)
{
options.Protocol = settings.OtlpExportProtocol.Value;
}
// Copy Auto settings to SDK settings
settings.OtlpSettings?.CopyTo(options);

pluginManager.ConfigureTracesOptions(options);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using OpenTelemetry.AutoInstrumentation.Configurations.Otlp;
using OpenTelemetry.AutoInstrumentation.Logging;

namespace OpenTelemetry.AutoInstrumentation.Configurations;
Expand Down Expand Up @@ -32,11 +33,21 @@ internal class LogSettings : Settings
/// </summary>
public IReadOnlyList<LogInstrumentation> EnabledInstrumentations { get; private set; } = new List<LogInstrumentation>();

/// <summary>
/// Gets logs OTLP Settings.
/// </summary>
public OtlpSettings? OtlpSettings { get; private set; }

protected override void OnLoad(Configuration configuration)
{
LogsEnabled = configuration.GetBool(ConfigurationKeys.Logs.LogsEnabled) ?? true;
var consoleExporterEnabled = configuration.GetBool(ConfigurationKeys.Logs.ConsoleExporterEnabled) ?? false;
LogExporters = ParseLogExporter(configuration, consoleExporterEnabled);
if (LogExporters.Contains(LogExporter.Otlp))
{
OtlpSettings = new OtlpSettings(OtlpSignalType.Logs, configuration);
}

IncludeFormattedMessage = configuration.GetBool(ConfigurationKeys.Logs.IncludeFormattedMessage) ?? false;

var instrumentationEnabledByDefault =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using OpenTelemetry.AutoInstrumentation.Configurations.Otlp;
using OpenTelemetry.AutoInstrumentation.Logging;

namespace OpenTelemetry.AutoInstrumentation.Configurations;
Expand Down Expand Up @@ -32,10 +33,19 @@ internal class MetricSettings : Settings
/// </summary>
public IList<string> Meters { get; } = new List<string>();

/// <summary>
/// Gets metrics OTLP Settings.
/// </summary>
public OtlpSettings? OtlpSettings { get; private set; }

protected override void OnLoad(Configuration configuration)
{
var consoleExporterEnabled = configuration.GetBool(ConfigurationKeys.Metrics.ConsoleExporterEnabled) ?? false;
MetricExporters = ParseMetricExporter(configuration, consoleExporterEnabled);
if (MetricExporters.Contains(MetricsExporter.Otlp))
{
OtlpSettings = new OtlpSettings(OtlpSignalType.Metrics, configuration);
}

var instrumentationEnabledByDefault =
configuration.GetBool(ConfigurationKeys.Metrics.MetricsInstrumentationEnabled) ??
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using OpenTelemetry.Exporter;

namespace OpenTelemetry.AutoInstrumentation.Configurations.Otlp;

/// <summary>
/// Overrides SDK logic and sets separate values for every signal
/// when more detailed environment variable is set.
/// </summary>
internal class OtlpSettings
{
public OtlpSettings(OtlpSignalType signalType, Configuration configuration)
{
Protocol = GetExporterOtlpProtocol(signalType, configuration);

var priorityVar = OtlpSpecConfigDefinitions.GetHeadersEnvVar(signalType);
Headers = configuration.GetString(priorityVar);

priorityVar = OtlpSpecConfigDefinitions.GetTimeoutEnvVar(signalType);
TimeoutMilliseconds = configuration.GetInt32(priorityVar);

priorityVar = OtlpSpecConfigDefinitions.GetEndpointEnvVar(signalType);
Endpoint = configuration.GetUri(priorityVar);
}

/// <summary>
/// Gets the OTLP transport protocol. Supported values: Grpc and HttpProtobuf.
/// </summary>
public OtlpExportProtocol? Protocol { get; private set; }

/// <summary>
/// Gets the optional headers for the connection.
/// </summary>
public string? Headers { get; private set; }

/// <summary>
/// Gets the max waiting time (in milliseconds) for the backend to
/// process each batch. Default value: <c>10000</c>.
/// </summary>
public int? TimeoutMilliseconds { get; private set; }

/// <summary>
/// Gets the target to which the exporter is going to send telemetry.
/// </summary>
public Uri? Endpoint { get; private set; }

public void CopyTo(OtlpExporterOptions options)
{
if (Protocol.HasValue)
{
options.Protocol = Protocol.Value;
}

if (!string.IsNullOrWhiteSpace(Headers))
{
options.Headers = Headers;
}

if (Endpoint is not null)
{
// NOTE! This must be always full path. Endpoint setter is disabling further path handling in SDK side.
options.Endpoint = Endpoint;
}

if (TimeoutMilliseconds.HasValue)
{
options.TimeoutMilliseconds = TimeoutMilliseconds.Value;
}
}

private static OtlpExportProtocol? GetExporterOtlpProtocol(OtlpSignalType signalType, Configuration configuration)
{
// the default in SDK is grpc. http/protobuf should be default for our purposes
var priorityVar = OtlpSpecConfigDefinitions.GetProtocolEnvVar(signalType);
var exporterOtlpProtocol = configuration.GetString(priorityVar) ??
configuration.GetString(OtlpSpecConfigDefinitions.DefaultProtocolEnvVarName);

if (string.IsNullOrEmpty(exporterOtlpProtocol))
Comment thread
zacharycmontoya marked this conversation as resolved.
{
// override settings only for http/protobuf
return OtlpExportProtocol.HttpProtobuf;
}

// null value here means that it will be handled by OTEL .NET SDK
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

namespace OpenTelemetry.AutoInstrumentation.Configurations.Otlp;

internal enum OtlpSignalType
{
Traces,
Metrics,
Logs
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

namespace OpenTelemetry.AutoInstrumentation.Configurations.Otlp;

/// <summary>
/// Contains spec environment variable key definitions for OpenTelemetry Protocol (OTLP) exporter.
/// </summary>
/// <remarks>
/// Specification: <see href="https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md"/>.
/// </remarks>
internal static class OtlpSpecConfigDefinitions
{
public const string DefaultEndpointEnvVarName = "OTEL_EXPORTER_OTLP_ENDPOINT";
public const string DefaultHeadersEnvVarName = "OTEL_EXPORTER_OTLP_HEADERS";
public const string DefaultTimeoutEnvVarName = "OTEL_EXPORTER_OTLP_TIMEOUT";
public const string DefaultProtocolEnvVarName = "OTEL_EXPORTER_OTLP_PROTOCOL";

public const string LogsEndpointEnvVarName = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT";
public const string LogsHeadersEnvVarName = "OTEL_EXPORTER_OTLP_LOGS_HEADERS";
public const string LogsTimeoutEnvVarName = "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT";
public const string LogsProtocolEnvVarName = "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL";

public const string MetricsEndpointEnvVarName = "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT";
public const string MetricsHeadersEnvVarName = "OTEL_EXPORTER_OTLP_METRICS_HEADERS";
public const string MetricsTimeoutEnvVarName = "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT";
public const string MetricsProtocolEnvVarName = "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL";

public const string TracesEndpointEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
public const string TracesHeadersEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_HEADERS";
public const string TracesTimeoutEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT";
public const string TracesProtocolEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL";

public static string GetProtocolEnvVar(OtlpSignalType signal) => signal switch
{
OtlpSignalType.Traces => TracesProtocolEnvVarName,
OtlpSignalType.Metrics => MetricsProtocolEnvVarName,
OtlpSignalType.Logs => LogsProtocolEnvVarName,
_ => throw new NotSupportedException()
};

public static string GetHeadersEnvVar(OtlpSignalType signal) => signal switch
{
OtlpSignalType.Traces => TracesHeadersEnvVarName,
OtlpSignalType.Metrics => MetricsHeadersEnvVarName,
OtlpSignalType.Logs => LogsHeadersEnvVarName,
_ => throw new NotSupportedException()
};

public static string GetEndpointEnvVar(OtlpSignalType signal) => signal switch
{
OtlpSignalType.Traces => TracesEndpointEnvVarName,
OtlpSignalType.Metrics => MetricsEndpointEnvVarName,
OtlpSignalType.Logs => LogsEndpointEnvVarName,
_ => throw new NotSupportedException()
};

public static string GetTimeoutEnvVar(OtlpSignalType signal) => signal switch
{
OtlpSignalType.Traces => TracesTimeoutEnvVarName,
OtlpSignalType.Metrics => MetricsTimeoutEnvVarName,
OtlpSignalType.Logs => LogsTimeoutEnvVarName,
_ => throw new NotSupportedException()
};
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using OpenTelemetry.Exporter;

namespace OpenTelemetry.AutoInstrumentation.Configurations;

/// <summary>
/// Global Settings
/// </summary>
internal abstract class Settings
{
/// <summary>
/// Gets the the OTLP transport protocol. Supported values: Grpc and HttpProtobuf.
/// </summary>
public OtlpExportProtocol? OtlpExportProtocol { get; private set; }

public static T FromDefaultSources<T>(bool failFast)
where T : Settings, new()
{
Expand All @@ -26,7 +19,6 @@ public static T FromDefaultSources<T>(bool failFast)

public void Load(Configuration configuration)
{
OtlpExportProtocol = GetExporterOtlpProtocol(configuration);
OnLoad(configuration);
}

Expand All @@ -36,19 +28,4 @@ public void Load(Configuration configuration)
/// </summary>
/// <param name="configuration">The <see cref="Configuration"/> to use when retrieving configuration values.</param>
protected abstract void OnLoad(Configuration configuration);

private static OtlpExportProtocol? GetExporterOtlpProtocol(Configuration configuration)
{
// the default in SDK is grpc. http/protobuf should be default for our purposes
var exporterOtlpProtocol = configuration.GetString(ConfigurationKeys.ExporterOtlpProtocol);

if (string.IsNullOrEmpty(exporterOtlpProtocol))
{
// override settings only for http/protobuf
return Exporter.OtlpExportProtocol.HttpProtobuf;
}

// null value here means that it will be handled by OTEL .NET SDK
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using OpenTelemetry.AutoInstrumentation.Configurations.Otlp;
using OpenTelemetry.AutoInstrumentation.Logging;

namespace OpenTelemetry.AutoInstrumentation.Configurations;
Expand Down Expand Up @@ -47,10 +48,19 @@ internal class TracerSettings : Settings
/// </summary>
public InstrumentationOptions InstrumentationOptions { get; private set; } = new(new Configuration(failFast: false));

/// <summary>
/// Gets tracing OTLP Settings.
/// </summary>
public OtlpSettings? OtlpSettings { get; private set; }

protected override void OnLoad(Configuration configuration)
{
var consoleExporterEnabled = configuration.GetBool(ConfigurationKeys.Traces.ConsoleExporterEnabled) ?? false;
TracesExporters = ParseTracesExporter(configuration, consoleExporterEnabled);
if (TracesExporters.Contains(TracesExporter.Otlp))
{
OtlpSettings = new OtlpSettings(OtlpSignalType.Traces, configuration);
}

var instrumentationEnabledByDefault =
configuration.GetBool(ConfigurationKeys.Traces.TracesInstrumentationEnabled) ??
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,8 @@ private static void AddOpenTelemetryLogs(ILoggingBuilder builder)
case LogExporter.Otlp:
options.AddOtlpExporter(otlpOptions =>
{
if (settings.OtlpExportProtocol.HasValue)
{
otlpOptions.Protocol = settings.OtlpExportProtocol.Value;
}
// Copy Auto settings to SDK settings
settings.OtlpSettings?.CopyTo(otlpOptions);

pluginManager?.ConfigureLogsOptions(otlpOptions);
});
Expand Down
Loading