如何从ILogger中获取自定义ILogger实现,例如控制器?

时间:2017-09-08 07:08:15

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

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

的扩展方法
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上的所有日志记录方法。

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

2 个答案:

答案 0 :(得分:0)

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

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

public LoggerInformation[] Loggers { get; set; }

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

答案 1 :(得分:0)

因此,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;
    }

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