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

Access to IServiceProvider from enrich callbacks in AspNetCoreInstrumentationOptions and HttpClientInstrumentationOptions #3955

Closed
evgenyfedorov2 opened this issue Nov 30, 2022 · 2 comments
Labels
enhancement New feature or request

Comments

@evgenyfedorov2
Copy link

Is your feature request related to a problem?

Trace enrichment can be achieved by calling EnrichWithHttpRequestMessage/EnrichWithHttpRequest , EnrichWithHttpResponseMessage/EnrichWithHttpResponse , EnrichWithException/EnrichWithException callbacks. These callbacks, however, do not provide access to IServiceProvider, so I can't take some service(-s) from the Dependency Injection container and pass the Activity object to them.

Describe the solution you'd like:

The callbacks mentioned above should have an additional argument - IServiceProvider, so that it would be possible to get services from the Dependency Injection container and use them to enrich traces.

Describe alternatives you've considered.

Another way to do enrichment is by using a custom processor. But this does not help when I need to enrich traces at the OnStart event, because the instrumentation is run AFTER the OnStart event, so the processor can deal with non-instrumented activities only.

@evgenyfedorov2 evgenyfedorov2 added the enhancement New feature or request label Nov 30, 2022
@CodeBlanch
Copy link
Member

@evgenyfedorov2 Are you using OpenTelemetry.Extensions.Hosting? If yes, you should be able to use the Options API to accomplish this. Try something like this...

// Build a class for each options type you want to modify and implement IConfigureOptions<T>
internal sealed class ConfigureAspNetCoreInstrumentationOptions : IConfigureOptions<AspNetCoreInstrumentationOptions>
{
    private readonly IServiceProvider serviceProvider;

    public ConfigureAspNetCoreInstrumentationOptions(IServiceProvider serviceProvider)
    {
        // In this example I injected IServiceProvider but you could also just
        // inject MyService directly and avoid having to interact with the
        // provider.
        this.serviceProvider = serviceProvider;
    }

    public void Configure(AspNetCoreInstrumentationOptions options)
    {
        var myService = this.serviceProvider.GetRequiredService<MyService>();

        // Attach the options delegates/callbacks here using whatever services you need!
        options.EnrichWithHttpRequest = (activity, request)
            => myService.EnrichWithHttpRequest(activity, request);
    }
}

// Startup code

// Register the IConfigureOptions<T> as singletons. They will be executed when
// options are requested. The key is the class implementing the interface (eg
// ConfigureAspNetCoreInstrumentationOptions) will be requested via the
// IServiceProvider so any ctor parameter services will be injected into it!
appBuilder.Services.AddSingleton<
    IConfigureOptions<AspNetCoreInstrumentationOptions>,
    ConfigureAspNetCoreInstrumentationOptions>();

// Nothing special here just make sure you turn on instrumentation.
appBuilder.Services.AddOpenTelemetryTracing(builder => builder
    .AddAspNetCoreInstrumentation());

@evgenyfedorov2
Copy link
Author

Oh, great, thank you! That works for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants