40

如何在标准跟踪、Logger.NET、企业库、log4net 或 Ukadc.Diagnostics 之间进行选择?

有没有一种情况比另一种更合适?……那会是什么?(ASP.NET、控制台应用、Azure 云、SOHO、企业...)

有什么好处或坏处?

我错过了任何其他主要的日志框架吗?

4

6 回答 6

103

SO上有很多类似的问题:

你错过了几个常用的日志框架。以下是常用框架的列表,您列出了其中的一些:

日志抽象:

System.Diagnostics 插件:

其他

来自 codeplex 的其他几个日志框架(我在 SO 上看到过这里提到的):

为什么你会选择一个而不是另一个?这是一个艰难的。很多都是个人喜好。其中一些是技术(或功能)优势。

任何日志框架(尤其是第三方框架)的一个明显缺点是支持质量。如果您对 log4net、NLog、Common.Logging 等有疑问怎么办?你能从这些框架的开发者那里得到修复吗?这可能不是非常重要,因为源代码可用于这些框架。但是,您可能不希望仅仅为了进行修复或添加增强而“继承”源代码树。我会说这些框架非常可扩展,可以通过正常的扩展点添加许多增强功能。

如果您阅读了我在上面发布的链接,我认为可以公平地说,仅根据好评的数量,log4net 将是明显的“赢家”。它将被更频繁地提及为历史上最喜欢的日志记录以及许多人未来会选择使用的东西。

NLog 有它的支持者,但它似乎没有 log4net 的渗透力或“首要”意识,尽管它们非常相似。NLog 的功能与 log4net 非常相似,并且它具有最近经历了重要的开发周期的额外优势。

企业库经常被吹捧为一个不错的选择,但几乎同样经常被吹捧为一个糟糕的选择。也许它的一些负面声誉可能不是那么好早期版本?也许现在好多了?

System.Diagnostics 通常被推荐为一个合理的选择,它至少具有三个强大的好处:没有第三方依赖,许多 Microsoft 组件都使用 System.Diagnostics 进行检测,它很容易扩展(可能是添加一些已经“免费”提供的功能在 log4net 和 NLog 等框架中?)。如果您使用 System.Diagnostics,我认为共识(正如我的建议)使用 TraceSource 对象而不是 Trace.WriteLine/Debug.WriteLine。

还要注意 System.Diagnostics 和 WCF 可以很好地协同工作。可以使用 System.Diagnostics 记录 WCF 消息流量,并且 WCF 还将跨 WCF 服务边界调用传播 System.Diagnostics 活动信息 (System.Diagnostics.CorrelationManager.ActivityId)。

我不太确定 log4net 是否应该继续保持其最受青睐的状态。 正如在 SO 的其他地方所指出的那样,log4net 最近似乎没有进行大量开发(请注意,我认为“log4net 已死”是夸大其词),而 NLog 2.0 目前处于测试阶段,最终版本预计在第一季度发布2011(更新:NLog 2.0于 2011年 7 月 17 日发布)。这是否使 NLog 成为比 log4net 更好的选择?我不知道,但我认为,相对而言,在两者之间进行选择时,NLog 至少应该得到同等的考虑,并且可能应该是新开发的首选,至少在 log4net 开发显示出更多生命迹象之前。

log4net 和 NLog 都提供了非常灵活的配置选项。它们允许您在日志记录语句的定义中具有非常精细的粒度(通过为每种类型定义记录器的“标准”模式)。它们还允许您开发自己的“日志记录目标”对象(log4net Appender 和 NLog 目标)和“格式化”对象(log4net 模式转换器和 NLog LayoutRenderers),从而轻松扩展库。

除了日志框架的选择之外,一些(很多?)提倡通过使用抽象层将您的应用程序代码与对特定日志框架的硬依赖隔离开来。这可以采用您自己实现的 ILogger 接口的形式,可能在现有框架之上。将来,您可以通过在不同的框架上实现 ILogger 来更改框架。或者,您可以使用 DI/IoC 将“ILogger”注入您的代码。许多 DI/IoC 框架提供了内置的 ILogger 抽象,可以配置为使用 log4net、NLog 或 Enterprise Library,或者您可以编写自己的 ILogger 实现并注入)。谁在乎实现是什么?另一种使您的代码免受对特定日志框架的硬依赖的方法是使用现有的日志抽象框架,例如 Common.Logging 或 SLF。好处是,您的应用程序不依赖于特定的日志记录框架。但是,有些人会说您刚刚将一个依赖项(在日志框架上)换成了另一个(日志抽象框架)。

