【问题标题】:Implementing Open Source Library: How to handle logging?实现开源库:如何处理日志记录?
【发布时间】:2011-01-16 04:17:26
【问题描述】:

我正在我正在开发的开源库中实现日志记录支持。大多数第 3 方库似乎明确选择了“首选”日志库,例如 Log4NetNLog 等,然后要求其库的使用者“处理它”。值得庆幸的是,我们有一个像 Common.Logging 这样的库来解决我们的消费应用程序中的这个问题,它统一了这些 3rd 方库日志记录实现。

我将尝试避免从我自己的开源库中引用另一个 3rd 方库,以避免将另一个程序集引用引入其他人的应用程序。也许这不是问题,我应该就此打住?

假设有些人同意过多的程序集引用很烦人(并且因为有人会提到它),我个人不喜欢在这种情况下使用 ILMerge,因为您可能很容易拥有多个使用 Log4Net 的库和如果他们每个人都在程序集中进行了 ILMerged,那么在我看来,这只是增加了应用程序的大小。

为此,我正在考虑实现和公开一个 LogBridge,以允许我的库的使用者在需要时连接到我的日志记录调用(默认情况下会关闭)。 另外让我强调一下,我不是在谈论实现我自己的日志框架,只是确保我在有人担心使用它时公开日志记录。我认为消费实现看起来像这样: p>

public class SomeSetupClass 
{
  private void SomeSetupMethod()
  {
    var log = LogManager.GetLogger("LogSourceName");
    var logBridge = new LogBridge()
                      {
                        DebugEnabled = log.IsDebugEnabled,
                        InformationEnabled = log.IsInfoEnabled,
                        WarningEnabled = log.IsWarnEnabled,
                        ErrorEnabled = log.IsErrorEnabled,
                        CriticalEnabled = log.IsFatalEnabled
                      };

    logBridge.DebugMessageReceived += (sender, e) => log.Debug(e.Message);
    logBridge.InformationMessageReceived += (sender, e) => log.Info(e.Message);
    logBridge.WarningMessageReceived += (sender, e) => log.Warn(e.Message);
    logBridge.ErrorMessageReceived += (sender, e) => log.Error(e.Message);
    logBridge.CrticalMessageReceived += (sender, e) => log.Fatal(e.Message);      }
  }
}

这种方法有意义吗?在假期太久之后我是否过度思考这个问题,我应该参考Log4NetNLog 等并完成它?我错过了这种方法的任何主要缺点吗?粗略的 API 有意义吗?

一如既往,好奇大家的想法……

更新

好奇人们是否认为 jgauffin 解决方案是更好的选择?在这篇文章之前我已经考虑过了;我的想法是 LogBridge 更容易为消费者连接,而不是需要在消费项目中实现自定义接口?想法?

【问题讨论】:

  • 这样的事情很有意义。那里有许多日志框架——有些比其他的好。每个人都有自己的最爱。通过在你做的时候提供一个很好的钩子,你不会把任何东西塞进任何人的喉咙里,而且你提供了极好的灵活性。

标签: .net logging


【解决方案1】:

查看 System.Diagnostics 并仅使用 Trace 或 Debug 类。像 Log4Net 这样的产品可以在需要时选择它们。

【讨论】:

  • 是的,我也考虑过这一点。我研究了如何实现 CustomTraceListener,尽管您可以覆盖 TraceEvent 的处理; API 似乎希望您覆盖 Write/WriteLine,此时您将丢失 TraveEventLevel。问题/非问题?
  • 没有问题 - 您从基本跟踪侦听器继承,因此您仍然可以构建您的 WriteLine() 方法以考虑到这一点(如果您愿意的话)。
  • 很公平……那是我最初的计划……当我看到 Write/WriteLine 是抽象的并且必须被覆盖时才开始考虑替代方案……感谢您的输入。
【解决方案2】:

我通常这样做:

  1. 提供日志接口:ILogger
  2. 创建用于获取记录器的记录器工厂:ILogger _logger = LogManager.GetLogger(typeof(ClassBeingLogged));
  3. 提供ConsoleLogger等基本实现。

您还可以在项目 wiki 中提供示例,展示如何实现 nlog 或 log4net。这通常就足够了。

LogManager 采用ILogFactory,它负责创建实际的实现:

public class LogManager
{ 
    ILogFactory _factory;

    public static void Assign(ILogFactory factory);
    public static ILogger GetLogger(Type typeBeingLogged);
}

public interface ILogFactory
{
    ILogger GetLogger(Type typeBeingLogged);
}

这使得为任何日志框架实现适配器变得非常容易。

【讨论】:

  • 我对这种方法进行了一些思考;我的想法是主要缺点是用户必须实现并注入日志接口的实现。我最初的印象是,对于消费者来说,这比仅仅将他们现有的日志框架绑定到一个非常简单的 LogBridge API 更有用。话虽如此,正如您指出的那样,项目 Wiki 中的示例是必须的。想法?
  • 通常只需要实现两个类即可使其正常工作。您还可以创建一个您合并的 nlog 或 log4net 实现(我并不是说您应该合并 log4net/nlog,而是框架的适配器)并在您的站点上提供单独的下载。用户仍然可以使用他们最喜欢的日志框架,因为主下载只定义了接口。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-07
  • 2020-01-14
  • 2012-11-09
  • 1970-01-01
  • 2018-07-31
相关资源
最近更新 更多