Application Insights 将用户名添加到遥测

Gur*_*101 5 c# asp.net azure-application-insights

我试图在用户发出请求时在应用程序见解中记录用户的用户名。

我一直在尝试这样做:

 public class AppInsightsInitializer : ClientIpHeaderTelemetryInitializer
    {
        private readonly IHttpContextAccessor _httpContextAccessor;

        public AppInsightsInitializer(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
        {
            _httpContextAccessor = httpContextAccessor;
        }

        protected override void OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry)
        {
            var userName = _httpContextAccessor.HttpContext?.User?.Identity?.Name; // Only set when request failed...
            var ip = _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
            if (userName != null) requestTelemetry.Context.User.AuthenticatedUserId= userName;
        }
    }
Run Code Online (Sandbox Code Playgroud)

在中注入并注册遥测后Startup.cs

 services.AddApplicationInsightsTelemetry(instrumentKey);
 services.AddSingleton<ITelemetryInitializer, AppInsights.AppInsightsInitializer>();
Run Code Online (Sandbox Code Playgroud)

但这会导致System.ObjectDisposedException: 'Safe handle has been closed

System.ObjectDisposedException
  HResult=0x80131622
  Message=Safe handle has been closed
  Source=mscorlib
  StackTrace:
   at System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success)
   at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
   at Microsoft.Win32.Win32Native.GetTokenInformation(SafeAccessTokenHandle TokenHandle, UInt32 TokenInformationClass, SafeLocalAllocHandle TokenInformation, UInt32 TokenInformationLength, UInt32& ReturnLength)
   at System.Security.Principal.WindowsIdentity.GetTokenInformation(SafeAccessTokenHandle tokenHandle, TokenInformationClass tokenInformationClass)
   at System.Security.Principal.WindowsIdentity.get_User()
   at System.Security.Principal.WindowsIdentity.GetName()
   at System.Security.Principal.WindowsIdentity.get_Name()
   at Webeco.Web.AppInsights.AppInsightsInitializer.OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry) in C:\Users\SESEGU\Documents\Projects\AppInsights\AppInsightsInitializer.cs:line 24
   at Microsoft.ApplicationInsights.AspNetCore.TelemetryInitializers.TelemetryInitializerBase.Initialize(ITelemetry telemetry)
   at Microsoft.ApplicationInsights.TelemetryClient.Initialize(ITelemetry telemetry)
Run Code Online (Sandbox Code Playgroud)

然后我尝试了下面的代码:

 public class AppInsightsInitializer : ITelemetryInitializer
    {
        public void Initialize(ITelemetry telemetry)
        {
            var identity = WindowsIdentity.GetCurrent();
            if (identity != null)
            {
                var name = new WindowsPrincipal(identity);
                telemetry.Context.User.AuthenticatedUserId = name.Identity.Name;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

这在本地机器上运行良好。但是当我在开发环境中尝试它时,它只记录服务器名称而不是用户名。

所以我认为我的第一个解决方案是正确的方法。然而,除了例外,我无法克服它的崩溃Safe handle has been closed

有什么帮助可以克服这个吗?

Nes*_*aje 5

环顾四周后,看起来这可能会解决您的问题

    public class AuthenticatedUserIdTelemetryInitializer : ITelemetryInitializer
    {
        IHttpContextAccessor httpContextAccessor;

        public AuthenticatedUserIdTelemetryInitializer(IHttpContextAccessor httpContextAccessor)
        {
            this.httpContextAccessor = httpContextAccessor;
        }

        public void Initialize(ITelemetry telemetry)
        {
            if (this.httpContextAccessor?.HttpContext?.User?.Identity?.IsAuthenticated == true)
                telemetry.Context.User.AuthenticatedUserId = this.httpContextAccessor.HttpContext.User.Identity.Name;
        }
    }
Run Code Online (Sandbox Code Playgroud)

这实际上是你的两个例子的组合。我相信区别在于使用Initialize方法而不是重写OnInitializeTelemetry方法。可能你的httpContextAccessor方法在Initialize方法中仍然存在,而它已经在被覆盖的方法中被释放了。不确定继承的动机是什么ClientIpHeaderTelemetryInitializer以及是否相关。

代码是从这里复制的。