【问题标题】:Implementation and usage of logger wrapper for SerilogSerilog logger wrapper的实现和使用
【发布时间】:2017-01-22 18:41:16
【问题描述】:

此问题与Steven 的答案-here 有关。他提出了一个非常好的记录器包装器。我将他的代码粘贴在下面:

public interface ILogger
{
    void Log(LogEntry entry);
}

public static class LoggerExtensions
{
    public static void Log(this ILogger logger, string message)
    {
        logger.Log(new LogEntry(LoggingEventType.Information,
            message, null));
    }

    public static void Log(this ILogger logger, Exception exception)
    {
        logger.Log(new LogEntry(LoggingEventType.Error, 
            exception.Message, exception));
    }

    // More methods here.
}

那么,我的问题是创建代理到 Serilog 的实现的正确方法是什么?

注意:此问题与 this question about log4net 有关,但现在特定于 Serilog。

【问题讨论】:

  • 你为什么提到你自己? :D 这是一个循环引用
  • @Sherlock 因为这只是关于 log4net 的相同问题(由其他人提出)的副本。我只需要公开记录这些信息,stackoverflow 对此非常有用。
  • 注意,传递 exception.Message 是因为消息对于 Serilog 来说是次优的;相反,如果您必须处理没有自己消息的事件,请使用常量message template,如{ExceptionMessage},并使用exception.Message 对其进行参数化。这避免了尝试将消息解析为模板,并且不会污染内部消息模板缓存。干杯!
  • 嗨尼克,请随时更新我的​​答案或添加您自己的答案。

标签: c# .net logging serilog


【解决方案1】:

那么,我的问题是创建代理到 Serilog 的实现的正确方法是什么?

你应该创建类似的东西:

public class SerilogAdapter : ILogger
{
    private readonly Serilog.ILogger m_Adaptee;

    public SerilogAdapter(Serilog.ILogger adaptee)
    {
        m_Adaptee = adaptee;
    }

    public void Log(LogEntry entry)
    {
        if (entry.Severity == LoggingEventType.Debug)
            m_Adaptee.Debug(entry.Exception, entry.Message);
        if (entry.Severity == LoggingEventType.Information)
            m_Adaptee.Information(entry.Exception, entry.Message);
        else if (entry.Severity == LoggingEventType.Warning)
            m_Adaptee.Warning(entry.Message, entry.Exception);
        else if (entry.Severity == LoggingEventType.Error)
            m_Adaptee.Error(entry.Message, entry.Exception);
        else
            m_Adaptee.Fatal(entry.Message, entry.Exception);
    }
}

这是否意味着每个将记录某事的类(基本上是每个类)都应该在其构造函数中包含 ILogger?

据我了解,史蒂文斯的回答是:是的,你应该这样做。

稍后在代码中使用它的最佳方式是什么?

如果您使用的是 DI 容器,则只需使用 DI 容器将 ILogger 映射到 SerilogAdapter。您还需要注册Serilog.ILogger,或者只是将一个 Serilog 记录器的实例提供给 DI 容器,以将其注入到 SerilogAdapter 构造函数中。

如果您不使用 DI 容器,即使用 Pure DI,那么您可以执行以下操作:

Serilog.ILogger log = Serilog.Log.Logger.ForContext("MyClass");

ILogger logging_adapter = new SerilogAdapter(log);

var myobject = new MyClass(other_dependencies_here, logging_adapter);

【讨论】:

  • 这应该如何与 Core 2.2 中使用的当前依赖注入一起使用?在 ConfigureServices 我有: services.AddSingleton();问题是,这会引发以下错误:InvalidOperationException: Unable to resolve service for type 'Serilog.ILogger' while trying to activate 'MyProject.Logging.Adapters.SerilogAdapter'
  • @RichieMN 您现在可能已经解决了这个问题,但是,在这里记录一下 - 只需添加 services.AddSingleton(Serilog.Log.Logger);。
  • 感谢您的回复!
  • SerilogAdapter.Log 是否会从调用类中获取 CallerMember、LineNumber 等值,或者它是否总是作为发起者填充为 SerilogAdapter 类?例如 - 如果 A 类通过在第 10 行调用 logging_adapter.log 来写入日志,那么带有 Callermember 的 Serilog 日志消息会是 ClassA 还是 SerilogAdapter?
  • 我是否遗漏了什么,或者我的理解是否正确,这将否定 Serilog 支持的结构化日志记录?
猜你喜欢
  • 2015-11-27
  • 1970-01-01
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多