要详细说明@pinkfloydx33 的评论:您可以通过
_logger.BeginScope( < your state here > )
{
// All log methods here include state, regardless
// of which ILogger object is used.
}
或通过使用
System.Diagnostics.Activity.Current.AddBaggage()
这无需额外配置即可工作(例如,范围已在 AI 上默认启用)。
例如,这是一个中间件类,用于记录显示两种方法的租户信息:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace MyApp
{
public static class StoreTenantForLoggingMiddlewareExtensions
{
/// <summary>
/// Register StoreTenantForLoggingMiddleware as middleware.
/// Call this from Configure() in Startup, as:
/// app.UseStoreTenantForLogging()
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
public static IApplicationBuilder UseStoreTenantForLogging(
this IApplicationBuilder builder)
{
return builder.UseMiddleware<StoreTenantForLoggingMiddleware>();
}
}
/// <summary>
/// Middleware to log the Tenant's domain to Application
/// Insights as a customDimension
/// </summary>
public class StoreTenantForLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<StoreTenantForLoggingMiddleware> _logger;
public StoreTenantForLoggingMiddleware(RequestDelegate next,
ILogger<StoreTenantForLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
// Here TenantContext is my own class that gets the state
// I want to be logged. You'd replace with your own object
// or just call a method on httpContext.
public async Task InvokeAsync(HttpContext httpContext, TenantContext tenantContext)
{
// Example 1: Add data to current activity. AI will pick this
// up and add as a customDimension in traces logs.
var currentActivity = System.Diagnostics.Activity.Current;
if (currentActivity != null)
{
currentActivity.AddBaggage("TenantDomain1", tenantContext?.Domain);
}
// Example 2: Use a scope.
// If you go with option 1, remove this 'using' but still
// call await _next(httpContext);
using ( var scope = _logger.BeginScope(new Dictionary<string, object>()
{ { "TenantDomain2", tenantContext?.Domain } }))
{
await _next(httpContext);
}
}
}
}
我不确定哪个是最好的。这个Activity
对我来说更有吸引力,而且我猜数据可能会在管道中持续一段时间。
如果您使用 nlog 并希望能够在那里记录该属性,您可以在Invoke()
上面的开头添加这一行,然后${mdlc:item=TenantDomain}
在您的nlog.config
文件中使用。
NLog.MappedDiagnosticsLogicalContext.Set("TenantDomain", tenantContext?.Domain);
您可能可以使用https://github.com/NLog/NLog.DiagnosticSource作为替代方案,但我没有尝试过。