System.Diagnostics.Debug 命名空间与其他日志记录解决方案(log4net、MS Enterprise Library 等)

2024-01-28

我目前正在研究 .net 项目的各种日志记录可能性,但我无法在 System.Diagnostics.Debug/Trace 功能和第三方库(如 log4net、MS Enterprise Library、NLog 等)之间做出决定。
目前我已经发现了这一点:

  • System.Diagnostics 的配置和使用相当困难,因为您需要显式配置所有侦听器、过滤器、源等。似乎它也缺乏对数据库的批量插入(考虑每个日志条目写入 100,000 个日志条目)它自己的插入,可怕,不是吗?)。但有些人认为不使用额外的库来实现诸如日志记录之类的“基本”功能是“很酷”的(当然,在某些时候,减少项目依赖的第三方库的数量是有意义的,但我想这次不是)
  • 第 3 方更强大,通常更快,更容易使用,但配置有时也可能很痛苦,而且这些库通常不太可靠(例如 EntLib 神秘地突然停止日志记录等)
  • Common.Logging 怎么样?是否值得尝试(因为据我所知,它提供了插入各种日志框架并充当应用程序和所需库之间的接口)?


如果有人能为我指出正确的方向或纠正(或添加一些内容)上面给出的比较,我将非常感激!也许如果您鼓励我使用第三方,您可以建议一些特定的第三方(考虑到我们的应用程序很可能不需要任何花哨的东西,如 UDP、滚动文件等 - 只需纯文件、电子邮件、数据库和事件日志)?
提前致谢!


您可以在 StackOverflow 上通过更广泛的谷歌搜索找到大量有关 log4net 和 NLog 的信息。

您还可以找到很多有关 System.Diagnostics 的信息。关于 System.Diagnostics 需要注意的一件事是,我认为您会在 StackOverflow 上找到很多有关使用 Debug.Write/WriteLine 和 Trace.Write/WriteLine 的参考资料。可以说“更好”的方法是使用 TraceSources。 TraceSources 类似于 log4net 和 NLog 中的记录器。 TraceSources 允许您对日志消息有更高的粒度,从而更容易地打开和关闭一些日志记录(除了按级别之外,还按类别或类别)。与 log4net 和 NLog 相比,TraceSource 确实有一个缺点,即您在代码中创建的每个 TraceSource 都必须在 app.config 中显式配置(如果您希望它实际记录)。

log4net 和 NLog 有一个分层概念,如果您请求的确切记录器未明确配置,则会检查其“祖先”以查看是否配置了任何“祖先”,如果配置了,则请求的记录器“继承”这些设置。祖先只是记录器名称中由“.”分隔的部分。 (因此,如果您请求一个名为"ABC.DEF.GHI",祖先将是"ABC.DEF", and "ABC")。也可以(必需?)在 app.config 中有一个“根”记录器配置,如果未显式配置且未配置祖先,则所有记录器请求都将回退到该配置。因此,您可以仅配置一个“根”记录器以在特定级别进行记录,并且代码中的所有记录器都将在该级别进行记录。或者,您可以将“根”记录器配置为“关闭”,然后显式打开一个或多个记录器(或通过配置祖先)。通过这种方式,除了那些已配置的记录器之外,没有记录器会记录日志。

如果你看here https://github.com/castleproject/Core/blob/master/src/Castle.Core/Core/Logging/TraceLogger.cs,您会发现 System.Diagnostics TraceSources 周围有一个有趣的包装器,它提供了与 log4net 和 NLog 非常相似的继承功能。

为了显示:

log4net 和 NLog 中记录器的常见使用模式是获取如下记录器:

//log4net
static ILog logger = LogManager.GetLogger(
                     System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 

//NLog
static Logger logger = LogManager.GetCurrentClassLogger();

在这两种情况下,记录器的名称都将是完全限定的类型名称。

在 app.config 文件中,如果需要,您可以仅配置“根”记录器,并且两个记录器都将继承根记录器的设置(级别、附加程序/目标等)。或者,您可以为某些名称空间配置记录器。在该命名空间中定义类型的任何记录器都将继承这些记录器设置。

log4net 和 NLog 已经讲够了,您可能已经知道它们是如何工作的。

上面的链接说明了一个基于 TraceSource 的包装器,它允许类似的配置。所以,如果你愿意,你可以在课堂上做这样的事情:

static TraceSource ts = new TraceSource(
               System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

使用上面链接的包装器,您可以在更高级别(类/命名空间层次结构,而不是级别)配置 TraceSource 并继承较低级别记录器中的这些设置。

因此,如果您的完全限定类型名称类似于:ABC.DEF.GHI,那么您可以为 ABC 或 ABC.DEF(命名空间级别)配置 TraceSource,并且类“GHI”将继承这些设置。这确实可以减少您必须执行的配置量。

请注意,您不限于(使用任何这些日志记录平台)使用类的类型或类型名称来获取记录器。您可以定义自己的记录器命名方案,可能基于功能区域(“通信”、“通信.发送”、“通信.接收”等)。同样,您可以以最高粒度(或不是最高粒度)请求记录器/TraceSource,然后以任何有意义的粒度级别进行配置。

因此,您可以在代码中请求记录器,如下所示:

ILog logger = LogManager.GetLogger("Communication.Receive");
ILog logger = LogManager.GetLogger("Communication.Send");

Logger logger = LogManager.GetLogger("Communication.Receive");
Logger logger = LogManager.GetLogger("Communication.Send");

TraceSource ts = new TraceSource("Communication.Receive");
TraceSource ts = new TraceSource("Communication.Send");

如果您在 app.config 文件中仅配置“通信”,则所有记录器都将继承这些设置(因为它们是“通信”的后代)。如果仅配置“Communication.Receive”,则仅“Communication.Receive”记录器会进行记录。 “通信.发送”记录器将被禁用。如果同时配置“Communication”和“Communication.Receive”,则“Communication.Receive”记录器将在“Communication.Receive”设置中记录,而“Communication.Sender”记录器将在“Communication”设置中记录。在 log4net 和 NLog 中,继承的内容可能不止这些,但我了解的还不够多,无法深入探讨。

使用 System.Diagnostics 时您错过的一件事是非常轻松地格式化日志输出格式的灵活性。有一个第三方库为基于 TraceSource 的日志记录提供了非常好的可配置格式。你可以找到它here http://ukadcdiagnostics.codeplex.com/.

我用过通用日志记录 http://netcommon.sourceforge.net/一些。主要用于原型设计,但我可能会在下一个项目中使用它。它工作得很好,并且编写自己的日志记录抽象来插入它相对容易(例如,如果您想编写类似于我上面链接的 TraceSource 抽象)。 Common.Logging 目前缺少的两个重要内容(尽管他们的网站称它们计划在“下一个”版本中发布)是日志记录上下文(例如 log4net 和 NLog NDC/MDC/GDC 对象以及 System.Diagnostics.CorrelationManger.LogicalOperationStack) )和 Silverlight 兼容性。使用 Common.Logging 时,您仍然可以与代码中的 log4net 或 NLog 上下文对象进行交互,但这违背了它的目的,不是吗?

不知道有没有帮到你!

以下是我对 log4net、NLog 和 TraceSource 的一些要点:

log4net - 非常流行,可能需要一些更新 - 至少是基于 .NET 4.0 构建的,最后一次发布是在几年前,非常灵活。

NLog - 在很多方面与 log4net 非常相似,现在是新版本(NLog 2.0 的测试版刚刚发布)

TraceSource - 没有第三方依赖性,无需您(或某人)付出任何努力,不像 log4net 或 NLog 那样强大(关键缺陷 - 记录器层次结构、输出格式 - 都可以通过上面的链接轻松寻址),Microsoft 检测了它们的许多组件使用 System.Diagnostics,这样您就可以获得 Microsoft 的日志输出和您的日志输出交错。 (通常,在其他日志系统中捕获 System.Diagnostics 很容易,因此可能不是大问题)。

虽然我没有经常使用 log4net 或 NLog,但在两者之间我会倾向于 NLog,主要是因为刚刚发布的新版本(测试版)。我认为 TraceSource 也是一个合理的(如果更基本的)选择,特别是如果您实现记录器层次结构并使用上面链接的 Ukadc.Diagnostics 库。

或者,使用 Common.Logging,您可以避免或延迟为底层日志记录平台做出决定,直到您准备好为止。无论如何,对我来说,Common.Logging 的一个非常有用的方面是,您可以在开发产品时“测试驱动”日志平台,而无需更改任何应用程序代码。您不必等到决定使用特定的日志记录平台才能将日志记录添加到代码中。现在通过 Common.Logging api 添加它。当您接近交付时,您应该缩小日志平台的选择范围。使用该平台进行交付(如果您重新分发日志记录平台),就完成了。如果您愿意,以后仍然可以更改。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

System.Diagnostics.Debug 命名空间与其他日志记录解决方案(log4net、MS Enterprise Library 等) 的相关文章

  • 如何 XML 序列化 DateTimeOffset 属性?

    The DateTimeOffset当数据表示为 Xml 时 我在此类中拥有的属性不会呈现 我需要做什么来告诉 Xml 序列化将其正确呈现为DateTime or DateTimeOffset XmlRoot playersConnecte
  • Lightspeed 与 NHibernate

    有什么体验光速 http www mindscape co nz products LightSpeed comparison aspx Mindscape 提供的比较并没有过多说明 NHibernate Lightspeed 看起来很灵活
  • CLSCompliant(true) 拖入未使用的引用

    任何人都可以explain以下行为 总之 如果您创建多个符合 CLS 标准Visual Studio 2008 中的库并让它们共享公共命名空间根 引用另一个库的库将require对该库的引用的引用 即使它不消耗它们 用一句话来解释是相当困难
  • C# 中 DLL 和命名空间的关系

    这里有一个高级问题 今天我花了很多时间自学基本的高级概念 例如 API 静态和动态库 DLL 以及 C 中的编组 获得所有这些知识让我想到了一个看起来非常基本的问题 并且可能表明我对这些概念的理解存在漏洞 我知道的 DLL 可能包含类 这些
  • 如果.Net Core可以在Windows上运行,为什么不能在.Net Framework中引用.Net Core DLL?

    我明白为什么 Net Framework 可能会在 Net Core IE 中导致问题 因为不存在特定于 Windows 平台的 API 但是为什么不能直接引用 Net Core 作为 Net Framework 中的库呢 如果 Net C
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • 为什么密码错误会导致“填充无效且无法删除”?

    我需要一些简单的字符串加密 所以我编写了以下代码 有很多 灵感 来自here http www codeproject com KB security DotNetCrypto aspx create and initialize a cr
  • 从 Orchard 内的主题渲染图像

    我刚刚选择 Orchard 来构建我的博客 作为创建这个新博客的努力的一部分 我正在创建一个自定义主题 这个自定义主题同时具有 CSS 和图像 我的问题 我的问题基本上可以归结为 如何渲染属于主题一部分的图像 到目前为止我已经尝试过的 我尝
  • 哪些属性有助于运行时 .Net 性能?

    我正在寻找可用于通过向加载器 JIT 编译器或 ngen 提供提示来确保 Net 应用程序获得最佳运行时性能的属性 例如我们有可调试属性 http msdn microsoft com en us library k2wxda47 aspx
  • .NET UI 元素线程限制的原因

    我们知道 除了实例化元素的线程之外 不可能从任何线程执行操作任何 UI 元素属性的代码 我的问题是 为什么 我记得当我们使用 COM 用户界面元素时 在 COM Visual Basic 6 0 时代 所有 UI 元素都是使用 COM 类和
  • 限制对记录的访问。基于声明的权限是个好主意吗

    在 net 基于声明的身份框架中 如果我想限制用户对某个帐户 特定帐户 123456 执行操作 查看或编辑 我说的是商业实体 例如银行帐户 创建索赔是个好主意吗对于他们可以查看或编辑的每个帐户 一组中有很多索赔有什么缺点吗 系统管理员可能有
  • 将 Xml 反序列化为对象时出错 - xmlns='' 不是预期的

    我在尝试反序列化某些 XML 时遇到了真正的麻烦 希望有人可以提供一些帮助 我读过很多类似的帖子 但我无法解决这个问题 我正在尝试反序列化 XML
  • 为什么即使当我尝试从工作线程更改 UI 时,同步上下文仍为空?为什么即使我不这样做,工作线程也会在 UI 线程上等待?

    我在表单上有一个按钮 点击它我调用FooAsync并在完成时阻止 UI 线程 下面是代码和我的问题 using System using System Diagnostics using System Threading using Sys
  • 是否可以调整AppFabric缓存服务器来存储更大的对象?

    当我假设将较大的对象图添加到缓存中时 我收到 AppFabric 缓存服务器错误 错误代码 子状态 连接已终止 可能是由于服务器或网络问题或序列化对象大小大于服务器上的 MaxBufferSize 请求的结果未知 我确信这不是网络问题 我能
  • 如何在Web网格的列中编写IF条件

    我在 WEB GRID 列中创建 if 条件时遇到错误 所以 请帮助改进我的代码并解决我的问题 grid Column Status format item gt
  • 删除 TableLayoutPanel 中的特定行

    我有 TableLayoutPanel 我以编程方式添加行 用户基本上选择一个属性 然后与一些控件一起显示在表中 我想我在这里有一个一般性的理解问题 我会尽力解释它 每行中的控件之一是 删除 按钮 该按钮应该删除它所在的行 我所做的是将事件
  • 如何检查 NTAccount 对象代表组还是用户?

    使用返回的访问规则时 GetAccessRules True True GetType System Security Principal NTAccount 如何判断每个规则中引用的 NTAccount 对象是用户帐户还是组 Update
  • 获取按下的按钮的返回值

    我有一个在特定事件中弹出的表单 它从数组中提取按钮并将标签值设置为特定值 因此 如果您要按下或单击此按钮 该函数应返回标签值 我怎样才能做到这一点 我如何知道点击了哪个按钮 此时代码返回 DialogResult 但我想从函数返回 Tag
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的

随机推荐

  • 如何/在哪里使用 NSNumberFormatter?

    我是代码新手 在查看了一些答案后仍然需要帮忙 在我的代码中 func labelInformation numLabels text newLabel text 当前结果 228500 23 期望的结果 228 500 23 如何 在哪里使
  • 短信收件箱中对联系人表的错误引用

    我正在尝试从手机的短信收件箱中查找与短信相对应的联系方式 据我了解person列是外键 id的列ContactsContract Contacts 我的问题是我得到了错误的值person来自短信查询的值 一些person联系人表中不存在 I
  • 静态变量还是通过 Bundle 传递变量? [复制]

    这个问题在这里已经有答案了 假设我有一个 ListView 并在列表上设置了一个 OnItemClickListener 传递变量的最佳方式是什么 静态变量 public static String example onItemClick
  • 由于 teamcity,pycharm 调试控制台不可读

    几天以来 我的 pycharm 调试控制台被 teamcity 信息系统性地污染了 例如当我想打印出变量值时 将显示以下内容 gt gt gt df teamcity testStdOut timestamp 2017 11 02T15 5
  • 我希望能够使用故事板左右滚动 UITableViewCell。这不可能吗?

    我已经尝试了所有我能想到的方法 但没有任何效果 与 iOS 7 的 Mail app 中的效果类似 我希望能够左右滑动表格视图的单元格 我希望能够在情节提要和自动布局中执行此操作 因为我的大部分应用程序都是使用这些完成的 我理解带有故事板的
  • 将 WebRTC (AudioTrackSinkInterface) 原始音频写入光盘

    我正在尝试录制 WebRTC 传输的音频PeerConnection MediaStream 我在音轨中添加了一个接收器 它实现了AudioTrackSinkInterface 它实现了OnData method void TestAudi
  • 确定 C# 中的调用对象类型

    不管这是否是一个好主意 是否可以实现一个接口 其中执行函数知道调用对象的类型 class A private C public int doC int input return C DoSomething input class B pri
  • JPA 实体管理器 - 如何运行 SQL 脚本文件?

    我有一个 SQL 脚本文件 它删除并重新创建各种表以及将各种记录插入到这些表中 该脚本在 SQL 查询控制台中执行时运行良好 但我需要它由实体管理器执行 关于我如何能够做到这一点有什么想法吗 Thanks H 参加聚会迟到了 但我是这样做的
  • Laravel 为资源控制器命名路由

    使用 Laravel 4 2 是否可以为资源控制器路由分配名称 我的路线定义如下 Route resource faq ProductFaqController 我尝试向路线添加名称选项 如下所示 Route resource faq Pr
  • 专家 R 用户,您的 .Rprofile 中有什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 为什么 Flink 在 DataStream join + Global window 上发出重复记录?

    我正在学习 试验 Flink 并且观察到 DataStream 连接的一些意外行为 并且想了解发生了什么 假设我有两个流 每个流有 10 条记录 我想将其加入到id场地 假设一个流中的每条记录在另一个流中都有一个匹配的记录 并且 ID 在每
  • Matlab:“分组平均值”

    假设我有向量 y 1 1 01 1 02 1 03 2 2 01 2 02 3 3 01 3 02 3 03 c 0 0 0 0 1 1 1 2 2 2 2 有没有一种矢量化的方法来获得 分组平均值 即平均值y对于每个唯一值c 这是一个简化
  • 为什么 Pip 忽略具有嵌套依赖项的配置存储库?

    Problem 假设我在 Linux 机器上有一个完全空的 Python Pip R pip 19 3 1 环境 并且我想安装该包rpy2与点 由于我位于公司防火墙后面 因此我将 pip 配置为使用私有存储库 global index ur
  • flutter 从文件路径打开图像

    我在用image picker从图库中获取一些图像 我将图像的路径保存在列表中 例如 private var mobile Containers Data Application E633FB78 77D3 4913 B37A 496BFB
  • 如何使用返回http承诺的Angular 2服务

    我在这里遇到了 Angular 2 的问题 我使用返回承诺的服务 但是当我尝试检索响应时出现错误 我读到了这个这个静态问题 https stackoverflow com questions 40009397 angular 2 http
  • Spark on 纱线概念理解

    我试图了解 Spark 如何在 YARN 集群 客户端上运行 我心里有以下问题 是否需要在yarn集群的所有节点上都安装spark 我认为应该是因为集群中的工作节点执行任务并且应该能够解码由驱动程序发送到集群的 Spark 应用程序中的代码
  • C# 将 datagridview 绑定到表单与控件中的数据表

    我有以下代码 DataGridView lGrid new DataGridView BindingSource bind new BindingSource DataTable Table new DataTable this Contr
  • 在C++中将派生类指针分配给基类指针

    我有以下 class base class derived public base public derived void myFunc cout lt lt My derived function lt lt std endl 我现在有
  • 在 Next.js 中设计持久布局

    我正在经历this https adamwathan me 2019 10 17 persistent layout patterns in nextjs 文章 我试图弄清楚在选项 4 中持久性应该如何发生 据我所知 您需要为每个页面重新定
  • System.Diagnostics.Debug 命名空间与其他日志记录解决方案(log4net、MS Enterprise Library 等)

    我目前正在研究 net 项目的各种日志记录可能性 但我无法在 System Diagnostics Debug Trace 功能和第三方库 如 log4net MS Enterprise Library NLog 等 之间做出决定 目前我已