[SDK] Support dependency injection in the GetDefaultResource API (#3798)

* Support dependency injection in the GetDefaultResource API.

* CHANGELOG patch.

* Test tweaks.

Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
This commit is contained in:
Mikel Blanchard 2022-10-21 12:33:38 -07:00 committed by GitHub
parent d21e609f00
commit 32650555d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 112 additions and 30 deletions

View File

@ -23,14 +23,9 @@ namespace OpenTelemetry.Exporter.Jaeger.Implementation
{
internal sealed class Process
{
public Process(string serviceName)
{
this.ServiceName = serviceName;
}
public string ServiceName { get; set; }
public string ServiceName { get; internal set; }
internal Dictionary<string, JaegerTag> Tags { get; set; }
public Dictionary<string, JaegerTag> Tags { get; set; }
public override string ToString()
{
@ -48,7 +43,7 @@ namespace OpenTelemetry.Exporter.Jaeger.Implementation
return sb.ToString();
}
internal void Write(TProtocol oprot)
public void Write(TProtocol oprot)
{
oprot.IncrementRecursionDepth();

View File

@ -78,14 +78,12 @@ namespace OpenTelemetry.Exporter
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 @@ namespace OpenTelemetry.Exporter
}
}
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);

View File

@ -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

View File

@ -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 @@ namespace OpenTelemetry.Metrics
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 @@ namespace OpenTelemetry.Metrics
OpenTelemetrySdkEventSource.Log.MeterProviderSdkEvent("Building MeterProvider.");
var state = new MeterProviderBuilderState(serviceProvider);
var state = new MeterProviderBuilderState(serviceProvider!);
MeterProviderBuilderServiceCollectionHelper.InvokeRegisteredConfigureStateCallbacks(
serviceProvider,
serviceProvider!,
state);
StringBuilder exportersAdded = new StringBuilder();

View File

@ -57,7 +57,23 @@ namespace OpenTelemetry
/// <returns><see cref="Resource"/>if found otherwise <see cref="Resource.Empty"/>.</returns>
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)

View File

@ -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 @@ namespace OpenTelemetry.Trace
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 @@ namespace OpenTelemetry.Trace
OpenTelemetrySdkEventSource.Log.TracerProviderSdkEvent("Building TracerProvider.");
var state = new TracerProviderBuilderState(serviceProvider);
var state = new TracerProviderBuilderState(serviceProvider!);
TracerProviderBuilderServiceCollectionHelper.InvokeRegisteredConfigureStateCallbacks(
serviceProvider,
serviceProvider!,
state);
StringBuilder processorsAdded = new StringBuilder();

View File

@ -51,10 +51,7 @@ namespace Benchmarks.Exporter
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++)
{

View File

@ -20,6 +20,7 @@ using System.Collections.Generic;
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 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests
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 @@ namespace OpenTelemetry.Exporter.Jaeger.Tests
Assert.Null(process.Tags);
}
[Fact]
public void JaegerTraceExporter_SetResource_UpdatesServiceNameFromIConfiguration()
{
var tracerProviderBuilder = Sdk.CreateTracerProviderBuilder()
.ConfigureServices(services =>
{
Dictionary<string, string> configuration = new()
{
["OTEL_SERVICE_NAME"] = "myservicename",
};
services.AddSingleton<IConfiguration>(
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()
{

View File

@ -292,6 +292,42 @@ namespace OpenTelemetry.Exporter.Zipkin.Tests
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<string, string> configuration = new()
{
["OTEL_SERVICE_NAME"] = "myservicename",
};
services.AddSingleton<IConfiguration>(
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)]