diff --git a/src/Elastic.OpenTelemetry.AutoInstrumentation/AutoInstrumentationPlugin.cs b/src/Elastic.OpenTelemetry.AutoInstrumentation/AutoInstrumentationPlugin.cs index 7583989e..d1cca41d 100644 --- a/src/Elastic.OpenTelemetry.AutoInstrumentation/AutoInstrumentationPlugin.cs +++ b/src/Elastic.OpenTelemetry.AutoInstrumentation/AutoInstrumentationPlugin.cs @@ -5,9 +5,12 @@ using Elastic.OpenTelemetry.Configuration; using Elastic.OpenTelemetry.Core; using Elastic.OpenTelemetry.Diagnostics; +using Elastic.OpenTelemetry.Exporters; using Elastic.OpenTelemetry.Resources; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using OpenTelemetry; +using OpenTelemetry.Exporter; using OpenTelemetry.Logs; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; @@ -39,6 +42,8 @@ public TracerProviderBuilder BeforeConfigureTracerProvider(TracerProviderBuilder { builder.ConfigureResource(r => r.WithElasticDefaultsCore(_components, null, null)); + builder.ConfigureServices(sc => sc.Configure(OtlpExporterDefaults.OtlpExporterOptions)); + CoreTracerProvderBuilderExtensions.AddActivitySourceWithLogging(builder, logger, "Elastic.Transport", ""); CoreTracerProvderBuilderExtensions.AddElasticProcessorsCore(builder, null, _components, null); @@ -66,6 +71,8 @@ public MeterProviderBuilder BeforeConfigureMeterProvider(MeterProviderBuilder bu { builder.ConfigureResource(r => r.WithElasticDefaultsCore(_components, null, null)); + builder.ConfigureServices(sc => sc.Configure(OtlpExporterDefaults.OtlpExporterOptions)); + logger.LogConfiguredSignalProvider(nameof(Signals.Metrics), nameof(MeterProviderBuilder), ""); return builder; diff --git a/src/Elastic.OpenTelemetry.AutoInstrumentation/Elastic.OpenTelemetry.AutoInstrumentation.csproj b/src/Elastic.OpenTelemetry.AutoInstrumentation/Elastic.OpenTelemetry.AutoInstrumentation.csproj index e379d6cd..f26993ce 100644 --- a/src/Elastic.OpenTelemetry.AutoInstrumentation/Elastic.OpenTelemetry.AutoInstrumentation.csproj +++ b/src/Elastic.OpenTelemetry.AutoInstrumentation/Elastic.OpenTelemetry.AutoInstrumentation.csproj @@ -24,6 +24,7 @@ + diff --git a/src/Elastic.OpenTelemetry.Core/Exporters/ElasticUserAgentHandler.cs b/src/Elastic.OpenTelemetry.Core/Exporters/ElasticUserAgentHandler.cs new file mode 100644 index 00000000..e27e4290 --- /dev/null +++ b/src/Elastic.OpenTelemetry.Core/Exporters/ElasticUserAgentHandler.cs @@ -0,0 +1,22 @@ +// 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 + +#if NETFRAMEWORK +using System.Net.Http; +#endif + +namespace Elastic.OpenTelemetry.Exporters; + +internal class ElasticUserAgentHandler(string userAgent) : HttpClientHandler +{ + private readonly string _userAgent = userAgent; + + protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + request.Headers.Remove("User-Agent"); + request.Headers.Add("User-Agent", _userAgent); + + return base.SendAsync(request, cancellationToken); + } +} diff --git a/src/Elastic.OpenTelemetry.Core/Exporters/OtlpExporterDefaults.cs b/src/Elastic.OpenTelemetry.Core/Exporters/OtlpExporterDefaults.cs new file mode 100644 index 00000000..6ca555de --- /dev/null +++ b/src/Elastic.OpenTelemetry.Core/Exporters/OtlpExporterDefaults.cs @@ -0,0 +1,24 @@ +// 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 Elastic.OpenTelemetry.Core; +using OpenTelemetry.Exporter; + +#if NETFRAMEWORK +using System.Net.Http; +#endif + +namespace Elastic.OpenTelemetry.Exporters; + +internal static class OtlpExporterDefaults +{ + internal static readonly HttpMessageHandler Handler = new ElasticUserAgentHandler($"elastic-otlp-dotnet/{VersionHelper.InformationalVersion}"); + + public static void OtlpExporterOptions(OtlpExporterOptions options) => + options.HttpClientFactory = () => + { + var client = new HttpClient(Handler); + return client; + }; +} diff --git a/src/Elastic.OpenTelemetry.Core/Extensions/ResourceBuilderExtensions.cs b/src/Elastic.OpenTelemetry.Core/Extensions/ResourceBuilderExtensions.cs index 6cd2b076..19b2eb39 100644 --- a/src/Elastic.OpenTelemetry.Core/Extensions/ResourceBuilderExtensions.cs +++ b/src/Elastic.OpenTelemetry.Core/Extensions/ResourceBuilderExtensions.cs @@ -21,7 +21,7 @@ internal static class ResourceBuilderExtensions /// /// Used to track the number of times any variation of `WithElasticDefaults` is invoked by consuming - /// code acrosss all instances. This allows us to warn about potenital + /// code across all instances. This allows us to warn about potential /// misconfigurations. /// private static int WithElasticDefaultsCallCount; diff --git a/src/Elastic.OpenTelemetry/Elastic.OpenTelemetry.csproj b/src/Elastic.OpenTelemetry/Elastic.OpenTelemetry.csproj index fcc2f457..3bfda666 100644 --- a/src/Elastic.OpenTelemetry/Elastic.OpenTelemetry.csproj +++ b/src/Elastic.OpenTelemetry/Elastic.OpenTelemetry.csproj @@ -1,4 +1,4 @@ - + Library @@ -47,6 +47,10 @@ + + + + diff --git a/src/Elastic.OpenTelemetry/Extensions/LoggingProviderBuilderExtensions.cs b/src/Elastic.OpenTelemetry/Extensions/LoggingProviderBuilderExtensions.cs index 343dc57a..bbd62fb2 100644 --- a/src/Elastic.OpenTelemetry/Extensions/LoggingProviderBuilderExtensions.cs +++ b/src/Elastic.OpenTelemetry/Extensions/LoggingProviderBuilderExtensions.cs @@ -7,13 +7,16 @@ using Elastic.OpenTelemetry.Configuration; using Elastic.OpenTelemetry.Core; using Elastic.OpenTelemetry.Diagnostics; +using Elastic.OpenTelemetry.Exporters; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using OpenTelemetry.Exporter; +using OpenTelemetry.Logs; using OpenTelemetry.Resources; // Matching namespace with LoggerProviderBuilder #pragma warning disable IDE0130 // Namespace does not match folder structure -namespace OpenTelemetry.Logs; +namespace OpenTelemetry; #pragma warning restore IDE0130 // Namespace does not match folder structure /// @@ -24,7 +27,7 @@ public static class LoggingProviderBuilderExtensions { /// /// Used to track the number of times any variation of `WithElasticDefaults` is invoked by consuming - /// code acrosss all instances. This allows us to warn about potenital + /// code across all instances. This allows us to warn about potential /// misconfigurations. /// private static int WithElasticDefaultsCallCount; @@ -149,6 +152,9 @@ static void ConfigureBuilder(LoggerProviderBuilder builder, BuilderState builder builder.ConfigureResource(r => r.WithElasticDefaults(builderState, services)); + if (services is null) + builder.ConfigureServices(sc => sc.Configure(OtlpExporterDefaults.OtlpExporterOptions)); + if (components.Options.SkipOtlpExporter) { logger.LogSkippingOtlpExporter(nameof(Signals.Logs), loggingProviderName, builderState.InstanceIdentifier); diff --git a/src/Elastic.OpenTelemetry/Extensions/MeterProviderBuilderExtensions.cs b/src/Elastic.OpenTelemetry/Extensions/MeterProviderBuilderExtensions.cs index 797ec2ec..dbd0170f 100644 --- a/src/Elastic.OpenTelemetry/Extensions/MeterProviderBuilderExtensions.cs +++ b/src/Elastic.OpenTelemetry/Extensions/MeterProviderBuilderExtensions.cs @@ -8,17 +8,19 @@ using Elastic.OpenTelemetry.Configuration; using Elastic.OpenTelemetry.Core; using Elastic.OpenTelemetry.Diagnostics; +using Elastic.OpenTelemetry.Exporters; using Elastic.OpenTelemetry.Instrumentation; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using OpenTelemetry.Exporter; using OpenTelemetry.Logs; +using OpenTelemetry.Metrics; using OpenTelemetry.Resources; -using OpenTelemetry.Trace; // Matching namespace with MeterProviderBuilder #pragma warning disable IDE0130 // Namespace does not match folder structure -namespace OpenTelemetry.Metrics; +namespace OpenTelemetry; #pragma warning restore IDE0130 // Namespace does not match folder structure /// @@ -29,7 +31,7 @@ public static class MeterProviderBuilderExtensions { /// /// Used to track the number of times any variation of `WithElasticDefaults` is invoked by consuming - /// code acrosss all instances. This allows us to warn about potenital + /// code across all instances. This allows us to warn about potential /// misconfigurations. /// private static int WithElasticDefaultsCallCount; @@ -177,6 +179,9 @@ static void ConfigureBuilder(MeterProviderBuilder builder, BuilderState builderS builder.ConfigureResource(r => r.WithElasticDefaults(builderState, services)); + if (services is null) + builder.ConfigureServices(sc => sc.Configure(OtlpExporterDefaults.OtlpExporterOptions)); + #if NET9_0_OR_GREATER // On .NET 9, the contrib HTTP instrumentation is no longer required. If the dependency exists, // it will be registered via the reflection-based assembly scanning. diff --git a/src/Elastic.OpenTelemetry/Extensions/OpenTelemetryBuilderExtensions.cs b/src/Elastic.OpenTelemetry/Extensions/OpenTelemetryBuilderExtensions.cs index 34675f8e..af924a33 100644 --- a/src/Elastic.OpenTelemetry/Extensions/OpenTelemetryBuilderExtensions.cs +++ b/src/Elastic.OpenTelemetry/Extensions/OpenTelemetryBuilderExtensions.cs @@ -6,10 +6,12 @@ using Elastic.OpenTelemetry.Configuration; using Elastic.OpenTelemetry.Core; using Elastic.OpenTelemetry.Diagnostics; +using Elastic.OpenTelemetry.Exporters; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.Metrics; using Microsoft.Extensions.Logging; +using OpenTelemetry.Exporter; using OpenTelemetry.Logs; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; @@ -28,7 +30,7 @@ public static class OpenTelemetryBuilderExtensions { /// /// Used to track the number of times any variation of `WithElasticDefaults` is invoked by consuming - /// code acrosss all instances. This allows us to warn about potenital + /// code across all instances. This allows us to warn about potential /// misconfigurations. /// private static int WithElasticDefaultsCallCount; @@ -138,6 +140,8 @@ private static void ConfigureBuilder(IOpenTelemetryBuilder builder, BuilderState var components = builderState.Components; var options = builderState.Components.Options; + services?.Configure(OtlpExporterDefaults.OtlpExporterOptions); + if (options.Signals.HasFlagFast(Signals.Traces)) { builder.WithTracing(b => b.WithElasticDefaults(components, builder.Services)); diff --git a/src/Elastic.OpenTelemetry/Extensions/TracerProviderBuilderExtensions.cs b/src/Elastic.OpenTelemetry/Extensions/TracerProviderBuilderExtensions.cs index 1cdfa6c2..e0ae319b 100644 --- a/src/Elastic.OpenTelemetry/Extensions/TracerProviderBuilderExtensions.cs +++ b/src/Elastic.OpenTelemetry/Extensions/TracerProviderBuilderExtensions.cs @@ -8,18 +8,18 @@ using Elastic.OpenTelemetry.Configuration; using Elastic.OpenTelemetry.Core; using Elastic.OpenTelemetry.Diagnostics; +using Elastic.OpenTelemetry.Exporters; using Elastic.OpenTelemetry.Instrumentation; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using OpenTelemetry.Logs; -using OpenTelemetry.Metrics; +using OpenTelemetry.Exporter; using OpenTelemetry.Resources; using OpenTelemetry.Trace; // Matching namespace with TracerProviderBuilder #pragma warning disable IDE0130 // Namespace does not match folder structure -namespace OpenTelemetry.Trace; +namespace OpenTelemetry; #pragma warning restore IDE0130 // Namespace does not match folder structure /// @@ -167,6 +167,9 @@ private static void ConfigureBuilder(TracerProviderBuilder builder, BuilderState builder.ConfigureResource(r => r.WithElasticDefaults(builderState, services)); + if (services is null) + builder.ConfigureServices(sc => sc.Configure(OtlpExporterDefaults.OtlpExporterOptions)); + #if NET9_0_OR_GREATER if (SignalBuilder.InstrumentationAssemblyExists("OpenTelemetry.Instrumentation.Http.dll")) {