【问题标题】:How do I get my custom ILogger implementation from ILogger in, for example a controller?如何从 ILogger 中获取我的自定义 ILogger 实现,例如控制器?
【发布时间】:2018-02-17 00:46:31
【问题描述】:

我有一个自定义记录器,我想创建一个名为

的扩展方法
SetContext(uniqueKey, object) 

我可以在自定义记录器中设置属性并在记录消息时记录该上下文。

所以代码看起来像这样

_logger
     .SetContext(User.Email(), User)
           .LogError(1, new Exception("foo foo foo"), "bleep Bloop");

我似乎面临的问题是 ILogger,通过我的控制器中的 DI 返回,然后由我的扩展方法使用,实际上并不是我的自定义 ILogger 实现。

 public static ILogger SetContext(this ILogger logger, string uniqueUserIdentifier, object context)
    {
        var redisPublisherLogger = logger as RedisPublisherLogger;

        if (redisPublisherLogger == null)
        {
            return logger;
        }

        redisPublisherLogger.Context = new LoggingContext
        {
            ContextData = context,
            UniqueUserIdentifier = uniqueUserIdentifier
        };

        return logger;
    }

那么无论如何我可以做这样的事情,我试图避免覆盖 ILogger 上的所有日志记录方法。

任何帮助将不胜感激! 谢谢

【问题讨论】:

    标签: logging dependency-injection asp.net-core asp.net-core-mvc error-logging


    【解决方案1】:

    对您的问题有部分答案...

    DI 返回一个Microsoft.Extensions.Logging.Logger 实例,它是所有已注册记录器的聚合器。如果你检查实现,你会看到它有

    public LoggerInformation[] Loggers { get; set; }
    

    Log 方法遍历这些记录器并分别调用每个记录器。您的 RedisPublisherLogger 实例是该数组中的一个项目。问题从这里开始,因为这个Logger 类是内部的,而ILogger 接口没有公开该属性。

    【讨论】:

    • 谢谢,我确实注意到了,但是因为它是内部的,所以我不能使用它。我正忙着研究使用 BeginScope,因为它将上下文添加到日志中。
    【解决方案2】:

    所以 BeginScope 允许您为日志提供上下文... 这个链接很好地解释了它...... https://nblumhardt.com/2016/11/ilogger-beginscope/

    但我做的一个例子是:

     public static ILogger SetContext(this ILogger logger, string uniqueUserIdentifier, object context)
        {
            var scope = logger.BeginScope(new LoggingContext
            {
                ContextData = context,
                UniqueUserIdentifier = uniqueUserIdentifier
            });
    
            scope.Dispose();
    
            return logger;
        }
    

    然后在我创建的 ILogger 实现中:

    private string _loggingContext;
    

    对于 BeginScope 实现,我这样做了:

      public IDisposable BeginScope<TState>(TState state)
        {
            var s = state as IDisposable;
    
            _loggingContext = JsonConvert.SerializeObject(s);
    
            return s;
        }
    

    所以现在我可以使用我的特定上下文数据...

    【讨论】:

    • 如果我使用您的示例,如果记录器在处理范围后接收到数据会发生什么?它仍然有_loggingContext 还是创建了一个新的记录器?
    猜你喜欢
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    相关资源
    最近更新 更多