Asp.net core ASP.net核心:如何将头值注入自定义记录器?
如果请求HTTP头具有类似CorrelationId的值,那么我的自定义记录器如何获取该值,以便所有日志条目都具有CorrelationId 公共ILogger CreateLogger(字符串类别名称)Asp.net core ASP.net核心:如何将头值注入自定义记录器?,asp.net-core,logging,Asp.net Core,Logging,如果请求HTTP头具有类似CorrelationId的值,那么我的自定义记录器如何获取该值,以便所有日志条目都具有CorrelationId 公共ILogger CreateLogger(字符串类别名称) 无法更改以插入任何参数,并且必须实现iLogger Provider您可以在ConfigureService中注册IHttpContextAccessor,并将其实例传递给自定义记录器 然后您可以使用 var header = _accessor.HttpContext.Request.Hea
无法更改以插入任何参数,并且必须实现iLogger Provider您可以在ConfigureService中注册
IHttpContextAccessor
,并将其实例传递给自定义记录器
然后您可以使用
var header = _accessor.HttpContext.Request.Headers["CorrelationId"].ToString()
1.startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
{
loggerFactory.AddCustomLogger(serviceProvider.GetService<IHttpContextAccessor>());
}
public void配置服务(IServiceCollection服务)
{
services.AddSingleton();
}
public void配置(IApplicationBuilder应用程序、ILoggerFactory loggerFactory、IServiceProvider服务提供商)
{
loggerFactory.AddCustomLogger(serviceProvider.GetService());
}
2.CustomLogger.cs:
public class CustomLogProvider : ILoggerProvider
{
private readonly Func<string, LogLevel, bool> _filter;
private readonly IHttpContextAccessor _accessor;//DI
public CustomLogProvider(Func<string, LogLevel, bool> filter, IHttpContextAccessor accessor)
{
_filter = filter;
_accessor = accessor;
}
public ILogger CreateLogger(string categoryName)
{
return new CustomLogger(categoryName, _filter, _accessor);
}
public void Dispose()
{
}
}
public class CustomLogger : ILogger
{
private string _categoryName;
private Func<string, LogLevel, bool> _filter;
private readonly IHttpContextAccessor _accessor;
public CustomLogger(string categoryName, Func<string, LogLevel, bool> filter, IHttpContextAccessor accessor)
{
_categoryName = categoryName;
_filter = filter;
_accessor = accessor;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return (_filter == null || _filter(_categoryName, logLevel));
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
if (formatter == null)
{
throw new ArgumentNullException(nameof(formatter));
}
var message = formatter(state, exception);
if (string.IsNullOrEmpty(message))
{
return;
}
message = $"{ logLevel }: {message}";
if (exception != null)
{
message += Environment.NewLine + Environment.NewLine + exception.ToString();
}
if (_accessor.HttpContext != null) // you should check HttpContext
{
var headers = _accessor.HttpContext.Request.Headers["CorrelationId"].ToString();
if(headers != "")
{
message += Environment.NewLine + headers + Environment.NewLine + _accessor.HttpContext.Request.Path;
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.WriteLine(message);
}
}
// your implementation
}
}
public static class CustomLoggerExtensions
{
public static ILoggerFactory AddCustomLogger(this ILoggerFactory factory, IHttpContextAccessor accessor,
Func<string, LogLevel, bool> filter = null)
{
factory.AddProvider(new CustomLogProvider(filter, accessor));
return factory;
}
}
公共类CustomLogProvider:ILoggerProvider
{
专用只读函数过滤器;
私有只读IHttpContextAccessor _accessor;//DI
公共CustomLogProvider(Func筛选器、IHttpContextAccessor访问器)
{
_过滤器=过滤器;
_存取器=存取器;
}
公共ILogger CreateLogger(字符串类别名称)
{
返回新的CustomLogger(categoryName、\u filter、\u accessor);
}
公共空间处置()
{
}
}
公共类CustomLogger:ILogger
{
私有字符串_categoryName;
私有函数过滤器;
专用只读IHttpContextAccessor\u访问器;
公共CustomLogger(字符串类别名称、Func筛选器、IHttpContextAccessor访问器)
{
_categoryName=categoryName;
_过滤器=过滤器;
_存取器=存取器;
}
公共IDisposable BeginScope(州)
{
返回null;
}
公共布尔值已启用(日志级别日志级别)
{
返回(_filter==null | | u filter(_categoryName,logLevel));
}
公共无效日志(日志级别、日志级别、事件ID、事件ID、TState状态、异常、函数格式化程序)
{
如果(!IsEnabled(日志级别))
{
返回;
}
if(格式化程序==null)
{
抛出新ArgumentNullException(nameof(formatter));
}
var消息=格式化程序(状态、异常);
if(string.IsNullOrEmpty(message))
{
返回;
}
message=$“{logLevel}:{message}”;
if(异常!=null)
{
message+=Environment.NewLine+Environment.NewLine+exception.ToString();
}
如果(_accessor.HttpContext!=null)//您应该检查HttpContext
{
var headers=_accessor.HttpContext.Request.headers[“CorrelationId”].ToString();
如果(标题!=“”)
{
message+=Environment.NewLine+headers+Environment.NewLine+\u accessor.HttpContext.Request.Path;
Console.ForegroundColor=ConsoleColor.DarkGreen;
控制台写入线(消息);
}
}
//您的实现
}
}
公共静态类CustomLoggerExtensions
{
公共静态iLogger工厂AddCustomLogger(此iLogger工厂、IHttpContextAccessor访问器、,
Func filter=null)
{
AddProvider(新的CustomLogProvider(过滤器、访问器));
返回工厂;
}
}
我最后使用的解决方案是实现一个具有相关id的基类。
创建了一个customer Controller工厂类,以从标头获取相关Id并将其设置在基类上。
然后,记录器可以使用基类中的值
示例代码位于此处。