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

Lyo*_*yon 1 logging error-logging dependency-injection asp.net-core-mvc asp.net-core

我有一个自定义记录器,我想创建一个名为的扩展方法

SetContext(uniqueKey, object) 
Run Code Online (Sandbox Code Playgroud)

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

所以代码看起来像这样

_logger
     .SetContext(User.Email(), User)
           .LogError(1, new Exception("foo foo foo"), "bleep Bloop");
Run Code Online (Sandbox Code Playgroud)

我似乎面临的问题是,通过控制器中的 DI 返回的 ILogger 又由我的扩展方法使用,实际上并不是我的自定义 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;
    }
Run Code Online (Sandbox Code Playgroud)

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

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

Lyo*_*yon 5

因此,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;
    }
Run Code Online (Sandbox Code Playgroud)

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

private string _loggingContext;
Run Code Online (Sandbox Code Playgroud)

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

  public IDisposable BeginScope<TState>(TState state)
    {
        var s = state as IDisposable;

        _loggingContext = JsonConvert.SerializeObject(s);

        return s;
    }
Run Code Online (Sandbox Code Playgroud)

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

  • 如果我使用您的示例,如果记录器在范围被处置后收到数据会发生什么?它是否仍然具有“_loggingContext”或者是否创建了新的记录器? (2认同)