关于日志抽象的另外两个注意事项:

  1. 一个好的日志抽象应该允许您在同一个输出文件中捕获来自不同日志框架的输出。Common.Logging 将此称为“桥接”。假设您使用 NLog 支持的 Common.Logging 编写了一个应用程序。现在假设您正在使用直接使用 log4net 编写的第三方类库。使用桥接系统,您可以捕获 log4net 输出(通过自定义附加程序)并通过 Common.Logging 重新路由它,以便可以在应用程序日志输出的上下文中查看第三方类库的日志输出。

  2. 使用日志抽象还允许您在开发期间“测试驱动”日志框架。你可能一开始认为 log4net 就是这样,但你想让自己敞开心扉去尝试 NLog。使用日志抽象可以相对容易地在两者之间切换。最终,您可以选择使用哪个日志框架,但与此同时,您已经能够编写大量不依赖于特定日志框架的代码。

您可能会选择一个框架而不是另一个框架的另一个原因是您工作的环境。如果您已经在使用 Enterprise Library 的一部分,那么这可能足以促使您使用 Enterprise Library 日志记录。

如果您在 Silverlight 中进行开发怎么办?您可能会选择使用像Clog 之类的东西 - 钙的一部分。您也可以选择使用与 Silverlight 和 WP7 兼容的 NLog 2.0。

System.Diagnostics 插件(Ukadc.Diagnostics、Essential.Diagnostics)。这些不是日志框架本身。相反,它们表示可以与现有 System.Diagnostics 框架一起使用的有用对象和扩展点的集合。在我看来,这些插件中的每一个添加的最好的事情之一就是能够格式化您的日志输出,类似于使用 log4net 和 NLog 格式化它的方式。我没有用过 Essential.Diagnostics,但是我用 Ukadc.Diagnostics 做了实验,觉得它真的很酷。编写自己的“格式化标记”甚至很容易。

我不知道这是否完全回答了您的问题(无论如何都相当广泛),但我认为这里有很多值得思考的地方。

于 2011-01-23T21:37:43.817 回答
5

我刚开始在 VS2010 中使用 log4net,发现它依赖于 System.Web...这使得它与“.NET xx Client Profile”框架目标不兼容...考虑到这里有人使用 Windows 更新发布的内容客户端配置文件作为 .NET 可再发行组件的选择,这意味着如果您想让代码在大多数机器上运行,log4net 不再是首选的记录器......

感谢您提供有关其他选项的信息 - 我会检查它们...

于 2011-03-02T17:30:05.873 回答
3

只是添加一些从 Microsoft 的 Build 2013 会议中学到的东西:

  • 重负载下的 Log4NET 写入文件主要是因为这个过程是同步的。在某些情况下可能会出现争用和超时。这可以使用 AppDynamics 或任何其他类似工具进行验证。

  • NLog 没有实现排队,所以在负载下,IO 调用会堆积起来。

  • 根据微软的说法,ETW 使用高效的内核环形缓冲区。.NET 4.5 和事件日志框架与语义日志记录应用程序块 (AKA SLAB)相结合将提高效率。

于 2013-08-09T19:14:28.320 回答
1

我不是 log4j 或 log4net 的粉丝。我喜欢 java.util.net 日志工具,因此我在https://github.com/greggwon/NetLog/上名为 NetLog 的 github 项目中重新创建了它。随时提供反馈。我正在尝试花一些时间将基于 ConfigurationManager 的配置放入 liu 的 logging.properties 文件中。使用 java.util.logging,使用命令行属性设置来指定日志配置的位置总是很容易。如果您不使用 ConfigurationManager,使用 .net 会更痛苦。为 CM 提供支持,将为记录器和处理程序之间的一些不同关系打开大门,这可能会使某些事情变得更好。

NetLog 包含一个 EventLogHandler,它将记录到系统事件日志。它还有一个 Level.EventLog 级别设置为略低于“警告”,这将允许您在不使用“警告”或“严重”的情况下针对 EventLog 指定一个名为“级别”。我还有一个 TCPSocketHandler,它可以让你远程登录到“日志”,这样你就可以在 Windows 上有一个“尾巴”,而没有可用的“尾巴”程序。

于 2013-08-08T23:28:46.110 回答
0

看看 GitHub 上的 NetLog.Logging 包,它是我的创作。它有一个监控应用程序,并遵循 java.util.logging API 范例,因为这是我喜欢使用的。它有一个用于访问“写入”的自旋锁,并且锁持有者在继续之前写入所有排队的记录,直到一个限制。这将允许日志记录减少基于争用的 I/O,并提供一个很好的折衷方案。

于 2013-12-30T19:00:32.623 回答
0

出于某种原因,System.Diagnostics 不支持将所有跟踪输出定向​​到单个侦听器的方法。如果您希望将多个源定向到同一个侦听器,则必须按名称显式列出每个源。

在具有许多依赖项的大型系统中,您可能不知道所有源,并且您可能不在乎。您只想让输出看到幕后发生的事情。必须为每个源单独设置侦听器使得在大型系统中使用 System.Diagnostics 变得更加困难。

log4net 不仅支持根级别的附加程序(监听器),它还支持分层日志记录,允许您为一组逻辑源配置日志记录作为一个组。在我看来,这使得 log4net 成为明确的选择。

于 2016-12-14T17:19:13.943 回答