我想了解人们如何处理实际应用程序中的跟踪和记录。以下是一些可能有助于解释您的答案的问题。
框架
您使用哪些框架?
如果使用跟踪,是否使用了Trace.Correlation.StartLogicalOperation?
您是手动编写此代码,还是使用某种形式的面向方面编程来执行此操作?小心共享代码片段?
您是否在跟踪源上提供任何形式的粒度?例如,WPF TraceSources允许您在不同级别配置它们:
监听
您使用什么日志输出?
如果使用文件,您使用滚动日志还是仅使用单个文件?如何使日志可供人们使用?
查看
您可以使用哪些工具查看日志?
如果要构建ASP.NET解决方案,是否还使用ASP.NET Health Monitoring?您是否在运行状况监视器事件中包含跟踪输出?那么Trace.axd呢?
自定义性能计数器怎么样?
答案 0 :(得分:232)
答案 1 :(得分:40)
我必须加入推荐log4net的合唱团,在我的情况下来自平台灵活性(桌面.Net / Compact Framework,32/64-bit)的观点。
但是,将其包装在私有标签API中是主要反模式。 log4net.ILogger
已经是Commons Logging包装器API的.Net对应物,因此已经为您最小化了耦合,并且由于它也是一个Apache库,因此通常不会引起关注“不要放弃任何控制:如果必须的话,请把它分开。”
我见过的大多数房屋包装工具库也会犯下一连串的错误:
Exception
参数,导致多个问题:
ILayout
装饰器,可以对异常执行详细的深入分析,以确定事件链。IsLevelEnabled
属性,这会在关闭区域或级别的日志记录时放弃跳过格式化代码的功能。答案 2 :(得分:18)
我不经常在asp.net中开发,但是当涉及到伐木工时,我认为很多最佳实践都是通用的。以下是我多年来学习的一些关于伐木的随机想法:
</xxx>
标记的情况下关闭电源开关,则您的日志会被破坏。-- Invoking Class: com.foocorp.foopackage.FooClass:9021 SELECT * FROM foo;
This is my logging statement - Repeated 100 times
答案 3 :(得分:17)
我没有资格评论.Net的日志记录,因为我的面包和黄油是Java,但是我们在过去8年中的日志记录中有一个迁移,你可能会发现你的问题有用的类比。 / p>
我们开始使用JVM中每个线程使用的Singleton记录器,并设置整个过程的日志记录级别。如果我们不得不调试系统的一个非常特定的部分,这会产生巨大的日志,所以第一课就是分割你的日志。
我们目前的记录器版本允许多个实例定义为默认值。我们可以实例化具有不同日志记录级别的任意数量的子记录器,但是该体系结构最有用的方面是只需更改日志记录属性即可为各个包和类创建记录器。第二课是创建一个灵活的系统,允许在不改变代码的情况下覆盖其行为。
我们正在使用围绕Log4J的Apache commons-logging库。
希望这有帮助!
*编辑*
在阅读下面的Jeffrey Hantin的帖子之后,我意识到我应该注意到我们的内部日志包装器实际上已经变成了什么。它现在基本上是一个工厂,并且严格用于使用正确的属性文件(由于遗留原因尚未移动到默认位置)来获取工作记录器。由于您现在可以在命令行上指定日志记录配置文件,我怀疑它会变得更加精简,如果您正在启动一个新的应用程序,我肯定会同意他的说法,即您甚至不应该费心包装记录器。 / p>
答案 4 :(得分:9)
我们使用Log4Net作为日志记录提供程序,使用日志实例的单例包装器(尽管单例正在审核中,质疑它们是否是个好主意。)
我们选择它的原因如下:
我应该提一下,这是从ASP.NET开发的角度来看
我可以看到使用.NET框架中的Trace的一些优点,但我并没有完全出售它,主要是因为我使用的组件并没有真正做任何Trace调用。我经常使用的唯一一件事是System.Net.Mail
,我可以告诉你。
所以我们有一个包装log4net的库,在我们的代码中我们只需要这样的东西:
Logger.Instance.Warn("Something to warn about");
Logger.Instance.Fatal("Something went bad!", new Exception());
try {
var i = int.Parse("Hello World");
} catch(FormatException, ex) {
Logger.Instance.Error(ex);
}
在这些方法中,我们检查日志级别是否已启用,因此您没有对log4net API进行冗余调用(因此,如果未启用Debug,则会忽略调试语句),但是当我得到一些时间我会更新它以暴露那些,这样你就可以自己做检查。这将阻止在不应该进行评估时进行评估,例如:
Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);
这将成为:
if(Logger.DebugEnabled) Logger.Instance.Debug(string.Format("Something to debug at {0}", DateTime.Now);
(节省一点时间)
默认情况下,我们会在两个位置登录:
文件以每天滚动或10mb(IIRC)的形式完成。我们不使用EventLog,因为它可能需要比我们通常想要提供站点更高的安全性。
我发现Notepad在阅读日志时效果很好。
答案 5 :(得分:8)
您使用哪些框架?
我们使用日志应用程序块的混合,以及围绕.Net框架位工作的自定义日志记录助手。 LAB配置为输出相当广泛的日志文件,包括用于服务方法进入/退出的单独的常规跟踪文件以及用于意外问题的特定错误文件。配置包括调试帮助的日期/时间,线程,pId等,以及完整的异常详细信息和堆栈(如果出现意外异常)。
自定义日志记录助手使用Trace.Correlation,在登录WF的上下文中特别方便。例如,我们有一个调用一系列顺序工作流的状态机。在每个调用活动中,我们记录开始(使用StartLogicalOperation),然后在最后我们使用gereric返回事件处理程序停止逻辑操作。
在尝试调试复杂业务序列中的故障时,这已被证明有用几次,因为它允许我们根据活动执行顺序更快地确定If / Else分支决策等内容。
您使用了哪些日志输出?
我们使用文本文件和XML文件。文本文件是通过app块配置的,但我们也从WF服务获得了XML输出。这使我们能够捕获运行时事件(持久性等)以及通用业务类型异常。文本文件是按日期和大小滚动的滚动日志(我相信总大小为1MB是翻转点)。
您可以使用哪些工具查看日志?
我们正在使用记事本和WCF服务跟踪查看器,具体取决于我们正在查看的输出组。如果您的输出设置正确并且可以使输出读取更简单,那么WCF服务跟踪查看器非常方便。也就是说,如果我大致知道错误的位置 - 只需读取带注释的文本文件也是好的。
将日志发送到单个目录,然后根据源服务将其拆分为子目录。根目录通过一个网站公开,该网站的访问权限由支持用户组控制。这使我们可以查看生产日志,而无需提交请求并对生产数据进行冗长的繁文缛节流程。
答案 6 :(得分:6)
作为该工具的作者,我们当然使用SmartInspect来记录和跟踪.NET应用程序。我们通常使用命名管道协议进行实时日志记录,并将(加密)二进制日志文件用于最终用户日志。我们使用SmartInspect控制台作为查看器和监视工具。
实际上有很多针对.NET的日志框架和工具。对DotNetLogging.com上的不同工具进行了概述和比较。
答案 7 :(得分:5)
答案中有很多很棒的建议。
一般的最佳做法是考虑谁将阅读日志。在我的情况下,它将是客户端站点的管理员。所以我记录的消息给了他们可以采取行动的东西。例如,“无法初始化应用程序。这通常是由......”引起的。
答案 8 :(得分:1)
我们在网络应用程序上使用log4net。
当应用程序在运行时出现故障并且您需要查看更多信息时,通过更改XML配置文件来在运行时自定义日志记录非常方便。
它还允许您定位特定的类或属性以进行登录。当您知道错误发生的位置时,这非常方便。一个典型的例子是NHibernate,你只想看到进入数据库的SQL。
编辑:
我们将所有事件都写入数据库和Trace系统。我们用于错误或异常的事件日志。我们将大多数事件记录到数据库中,以便我们可以创建自定义报告,并让用户查看日志,如果他们想要直接从应用程序。
答案 9 :(得分:1)
就面向方面的日志记录而言,我在另一个问题上推荐了PostSharp -
Aspect Oriented Logging with Unity\T4\anything else
如果您正在评估日志框架,那么答案中提供的链接值得访问。