在 Application Insight .Net Core 2.1 中使用自定义属性记录用户名和 IP
Log UserName and IP with Custom Properties in Application Insight .Net Core 2.1
我们是 运行 .Net Core 2.0 上的 Intranet 应用程序。应用程序洞察力非常有助于捕获异常。因此,当用户向我们寻求支持时,我们希望找到他的请求导致应用程序洞察出现问题。我添加了一个 ClientIpHeaderTelemetryInitializer,如下所示:
public class CustomTelemetry : ClientIpHeaderTelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor ;
public CustomTelemetry(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
/// <summary>
/// Implements initialization logic.
/// </summary>
/// <param name="platformContext">Http context.</param>
/// <param name="requestTelemetry">Request telemetry object associated with the current request.</param>
/// <param name="telemetry">Telemetry item to initialize.</param>
protected override void OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry)
{
requestTelemetry.Properties.Add("UserName", _httpContextAccessor.HttpContext.User.Identity.Name);
if (string.IsNullOrEmpty(telemetry.Context.Location.Ip))
{
LocationContext location = requestTelemetry.Context.Location;
telemetry.Context.Location.Ip = location.Ip;
requestTelemetry.Properties.Add("InternalIP", location.Ip);
}
}
}
Initalizer 在启动时注册如下:
services.AddSingleton<ITelemetryInitializer, CustomTelemetry>();
当我查看自定义数据请求时,仍然显示为空。
我是不是注册错了?我在 Application Insights 的集成测试中找到了添加服务的完全相同的行(尽管被注释掉了...)
有没有人知道哪里出了问题?
首先,您需要通过 visual studio 中的菜单选项将应用程序洞察添加到您的 asp.net 核心项目:
其次,在你的CustomTelemetry
class中,你最好设置一个断点以确保在代码为运行.
时可以命中它。
第三,在你的 CustomTelemetry
class 中,请在 UserName
和 InternalIP
为 null 或空时做一些逻辑。如果这些值为 null 或为空,则不会添加它们。
我的测试代码如下:
CustomTelemetry class:
public class CustomTelemetry: ITelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor;
public CustomTelemetry(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void Initialize(ITelemetry telemetry)
{
var requestTelemetry = telemetry as RequestTelemetry;
if (requestTelemetry == null) return;
if (!requestTelemetry.Context.Properties.ContainsKey("UserName"))
{
//if UserName is null or empty, add a default value for it
if (string.IsNullOrEmpty(_httpContextAccessor.HttpContext.User.Identity.Name))
{
requestTelemetry.Context.Properties.Add("UserName", "NA");
}
else
{
requestTelemetry.Context.Properties.Add("UserName", _httpContextAccessor.HttpContext.User.Identity.Name);
}
}
if (!requestTelemetry.Context.Properties.ContainsKey("InternalIP"))
{
//update
if (!string.IsNullOrEmpty(requestTelemetry.Context.Location.Ip))
{
requestTelemetry.Context.Properties.Add("InternalIP", requestTelemetry.Context.Location.Ip);
}
}
}
}
然后在Startup
注册 class:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<ITelemetryInitializer, CustomTelemetry>();
services.AddApplicationInsightsTelemetry();
}
测试结果:
因为我没有你的ClientIpHeaderTelemetryInitializer
class,就写上面的测试代码吧。如果您需要更多帮助,请分享 class.
我终于让它为我的目的工作了。
public class CustomTelemetry : ClientIpHeaderTelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor ;
public CustomTelemetry(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
/// <summary>
/// Implements initialization logic.
/// </summary>
/// <param name="platformContext">Http context.</param>
/// <param name="requestTelemetry">Request telemetry object associated with the current request.</param>
/// <param name="telemetry">Telemetry item to initialize.</param>
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 (ip != null) telemetry.Context.GlobalProperties.TryAdd("InternalIP", ip);
if(userName != null) requestTelemetry.Properties.Add("UserName", userName);
}
}
(注意:ClientIpHeaderTelemetryInitializer 是 AppInsights 的一部分)
此处重要的是从 HttpContext 获取所有内容,检查它是否为 null 并添加自定义属性。否则,IP 的内置属性可能会被覆盖。 Migrosoft GDPR Blogpost
在 Startup 中将其添加到 ConfigureService
services.AddSingleton<ITelemetryInitializer, CustomTelemetry>();
确保事先添加 ContextAccessor 以便可以注入:
services.AddHttpContextAccessor();
在Configure的开头加上这个:
app.UseForwardedHeaders(new ForwardedHeadersOptions{ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto});
在使用 反向代理 如 IIS 时,获取 IP 地址 非常重要.否则,您将始终收到本地主机。没有选项的 UseForwardedHeaders() 什么都不做! (您还需要使用远程服务器进行测试设置)
获取 用户名 似乎在请求失败时有效(通过 500 内部服务器错误测试)。否则 HttpContextAccessor 不会填充用户对象。可能是 2.1 的东西,很烦人,也许有人找到了一种方法来为每个请求获取它。
最后,您的信息应该到达 ApplicationInsights,如下所示:
我们是 运行 .Net Core 2.0 上的 Intranet 应用程序。应用程序洞察力非常有助于捕获异常。因此,当用户向我们寻求支持时,我们希望找到他的请求导致应用程序洞察出现问题。我添加了一个 ClientIpHeaderTelemetryInitializer,如下所示:
public class CustomTelemetry : ClientIpHeaderTelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor ;
public CustomTelemetry(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
/// <summary>
/// Implements initialization logic.
/// </summary>
/// <param name="platformContext">Http context.</param>
/// <param name="requestTelemetry">Request telemetry object associated with the current request.</param>
/// <param name="telemetry">Telemetry item to initialize.</param>
protected override void OnInitializeTelemetry(HttpContext platformContext, RequestTelemetry requestTelemetry, ITelemetry telemetry)
{
requestTelemetry.Properties.Add("UserName", _httpContextAccessor.HttpContext.User.Identity.Name);
if (string.IsNullOrEmpty(telemetry.Context.Location.Ip))
{
LocationContext location = requestTelemetry.Context.Location;
telemetry.Context.Location.Ip = location.Ip;
requestTelemetry.Properties.Add("InternalIP", location.Ip);
}
}
}
Initalizer 在启动时注册如下:
services.AddSingleton<ITelemetryInitializer, CustomTelemetry>();
当我查看自定义数据请求时,仍然显示为空。
我是不是注册错了?我在 Application Insights 的集成测试中找到了添加服务的完全相同的行(尽管被注释掉了...)
有没有人知道哪里出了问题?
首先,您需要通过 visual studio 中的菜单选项将应用程序洞察添加到您的 asp.net 核心项目:
其次,在你的CustomTelemetry
class中,你最好设置一个断点以确保在代码为运行.
第三,在你的 CustomTelemetry
class 中,请在 UserName
和 InternalIP
为 null 或空时做一些逻辑。如果这些值为 null 或为空,则不会添加它们。
我的测试代码如下:
CustomTelemetry class:
public class CustomTelemetry: ITelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor;
public CustomTelemetry(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public void Initialize(ITelemetry telemetry)
{
var requestTelemetry = telemetry as RequestTelemetry;
if (requestTelemetry == null) return;
if (!requestTelemetry.Context.Properties.ContainsKey("UserName"))
{
//if UserName is null or empty, add a default value for it
if (string.IsNullOrEmpty(_httpContextAccessor.HttpContext.User.Identity.Name))
{
requestTelemetry.Context.Properties.Add("UserName", "NA");
}
else
{
requestTelemetry.Context.Properties.Add("UserName", _httpContextAccessor.HttpContext.User.Identity.Name);
}
}
if (!requestTelemetry.Context.Properties.ContainsKey("InternalIP"))
{
//update
if (!string.IsNullOrEmpty(requestTelemetry.Context.Location.Ip))
{
requestTelemetry.Context.Properties.Add("InternalIP", requestTelemetry.Context.Location.Ip);
}
}
}
}
然后在Startup
注册 class:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSingleton<ITelemetryInitializer, CustomTelemetry>();
services.AddApplicationInsightsTelemetry();
}
测试结果:
因为我没有你的ClientIpHeaderTelemetryInitializer
class,就写上面的测试代码吧。如果您需要更多帮助,请分享 class.
我终于让它为我的目的工作了。
public class CustomTelemetry : ClientIpHeaderTelemetryInitializer
{
private readonly IHttpContextAccessor _httpContextAccessor ;
public CustomTelemetry(IHttpContextAccessor httpContextAccessor) : base(httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
/// <summary>
/// Implements initialization logic.
/// </summary>
/// <param name="platformContext">Http context.</param>
/// <param name="requestTelemetry">Request telemetry object associated with the current request.</param>
/// <param name="telemetry">Telemetry item to initialize.</param>
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 (ip != null) telemetry.Context.GlobalProperties.TryAdd("InternalIP", ip);
if(userName != null) requestTelemetry.Properties.Add("UserName", userName);
}
}
(注意:ClientIpHeaderTelemetryInitializer 是 AppInsights 的一部分)
此处重要的是从 HttpContext 获取所有内容,检查它是否为 null 并添加自定义属性。否则,IP 的内置属性可能会被覆盖。 Migrosoft GDPR Blogpost
在 Startup 中将其添加到 ConfigureService
services.AddSingleton<ITelemetryInitializer, CustomTelemetry>();
确保事先添加 ContextAccessor 以便可以注入:
services.AddHttpContextAccessor();
在Configure的开头加上这个:
app.UseForwardedHeaders(new ForwardedHeadersOptions{ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto});
在使用 反向代理 如 IIS 时,获取 IP 地址 非常重要.否则,您将始终收到本地主机。没有选项的 UseForwardedHeaders() 什么都不做! (您还需要使用远程服务器进行测试设置)
获取 用户名 似乎在请求失败时有效(通过 500 内部服务器错误测试)。否则 HttpContextAccessor 不会填充用户对象。可能是 2.1 的东西,很烦人,也许有人找到了一种方法来为每个请求获取它。
最后,您的信息应该到达 ApplicationInsights,如下所示: