diff --git a/src/OpenTelemetry.Exporter.Jaeger/Implementation/Process.cs b/src/OpenTelemetry.Exporter.Jaeger/Implementation/Process.cs index 1d76584748e..0f0da694d08 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/Implementation/Process.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/Implementation/Process.cs @@ -23,14 +23,9 @@ namespace OpenTelemetry.Exporter.Jaeger.Implementation { internal sealed class Process { - public Process(string serviceName) - { - this.ServiceName = serviceName; - } - - public string ServiceName { get; internal set; } + public string ServiceName { get; set; } - internal Dictionary Tags { get; set; } + public Dictionary Tags { get; set; } public override string ToString() { @@ -48,7 +43,7 @@ public override string ToString() return sb.ToString(); } - internal void Write(TProtocol oprot) + public void Write(TProtocol oprot) { oprot.IncrementRecursionDepth(); diff --git a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporter.cs b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporter.cs index 4a26ce813d4..462d67ffb4f 100644 --- a/src/OpenTelemetry.Exporter.Jaeger/JaegerExporter.cs +++ b/src/OpenTelemetry.Exporter.Jaeger/JaegerExporter.cs @@ -78,14 +78,12 @@ internal JaegerExporter(JaegerExporterOptions options, TProtocolFactory protocol this.batchWriter = protocolFactory.GetProtocol(this.maxPayloadSizeInBytes * 2); this.spanWriter = protocolFactory.GetProtocol(this.maxPayloadSizeInBytes); - string serviceName = (string)this.ParentProvider.GetDefaultResource().Attributes.FirstOrDefault( - pair => pair.Key == ResourceSemanticConventions.AttributeServiceName).Value; - this.Process = new Process(serviceName); + this.Process = new(); client.Connect(); } - internal Process Process { get; set; } + internal Process Process { get; } internal EmitBatchArgs EmitBatchArgs { get; private set; } @@ -156,19 +154,21 @@ internal void SetResourceAndInitializeBatch(Resource resource) } } - if (serviceName != null) + if (!string.IsNullOrWhiteSpace(serviceName)) { serviceName = string.IsNullOrEmpty(serviceNamespace) ? serviceName : serviceNamespace + "." + serviceName; } - - if (!string.IsNullOrEmpty(serviceName)) + else { - process.ServiceName = serviceName; + serviceName = (string)this.ParentProvider.GetDefaultResource().Attributes.FirstOrDefault( + pair => pair.Key == ResourceSemanticConventions.AttributeServiceName).Value; } - this.Batch = new Batch(this.Process, this.batchWriter); + process.ServiceName = serviceName; + + this.Batch = new Batch(process, this.batchWriter); if (this.sendUsingEmitBatchArgs) { this.EmitBatchArgs = new EmitBatchArgs(this.batchWriter); diff --git a/src/OpenTelemetry/CHANGELOG.md b/src/OpenTelemetry/CHANGELOG.md index a98ce37a322..6944fae04c8 100644 --- a/src/OpenTelemetry/CHANGELOG.md +++ b/src/OpenTelemetry/CHANGELOG.md @@ -11,7 +11,8 @@ * Added dependency injection support in the `ResourceBuilder` class and added support for loading environment variables from `IConfiguration` for the `AddEnvironmentVariableDetector` extension - ([#3782](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3782)) + ([#3782](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3782), + [#3798](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3798)) ## 1.4.0-beta.2 diff --git a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs index de38cf4d8a0..949cc25cb80 100644 --- a/src/OpenTelemetry/Metrics/MeterProviderSdk.cs +++ b/src/OpenTelemetry/Metrics/MeterProviderSdk.cs @@ -29,6 +29,7 @@ namespace OpenTelemetry.Metrics { internal sealed class MeterProviderSdk : MeterProvider { + internal readonly IServiceProvider ServiceProvider; internal readonly IDisposable? OwnedServiceProvider; internal int ShutdownCount; internal bool Disposed; @@ -44,6 +45,10 @@ internal MeterProviderSdk( IServiceProvider serviceProvider, bool ownsServiceProvider) { + Debug.Assert(serviceProvider != null, "serviceProvider was null"); + + this.ServiceProvider = serviceProvider!; + if (ownsServiceProvider) { this.OwnedServiceProvider = serviceProvider as IDisposable; @@ -52,10 +57,10 @@ internal MeterProviderSdk( OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent("Building MeterProvider."); - var state = new MeterProviderBuilderState(serviceProvider); + var state = new MeterProviderBuilderState(serviceProvider!); MeterProviderBuilderServiceCollectionHelper.InvokeRegisteredConfigureStateCallbacks( - serviceProvider, + serviceProvider!, state); StringBuilder exportersAdded = new StringBuilder(); diff --git a/src/OpenTelemetry/ProviderExtensions.cs b/src/OpenTelemetry/ProviderExtensions.cs index 1ae3a85ecfc..c110fa9020b 100644 --- a/src/OpenTelemetry/ProviderExtensions.cs +++ b/src/OpenTelemetry/ProviderExtensions.cs @@ -57,7 +57,23 @@ public static Resource GetResource(this BaseProvider baseProvider) /// if found otherwise . public static Resource GetDefaultResource(this BaseProvider baseProvider) { - return ResourceBuilder.CreateDefault().Build(); + var builder = ResourceBuilder.CreateDefault(); + builder.ServiceProvider = GetServiceProvider(baseProvider); + return builder.Build(); + } + + internal static IServiceProvider GetServiceProvider(this BaseProvider baseProvider) + { + if (baseProvider is TracerProviderSdk tracerProviderSdk) + { + return tracerProviderSdk.ServiceProvider; + } + else if (baseProvider is MeterProviderSdk meterProviderSdk) + { + return meterProviderSdk.ServiceProvider; + } + + return null; } internal static Action GetObservableInstrumentCollectCallback(this BaseProvider baseProvider) diff --git a/src/OpenTelemetry/Trace/TracerProviderSdk.cs b/src/OpenTelemetry/Trace/TracerProviderSdk.cs index 20485c43a62..73439b5b6c0 100644 --- a/src/OpenTelemetry/Trace/TracerProviderSdk.cs +++ b/src/OpenTelemetry/Trace/TracerProviderSdk.cs @@ -29,6 +29,7 @@ namespace OpenTelemetry.Trace { internal sealed class TracerProviderSdk : TracerProvider { + internal readonly IServiceProvider ServiceProvider; internal readonly IDisposable? OwnedServiceProvider; internal int ShutdownCount; internal bool Disposed; @@ -44,6 +45,10 @@ internal TracerProviderSdk( IServiceProvider serviceProvider, bool ownsServiceProvider) { + Debug.Assert(serviceProvider != null, "serviceProvider was null"); + + this.ServiceProvider = serviceProvider!; + if (ownsServiceProvider) { this.OwnedServiceProvider = serviceProvider as IDisposable; @@ -52,10 +57,10 @@ internal TracerProviderSdk( OpenTelemetrySdkEventSource.Log.TracerProviderSdkEvent("Building TracerProvider."); - var state = new TracerProviderBuilderState(serviceProvider); + var state = new TracerProviderBuilderState(serviceProvider!); TracerProviderBuilderServiceCollectionHelper.InvokeRegisteredConfigureStateCallbacks( - serviceProvider, + serviceProvider!, state); StringBuilder processorsAdded = new StringBuilder(); diff --git a/test/Benchmarks/Exporter/JaegerExporterBenchmarks.cs b/test/Benchmarks/Exporter/JaegerExporterBenchmarks.cs index c13dc8654bc..b4a9d6d7855 100644 --- a/test/Benchmarks/Exporter/JaegerExporterBenchmarks.cs +++ b/test/Benchmarks/Exporter/JaegerExporterBenchmarks.cs @@ -51,10 +51,7 @@ public void JaegerExporter_Batching() using JaegerExporter exporter = new JaegerExporter( new JaegerExporterOptions(), new TCompactProtocol.Factory(), - new NoopJaegerClient()) - { - Process = new Jaeger::OpenTelemetry.Exporter.Jaeger.Implementation.Process("TestService"), - }; + new NoopJaegerClient()); for (int i = 0; i < this.NumberOfBatches; i++) { diff --git a/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterTests.cs b/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterTests.cs index 28baef09e66..2998ce78fc0 100644 --- a/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterTests.cs @@ -20,6 +20,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Exporter.Jaeger.Implementation; using OpenTelemetry.Exporter.Jaeger.Implementation.Tests; @@ -185,11 +186,9 @@ public void JaegerTraceExporter_SetResource_UpdatesServiceName() using var jaegerTraceExporter = new JaegerExporter(new JaegerExporterOptions()); var process = jaegerTraceExporter.Process; - process.ServiceName = "TestService"; - jaegerTraceExporter.SetResourceAndInitializeBatch(Resource.Empty); - Assert.Equal("TestService", process.ServiceName); + Assert.StartsWith("unknown_service:", process.ServiceName); jaegerTraceExporter.SetResourceAndInitializeBatch(ResourceBuilder.CreateEmpty().AddService("MyService").Build()); @@ -251,6 +250,34 @@ public void JaegerTraceExporter_SetResource_IgnoreServiceResources() Assert.Null(process.Tags); } + [Fact] + public void JaegerTraceExporter_SetResource_UpdatesServiceNameFromIConfiguration() + { + var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + Dictionary configuration = new() + { + ["OTEL_SERVICE_NAME"] = "myservicename", + }; + + services.AddSingleton( + new ConfigurationBuilder().AddInMemoryCollection(configuration).Build()); + }); + + var jaegerTraceExporter = new JaegerExporter(new JaegerExporterOptions()); + + tracerProviderBuilder.AddExporter(ExportProcessorType.Batch, jaegerTraceExporter); + + using var provider = tracerProviderBuilder.Build(); + + var process = jaegerTraceExporter.Process; + + jaegerTraceExporter.SetResourceAndInitializeBatch(Resource.Empty); + + Assert.Equal("myservicename", process.ServiceName); + } + [Fact] public void JaegerTraceExporter_BuildBatchesToTransmit_FlushedBatch() { diff --git a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs index 3c19c2c106c..2eb3ca9e213 100644 --- a/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs +++ b/test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs @@ -292,6 +292,42 @@ public void ServiceProviderHttpClientFactoryInvoked() Assert.Equal(1, invocations); } + [Fact] + public void UpdatesServiceNameFromDefaultResource() + { + var zipkinExporter = new ZipkinExporter(new ZipkinExporterOptions()); + + zipkinExporter.SetLocalEndpointFromResource(Resource.Empty); + + Assert.StartsWith("unknown_service:", zipkinExporter.LocalEndpoint.ServiceName); + } + + [Fact] + public void UpdatesServiceNameFromIConfiguration() + { + var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder() + .ConfigureServices(services => + { + Dictionary configuration = new() + { + ["OTEL_SERVICE_NAME"] = "myservicename", + }; + + services.AddSingleton( + new ConfigurationBuilder().AddInMemoryCollection(configuration).Build()); + }); + + var zipkinExporter = new ZipkinExporter(new ZipkinExporterOptions()); + + tracerProviderBuilder.AddExporter(ExportProcessorType.Batch, zipkinExporter); + + using var provider = tracerProviderBuilder.Build(); + + zipkinExporter.SetLocalEndpointFromResource(Resource.Empty); + + Assert.Equal("myservicename", zipkinExporter.LocalEndpoint.ServiceName); + } + [Theory] [InlineData(true, false, false)] [InlineData(false, false, false)]