I am trying to use OpenTelemetry with my net472 app that uses Microsoft.Extensions.Hosting.
I create my host like this:
Host.CreateDefaultBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddOpenTelemetry().WithTracing(tracerProviderBuilder =>
{
tracerProviderBuilder
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MySample"))
.AddConsoleExporter()
.AddSource(serviceName);
}).StartWithHost();
})
.Build();
If I then try to create a new activity like this, it is null:
var activitySource = new ActivitySource(serviceName);
using var activity = activitySource.StartActivity("Hello");
If instead I register OpenTelemetry like this, it works just fine:
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MySample"))
.AddSource(serviceName)
.AddConsoleExporter()
.Build();
How can I get an ActivitySource that has the configured listener using the first approach of creating a Host?
The solution that worked for me is to resolve the TracerProvider using the ServiceCollection. That way the listener gets subscribed and ActivitySource is able to start activities.
This is how I register the services.
Host.CreateDefaultBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddSingleton(new ActivitySource(serviceName));
services.AddOpenTelemetry().WithTracing(tracerProviderBuilder =>
{
tracerProviderBuilder
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MySample"))
.AddConsoleExporter()
.AddSource(serviceName);
});
})
.Build();
And then when TracerProvider
is resolved, it's build using the configured TracerProvider
:
using var tracerProvider = ServiceLocator.GetService<TracerProvider>();
var activitySource = ServiceLocator.GetService<ActivitySource>();
// Now this doesn't provide a null object
using var activity = activitySource.StartActivity("Hello");
Just for reference, this is ServiceLocator:
public static class ServiceLocator
{
internal static IHost Host { get; set; }
public static T GetService<T>() where T : class
{
return (T)Host.Services.GetService(typeof(T));
}
}