Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions src/OpenTelemetry.Exporter.Jaeger/Implementation/Process.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, JaegerTag> Tags { get; set; }
public Dictionary<string, JaegerTag> Tags { get; set; }

public override string ToString()
{
Expand All @@ -48,7 +43,7 @@ public override string ToString()
return sb.ToString();
}

internal void Write(TProtocol oprot)
public void Write(TProtocol oprot)
{
oprot.IncrementRecursionDepth();

Expand Down
18 changes: 9 additions & 9 deletions src/OpenTelemetry.Exporter.Jaeger/JaegerExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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; }

Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/OpenTelemetry/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
9 changes: 7 additions & 2 deletions src/OpenTelemetry/Metrics/MeterProviderSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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();
Expand Down
18 changes: 17 additions & 1 deletion src/OpenTelemetry/ProviderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,23 @@ public static Resource GetResource(this BaseProvider baseProvider)
/// <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)
Expand Down
9 changes: 7 additions & 2 deletions src/OpenTelemetry/Trace/TracerProviderSdk.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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();
Expand Down
5 changes: 1 addition & 4 deletions test/Benchmarks/Exporter/JaegerExporterBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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++)
{
Expand Down
33 changes: 30 additions & 3 deletions test/OpenTelemetry.Exporter.Jaeger.Tests/JaegerExporterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -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<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()
{
Expand Down
36 changes: 36 additions & 0 deletions test/OpenTelemetry.Exporter.Zipkin.Tests/ZipkinExporterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<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)]
Expand Down