Filling User Id Field in Application Insights from ASP.NET Core
Asked Answered
H

1

3

I would like to be able to populate the User Id field in Application Insights with my real username data. This is an internal application, so privacy concerns with a simple username field are moot.

As far as I can tell, all solutions available online for this strictly work in .NET Framework, not .NET Core.

You can find this solution in a few places, including some old AI documentation on GitHub. However, when I run it, I get an error on startup indicating that dependency on the scoped object IHttpContextAccessor is not acceptable from a singleton, which of course is logical. I don't see how this could have ever worked unless a previous version of .NET Core's DI allowed it (I'm on 2.2).

This issue on GitHub sort of spells out the problem but it was closed after the AI team pointed out that you must use a singleton. I tried variations of what's in the OP and the first response, and while the code ran, the User Id field on AI continued to be filled with gibberish data.

Is there any way to make the User Id field in AI fill with something useful for server requests coming from an ASP.NET Core app?

EDIT

After seeing the answer below that my code should have worked just fine, I went back and realized the exception message hadn't specifically mentioned IHttpContextAccessor:

System.InvalidOperationException: 'Cannot consume scoped service 'Microsoft.ApplicationInsights.Extensibility.ITelemetryInitializer' from singleton 'Microsoft.Extensions.Options.IConfigureOptions`1[Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration]'.'

Now, my code looks just about identical to @PeterBons' answer below, so on the face of it this exception made no sense. TelemetryConfiguration doesn't event appear in my code. But then I remembered I am using Scrutor to lazily do DI registration in Startup:

    services.Scan(scan => scan
        .FromAssembliesOf(typeof(Startup), typeof(MyDbContext))
        .AddClasses()
        .AsSelfWithInterfaces().WithScopedLifetime());

I assume the problem was that I need to register my ITelemetryInitializer as Singleton, and this code was inadvertently de- or re-registering it as scoped. So I changed the last two lines to:

        .AddClasses(f => f.Where(t => t != typeof(RealUserAIProvider)))
        .AsSelfWithInterfaces().WithScopedLifetime());

And it worked. Rather than editing out my mistake above, I'll leave it. @PeterBons' answer below is still going to be helpful to other people, and maybe my confusion with Scrutor will help someone too.

Horntail answered 10/7, 2019 at 22:31 Comment(0)
D
6

You don't have to register the HttpContextAccessor as a scoped dependency. Just use a singleton.

We have this working in production using this:

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

combined with this initializer:

public class SessionDetailsTelemetryEnrichment : TelemetryInitializerBase
{
    public SessionDetailsTelemetryEnrichment(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
    {

    }

    protected override void OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry)
    {
        telemetry.Context.User.AuthenticatedUserId =
            platformContext.User?.Claims.FirstOrDefault(c => c.Type == "Username")?.Value ?? string.Empty;

    }
}
Deluca answered 11/7, 2019 at 5:53 Comment(2)
Thank you. After seeing your comment, I went back and retried what I was doing yesterday, only to realize the exception I was getting didn't specifically mention IHttpContextAccessor. I'm being bitten by Scrutor doing automatic registration. Once I track down a fix, I'll update my post above. Deeply embarrassing, but maybe it will help someone else out. Thanks again.Horntail
Hi, could you please update your answer to show how to use SessionDetailsTelemetryEnrichment? I tried services.AddSingleton<ITelemetryInitializer, SessionDetailsTelemetryEnrichment>(); but that doesn't help. Please check my question on this hereCerotype

© 2022 - 2024 — McMap. All rights reserved.