From 52738a13187a7213df245468070849960b192f8a Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Thu, 21 Nov 2024 15:12:01 +0000 Subject: [PATCH 1/6] Switch to using AddOtlpExporter method We originally used UseOtlpExporter as a nice way to globally enable OTLP export by default for all signals. However, this doesn't play well with the AddOtlpExporter methods which then throw if called by consumer code. This change avoids that risk. It also introduces a LoggingProviderBuilder extension to register our defaults which our main builder calls. --- .../ElasticOpenTelemetryBuilder.cs | 28 +++++++---------- .../LoggingProviderBuilderExtensions.cs | 31 +++++++++++++++++++ .../MeterProviderBuilderExtensions.cs | 5 ++- .../TracerProviderBuilderExtensions.cs | 19 +++++++++--- 4 files changed, 61 insertions(+), 22 deletions(-) create mode 100644 src/Elastic.OpenTelemetry/Extensions/LoggingProviderBuilderExtensions.cs diff --git a/src/Elastic.OpenTelemetry/ElasticOpenTelemetryBuilder.cs b/src/Elastic.OpenTelemetry/ElasticOpenTelemetryBuilder.cs index 6b44c98..7804718 100644 --- a/src/Elastic.OpenTelemetry/ElasticOpenTelemetryBuilder.cs +++ b/src/Elastic.OpenTelemetry/ElasticOpenTelemetryBuilder.cs @@ -4,7 +4,6 @@ using System.Diagnostics; using System.Diagnostics.Tracing; -using System.Reflection; using Elastic.OpenTelemetry.Configuration; using Elastic.OpenTelemetry.Diagnostics; using Elastic.OpenTelemetry.Diagnostics.Logging; @@ -15,10 +14,6 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using OpenTelemetry; -using OpenTelemetry.Logs; -using OpenTelemetry.Metrics; -using OpenTelemetry.Trace; -using static Elastic.OpenTelemetry.Configuration.ElasticOpenTelemetryOptions; namespace Elastic.OpenTelemetry; @@ -112,49 +107,50 @@ public ElasticOpenTelemetryBuilder(ElasticOpenTelemetryBuilderOptions options) openTelemetry.ConfigureResource(r => r.UseElasticDefaults(Logger)); var distro = options.DistroOptions; - //https://github.com/open-telemetry/opentelemetry-dotnet/pull/5400 - if (!distro.SkipOtlpExporter) - openTelemetry.UseOtlpExporter(); - if (distro.Signals.HasFlag(Signals.Logs)) { - //TODO Move to WithLogging once it gets stable - Services.Configure(logging => + openTelemetry.WithLogging(logging => { if (distro.ElasticDefaults.HasFlag(ElasticDefaults.Logs)) - logging.UseElasticDefaults(); + logging.UseElasticDefaults(distro.SkipOtlpExporter, Logger); else Logger.LogDefaultsDisabled(nameof(ElasticDefaults.Logs)); }); } else + { Logger.LogSignalDisabled(nameof(Signals.Logs)); + } if (distro.Signals.HasFlag(Signals.Traces)) { openTelemetry.WithTracing(tracing => { if (distro.ElasticDefaults.HasFlag(ElasticDefaults.Traces)) - tracing.UseElasticDefaults(Logger); + tracing.UseElasticDefaults(distro.SkipOtlpExporter, Logger); else Logger.LogDefaultsDisabled(nameof(ElasticDefaults.Traces)); }); } else + { Logger.LogSignalDisabled(nameof(Signals.Metrics)); + } if (distro.Signals.HasFlag(Signals.Metrics)) { openTelemetry.WithMetrics(metrics => { if (distro.ElasticDefaults.HasFlag(ElasticDefaults.Metrics)) - metrics.UseElasticDefaults(Logger); + metrics.UseElasticDefaults(distro.SkipOtlpExporter, Logger); else Logger.LogDefaultsDisabled(nameof(ElasticDefaults.Metrics)); }); } else + { Logger.LogSignalDisabled(nameof(Signals.Metrics)); + } } } @@ -169,10 +165,10 @@ internal static partial class LoggerMessages [LoggerMessage(EventId = 2, Level = LogLevel.Information, Message = "No Elastic defaults were enabled.")] public static partial void LogNoElasticDefaults(this ILogger logger); - [LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = "ElasticOpenTelemetryBuilder {Signal} skipped, configured to be disabled")] + [LoggerMessage(EventId = 3, Level = LogLevel.Information, Message = "ElasticOpenTelemetryBuilder {Signal} skipped, configured to be disabled")] public static partial void LogSignalDisabled(this ILogger logger, string signal); - [LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = "Elastic defaults for {Signal} skipped, configured to be disabled")] + [LoggerMessage(EventId = 4, Level = LogLevel.Information, Message = "Elastic defaults for {Signal} skipped, configured to be disabled")] public static partial void LogDefaultsDisabled(this ILogger logger, string signal); } diff --git a/src/Elastic.OpenTelemetry/Extensions/LoggingProviderBuilderExtensions.cs b/src/Elastic.OpenTelemetry/Extensions/LoggingProviderBuilderExtensions.cs new file mode 100644 index 0000000..6450b8c --- /dev/null +++ b/src/Elastic.OpenTelemetry/Extensions/LoggingProviderBuilderExtensions.cs @@ -0,0 +1,31 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information + +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using OpenTelemetry.Logs; +using OpenTelemetry.Trace; +using static Elastic.OpenTelemetry.Configuration.Signals; + +namespace Elastic.OpenTelemetry.Extensions; + +/// +/// Elastic extensions for . +/// +public static class LoggingProviderBuilderExtensions +{ + /// + /// Use Elastic Distribution of OpenTelemetry .NET defaults for . + /// + public static LoggerProviderBuilder UseElasticDefaults(this LoggerProviderBuilder builder, bool skipOtlp = false, ILogger? logger = null) + { + logger ??= NullLogger.Instance; + + if (!skipOtlp) + builder.AddOtlpExporter(); + + logger.LogConfiguredSignalProvider(nameof(Logs), nameof(LoggerProviderBuilder)); + return builder; + } +} diff --git a/src/Elastic.OpenTelemetry/Extensions/MeterProviderBuilderExtensions.cs b/src/Elastic.OpenTelemetry/Extensions/MeterProviderBuilderExtensions.cs index 092c847..6e52755 100644 --- a/src/Elastic.OpenTelemetry/Extensions/MeterProviderBuilderExtensions.cs +++ b/src/Elastic.OpenTelemetry/Extensions/MeterProviderBuilderExtensions.cs @@ -15,7 +15,7 @@ namespace Elastic.OpenTelemetry.Extensions; public static class MeterProviderBuilderExtensions { /// Use Elastic Distribution of OpenTelemetry .NET defaults for - public static MeterProviderBuilder UseElasticDefaults(this MeterProviderBuilder builder, ILogger? logger = null) + public static MeterProviderBuilder UseElasticDefaults(this MeterProviderBuilder builder, bool skipOtlp = false, ILogger? logger = null) { logger ??= NullLogger.Instance; @@ -24,6 +24,9 @@ public static MeterProviderBuilder UseElasticDefaults(this MeterProviderBuilder .AddRuntimeInstrumentation() .AddHttpClientInstrumentation(); + if (!skipOtlp) + builder.AddOtlpExporter(); + logger.LogConfiguredSignalProvider(nameof(Metrics), nameof(MeterProviderBuilder)); return builder; diff --git a/src/Elastic.OpenTelemetry/Extensions/TracerProviderBuilderExtensions.cs b/src/Elastic.OpenTelemetry/Extensions/TracerProviderBuilderExtensions.cs index 6807d57..5285c81 100644 --- a/src/Elastic.OpenTelemetry/Extensions/TracerProviderBuilderExtensions.cs +++ b/src/Elastic.OpenTelemetry/Extensions/TracerProviderBuilderExtensions.cs @@ -8,12 +8,15 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; using OpenTelemetry; +using OpenTelemetry.Logs; using OpenTelemetry.Trace; using static Elastic.OpenTelemetry.Configuration.Signals; namespace Elastic.OpenTelemetry.Extensions; -/// Elastic extensions for . +/// +/// Elastic extensions for . +/// public static class TracerProviderBuilderExtensions { /// @@ -34,17 +37,23 @@ private static TracerProviderBuilder LogAndAddProcessor(this TracerProviderBuild return builder.AddProcessor(processor); } - /// Use Elastic Distribution of OpenTelemetry .NET defaults for - public static TracerProviderBuilder UseElasticDefaults(this TracerProviderBuilder builder, ILogger? logger = null) + /// + /// Use Elastic Distribution of OpenTelemetry .NET defaults for . + /// + public static TracerProviderBuilder UseElasticDefaults(this TracerProviderBuilder builder, bool skipOtlp = false, ILogger? logger = null) { logger ??= NullLogger.Instance; builder .AddHttpClientInstrumentation() .AddGrpcClientInstrumentation() - .AddEntityFrameworkCoreInstrumentation(); + .AddEntityFrameworkCoreInstrumentation() + .AddSource("Elastic.Transport") + .AddElasticProcessors(logger); + + if (!skipOtlp) + builder.AddOtlpExporter(); - builder.AddElasticProcessors(logger); logger.LogConfiguredSignalProvider(nameof(Traces), nameof(TracerProviderBuilder)); return builder; } From 80f0d81c8a43553b2ef74fea1d122aed0b7e3028 Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Thu, 21 Nov 2024 15:12:12 +0000 Subject: [PATCH 2/6] Fix typo in docs --- docs/configure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configure.md b/docs/configure.md index a3eee26..383c6fd 100644 --- a/docs/configure.md +++ b/docs/configure.md @@ -172,7 +172,7 @@ Valid options: `Critical`, `Error`, `Warning`, `Information`, `Debug`, `Trace` a * _Type_: Bool * _Default_: `false` -Allows EDOT .NET to used with its defaults, but without enabling the export of telemetry data to +Allows EDOT .NET to be used with its defaults, but without enabling the export of telemetry data to an OTLP endpoint. This can be useful when you want to test applications without sending telemetry data. | Configuration method | Key | From 527bf02aead5890e5cd9442c8092c8a8738a8264 Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Thu, 21 Nov 2024 15:12:43 +0000 Subject: [PATCH 3/6] Support skipOtlp option in the autoinstrumentation plugin --- .../AutoInstrumentationPlugin.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Elastic.OpenTelemetry/AutoInstrumentationPlugin.cs b/src/Elastic.OpenTelemetry/AutoInstrumentationPlugin.cs index 266b31c..4b8a1f3 100644 --- a/src/Elastic.OpenTelemetry/AutoInstrumentationPlugin.cs +++ b/src/Elastic.OpenTelemetry/AutoInstrumentationPlugin.cs @@ -23,6 +23,8 @@ public class AutoInstrumentationPlugin private readonly ILogger _logger; private readonly EventListener _eventListener; + private readonly bool _skipOtlp; + /// public AutoInstrumentationPlugin() { @@ -31,6 +33,11 @@ public AutoInstrumentationPlugin() _logger = logger; _eventListener = eventListener; + + var skipOtlpString = Environment.GetEnvironmentVariable("ELASTIC_OTEL_SKIP_OTLP_EXPORTER"); + + if (skipOtlpString is not null && bool.TryParse(skipOtlpString, out var skipOtlp)) + _skipOtlp = skipOtlp; } /// To access TracerProvider right after TracerProviderBuilder.Build() is executed. @@ -45,8 +52,7 @@ public void MeterProviderInitialized(MeterProvider meterProvider) /// To configure tracing SDK before Auto Instrumentation configured SDK public TracerProviderBuilder BeforeConfigureTracerProvider(TracerProviderBuilder builder) => - builder.UseElasticDefaults(_logger); - + builder.UseElasticDefaults(_skipOtlp, _logger); /// To configure tracing SDK after Auto Instrumentation configured SDK public TracerProviderBuilder AfterConfigureTracerProvider(TracerProviderBuilder builder) => @@ -54,13 +60,12 @@ public TracerProviderBuilder AfterConfigureTracerProvider(TracerProviderBuilder /// To configure metrics SDK before Auto Instrumentation configured SDK public MeterProviderBuilder BeforeConfigureMeterProvider(MeterProviderBuilder builder) => - builder.UseElasticDefaults(_logger); + builder.UseElasticDefaults(_skipOtlp, _logger); /// To configure metrics SDK after Auto Instrumentation configured SDK public MeterProviderBuilder AfterConfigureMeterProvider(MeterProviderBuilder builder) => builder; - /// To configure logs SDK (the method name is the same as for other logs options) public void ConfigureLogsOptions(OpenTelemetryLoggerOptions options) => options.UseElasticDefaults(_logger); From 6bc0064e8c664059dbc4cc2a290edc9b4b21f315 Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Thu, 21 Nov 2024 15:28:17 +0000 Subject: [PATCH 4/6] Pin 8.x SDK until we're ready to switch to 9.x --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 72d38cd..60b4c02 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,7 @@ { "sdk": { "version": "8.0.100", - "rollForward": "latestMajor", + "rollForward": "latestMinor", "allowPrerelease": false } } \ No newline at end of file From 5367798857bf30f68cca8fbb24ec4012c051c6ad Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Thu, 21 Nov 2024 16:23:20 +0000 Subject: [PATCH 5/6] Switch to latest Feature --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 60b4c02..789bff3 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,7 @@ { "sdk": { "version": "8.0.100", - "rollForward": "latestMinor", + "rollForward": "latestFeature", "allowPrerelease": false } } \ No newline at end of file From 802d9c2566352ef4e795491c9ec6d70e83ad41b7 Mon Sep 17 00:00:00 2001 From: Steve Gordon Date: Thu, 21 Nov 2024 16:33:36 +0000 Subject: [PATCH 6/6] Update global.json --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 789bff3..42f2b94 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.100", + "version": "8.0.404", "rollForward": "latestFeature", "allowPrerelease": false }