Skip to content

Commit

Permalink
[SDK] Support dependency injection in the GetDefaultResource API (#3798)
Browse files Browse the repository at this point in the history
* Support dependency injection in the GetDefaultResource API.

* CHANGELOG patch.

* Test tweaks.

Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
  • Loading branch information
CodeBlanch and cijothomas authored Oct 21, 2022
1 parent d21e609 commit 3265055
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 30 deletions.
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

0 comments on commit 3265055

Please sign in to comment.