【问题标题】:ASP.net Core: How to inject header values into custom logger?ASP.net Core:如何将标头值注入自定义记录器?
【发布时间】:2025-12-04 19:00:02
【问题描述】:

如果请求 HTTP 标头具有 CorrelationId 之类的值,我的自定义 Logger 如何获取此值,以便所有日志条目都具有 CorrelationId?

公共 ILogger CreateLogger(string categoryName) 不能更改注入任何参数,必须实现 ILoggerProvider

【问题讨论】:

    标签: asp.net-core logging


    【解决方案1】:

    您可以在 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>());
    
    }
    

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

    【讨论】:

      【解决方案2】:

      我使用的最终解决方案是实现一个具有相关 ID 的基类。 创建了一个客户控制器工厂类以从标头中获取相关 ID 并将其设置在基类上。 然后记录器可以使用基类中的值。

      示例代码位于此处。 https://github.com/xavierjohn/AspCoreApplicationPart/blob/PlusConfigureCreatedController/AspCoreApplicationPart/MyCustomControllerFactory.cs

      【讨论】:

        最近更新 更多