代码之家  ›  专栏  ›  技术社区  ›  pbristow

从中填充Application Insights中的用户Id字段ASP.NET核心

  •  0
  • pbristow  · 技术社区  · 5 年前

    我希望能够用我的真实用户名数据填充Application Insights中的User Id字段。这是一个内部应用程序,因此对简单用户名字段的隐私关注是没有意义的。

    据我所知,所有在线解决方案都严格在.NETFramework中工作,而不是.NETCore。

    你可以找到 this solution 在一些地方,包括GitHub上的一些旧AI文档。但是,当我运行它时,在启动时会出现一个错误,表明单例不能接受对作用域对象IHttpContextAccessor的依赖,这当然是合乎逻辑的。除非.NETCore的DI以前的版本允许,否则我看不出这是怎么工作的(我在2.2上)。

    This issue on GitHub 在某种程度上解释了问题,但在AI团队指出必须使用单例后,问题就解决了。我尝试了OP和第一个响应中的内容的变体,当代码运行时,AI上的用户Id字段继续被乱七八糟的数据填充。

    有没有办法让AI中的userid字段填充一些有用的东西,以满足来自一个ASP.NET核心应用程序?

    编辑

    在看到下面的答案(我的代码应该可以正常工作)后,我返回并意识到异常消息没有特别提到IHttpContextAccessor:

    System.InvalidOperationException异常: '无法使用作用域服务 'Microsoft.ApplicationInsights.Extensibility可扩展性.ITelemetryInitializer' 从辛格尔顿 'Microsoft.Extensions.Options.IConfigureOptions​​`1[Microsoft.ApplicationInsights.Extensibility可扩展性.TelemetryConfiguration]'。'

    现在,我的代码看起来和下面@PeterBons的答案差不多,所以表面上看这个异常毫无意义。 TelemetryConfiguration 事件不会出现在我的代码中。但后来我想起我正在使用Scrutor在Startup中懒洋洋地进行DI注册:

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

    我假设问题是我需要将我的ITelemetryInitializer注册为Singleton,而这段代码无意中将其取消注册或重新注册为scoped。所以我把最后两行改成:

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

    而且成功了。与其删掉我上面的错误,我还是留下吧。@彼得伯恩下面的回答仍然会对其他人有所帮助,也许我对Scrutor的混淆也会对其他人有所帮助。

    0 回复  |  直到 5 年前
        1
  •  6
  •   Peter Bons    5 年前

    你不必注册 HttpContextAccessor 作为作用域依赖项。就用一个单子。

    我们在生产过程中使用:

    services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    

    结合此初始值设定项:

    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;
    
        }
    }