我想了解一下人们在实际应用程序中是如何处理跟踪和日志(log)记录的.这里有一些问题可能有助于解释你的答案.

Frameworks

你使用什么框架?

  • log4net
  • System.Diagnostics.Trace
  • 系统诊断学.TraceSource
  • 日志(log)记录应用程序挡路
  • 另外

如果你使用追踪,你会使用追踪吗.相关性什么手术?

您是手动编写这段代码,还是使用某种形式的面向方面编程来完成这段代码?想分享一段代码片段吗?

您是否提供了任何形式的跟踪源粒度?例如,WPF TraceSources允许您在不同级别配置它们:

  • 系统Windows-settings for all of WPF
  • System.Windows.Animation-override specifically for Animation.

Listeners

你使用什么日志(log)输出?

  • 文本文件
  • XML文件
  • 事件日志(log)
  • 另外

如果使用文件,您是使用滚动日志(log)还是仅使用单个文件?你如何让人们可以使用这些日志(log)?

Viewing

您使用什么工具查看日志(log)?

  • 记事本
  • tail
  • 事件查看器
  • 系统中心运营经理/微软运营经理
  • WCF服务跟踪查看器
  • 另外

如果你正在构建一个ASP.NET解决方案,是否也使用ASP.网络健康监测?是否在运行状况监视器事件中包含跟踪输出?Trace呢.axd?

那么定制性能计数器呢?

推荐答案


Update:用于系统扩展.诊断,提供一些您可能需要的缺失侦听器,请参阅Essential.CodePlex上的诊断(http://essentialdiagnostics.codeplex.com/)


Frameworks

问:你使用什么框架?

A: System.Diagnostics.TraceSource, built in to .NET 2.0.

它为应用程序提供了强大、灵活、高性能的日志(log)记录,但是许多开发人员不知道它的功能,也没有充分利用它们.

在某些领域,附加功能很有用,或者有时该功能存在但没有很好的文档记录,然而,这并不意味着应该丢弃整个日志(log)记录框架(设计为可扩展),并像一些流行的替代方案(NLog、log4net、Common.Logging,甚至EntLib日志(log)记录)那样完全替换它.

与其改变向应用程序中添加日志(log)语句的方式并重新发明轮子,不如扩展系统.在您需要的几个地方使用诊断框架.

在我看来,其他框架,即使是EntLib,也只是患上了Not Created Here综合征,我认为它们浪费了时间,重新发明了在系统中已经运行良好的基础.诊断(例如如何编写日志(log)语句),而不是填补存在的几个空白.简而言之,不要使用它们——它们是不需要的.

Features you may not have known:

  • 使用采用格式字符串和参数的TraceEvent重载可以帮助提高性能,因为参数作为单独的引用保留,直到筛选之后.ShouldTrace()已成功.这意味着在系统确认消息实际被记录之前,不会对参数值调用ToString().
  • 痕迹.CorrelationManager允许您关联关于同一逻辑操作的日志(log)语句(见下文).
  • 视觉的.登录中.FileLogTraceListener适用于写入日志(log)文件,并支持文件旋转.尽管在VisualBasic名称空间中,它也可以简单地通过包含DLL在C#(或其他语言)项目中使用.
  • 使用EventLogTraceListener时,如果使用多个参数和空或空格式字符串调用TraceEvent,则参数将直接传递给EventLog.WriteEntry(),如果您使用的是本地化消息资源.
  • 服务跟踪查看器工具(来自WCF)对于查看与活动相关的日志(log)文件的图形非常有用(即使您没有使用WCF).这确实有助于调试涉及多个线程/活动的复杂问题.
  • 通过清除所有侦听器(或删除默认值)避免开销;否则,默认值会将所有内容传递给跟踪系统(并导致所有这些ToString()开销).

Areas you might want to look at extending (if needed):

  • 数据库跟踪侦听器
  • 彩色控制台跟踪监听器
  • MSMQ/Email/WMI跟踪侦听器(如果需要)
  • 实现FileSystemWatcher以调用Trace.Refresh以进行动态配置更改

Other Recommendations:

使用 struct 化事件id,并保留一个参考列表(例如,在枚举中记录它们).

为系统中的每个(重要)事件提供唯一的事件id对于关联和查找特定问题非常有用.可以很容易地追溯到记录/使用事件ID的特定代码,并且可以很容易地为常见错误提供指导,例如错误5178表示您的数据库连接字符串错误,等等.

事件id应该遵循某种 struct (类似于邮箱和HTTP中使用的回复代码理论),这允许您在不知道特定代码的情况下按类别处理它们.

e、 g.第一位数字可以详细说明一般类别:1xx可用于"启动"操作,2xxx可用于正常行为,3xxx可用于活动跟踪,4xxx可用于警告,5xxx可用于错误,8xxx可用于"停止"操作,9xxx可用于致命错误等.

第二位数字可以详细说明该区域,例如21xx表示数据库信息(41xx表示数据库警告,51xx表示数据库错误),22xx表示计算模式(42xx表示计算警告等),23xx表示另一个模块等.

指定的 struct 化事件id也允许您在筛选器中使用它们.

问:如果你使用追踪,你会使用追踪吗.相关性什么手术?

A: Trace.CorrelationManager is very useful for correlating log statements in any sort of multi-threaded environment (which is pretty much anything these days).

您至少需要 for each 逻辑操作设置一次ActivityId,以便进行关联.

然后,启动/停止和LogicalOperationStack可用于基于堆栈的简单上下文.对于更复杂的上下文(例如异步操作),使用TraceTransfer转换到新的ActivityId(在更改之前),可以进行关联.

服务跟踪查看器工具对于查看活动图很有用(即使您没有使用WCF).

问:您是手动编写代码,还是使用某种形式的面向方面编程来编写代码?想分享一段代码片段吗?

A: You may want to create a scope class, e.g. LogicalOperationScope, that (a) sets up the context when created and (b) resets the context when disposed.

这允许您编写如下代码来自动包装操作:

  using( LogicalOperationScope operation = new LogicalOperationScope("Operation") )
  {
    // .. do work here
  }

在创建时,如果需要,作用域可以首先设置ActivityId,调用StartLogicalOperation,然后记录TraceEventType.Start消息.在Dispose时,它可以记录一条停止消息,然后调用StopLogicalOperation.

问:您是否提供了任何形式的跟踪源粒度?例如,WPF TraceSources允许您在不同级别配置它们.

A: Yes, multiple Trace Sources are useful / important as systems get larger.

虽然您可能希望始终如一地记录所有警告&;以上,或所有信息&;在上面的消息中,对于任何大小合理的系统,活动跟踪(启动、停止等)和详细日志(log)记录的量都会变得太大.

与其只有一个switch 来打开或关闭所有信息,不如一次为系统的一个部分打开这些信息.

通过这种方式,您可以从通常的日志(log)记录中找到重大问题(所有警告、错误等),然后"放大"所需的部分,并将其设置为活动跟踪甚至调试级别.

您需要的跟踪源的数量取决于您的应用程序,例如,您可能希望每个应用程序的每个程序集或每个主要部分都有一个跟踪源.

如果需要更精细的控制,可以添加单独的布尔switch 来打开/关闭特定的大容量跟踪,例如原始消息转储.(或者可以使用单独的跟踪源,类似于WCF/WPF).

您可能还需要考虑活动跟踪与一般(其他)日志(log)记录的单独跟踪源,因为它可以更容易配置过滤器,而不是您想要它们.

请注意,即使使用不同的源,消息仍然可以通过ActivityId进行关联,因此可以根据需要使用任意数量的消息.


听众

Q: What log outputs do you use?

这可能取决于您正在编写的应用程序的类型,以及正在记录的内容.通常不同的东西放在不同的地方(即多个输出).

我通常将输出分为三类:

(1) Events - Windows Event Log (and trace files)

例如,如果编写服务器/服务,则Windows上的最佳实践是使用Windows事件日志(log)(您没有要报告的UI).

在这种情况下,所有致命、错误、警告和(服务级别)信息事件都应写入Windows事件日志(log).信息级别应该保留给这些类型的高级事件,即您想要记录在事件日志(log)中的事件,例如"服务已启动"、"服务已停止"、"已连接到XYZ",甚至可能还有"计划启动"、"用户登录"等.

在某些情况下,您可能希望将写入事件日志(log)作为应用程序的内置部分,而不是通过跟踪系统(即直接写入事件日志(log)条目).这意味着它不会被意外关闭.(注意,您仍然希望在跟踪系统中记录相同的事件,以便进行关联).

相反,Windows GUI应用程序通常会将这些情况报告给用户(尽管它们也可能记录到Windows事件日志(log)).

事件还可能具有相关的性能计数器(例如,每秒的错误数),协调任何直接写入事件日志(log)、性能计数器、写入跟踪系统并向用户报告以使它们同时发生可能很重要.

i、 e.如果用户在特定时间看到错误消息,您应该能够在Windows事件日志(log)中找到相同的错误消息,然后在跟踪日志(log)中找到具有相同时间戳的相同事件(以及其他跟踪详细信息).

(2) Activities - Application Log files or database table (and trace files)

这是系统执行的常规活动,例如,提供网页、提交股票市场交易、接受订单、执行计算等.

活动跟踪(开始、停止等)在这里很有用(在右边).

此外,使用特定的应用程序日志(log)(有时称为审核日志(log))也很常见.通常这是一个数据库表或应用程序日志(log)文件,包含 struct 化数据(即一组字段).

根据您的应用程序的不同,这里的情况可能会变得有点模糊.一个很好的示例可能是将每个请求写入Web日志(log)的Web服务器;类似的示例可能是消息传递系统或计算系统,其中记录每个操作以及特定于应用程序的详细信息.

一个不太好的例子是股票市场交易或销售订单系统.在这些系统中,您可能已经在记录活动,因为它们具有重要的业务价值,但是将它们与其他操作关联的原则仍然很重要.

除了自定义应用程序日志(log),活动通常还具有相关的性能计数器,例如每秒的事务数.

通常,您应该协调不同系统之间的活动日志(log)记录,即在增加性能计数器的同时写入应用程序日志(log),并将日志(log)记录到跟踪系统中.如果您同时执行所有操作(或在代码中紧随其后),那么调试问题就更容易了(而不是在代码中的不同时间/位置出现问题).

(3) Debug Trace - Text file, or maybe XML or database.

这是详细级别和更低级别的信息(例如,用于打开/关闭原始数据转储的自定义布尔switch ).这提供了系统在子活动级别所做工作的勇气或细节.

这是您希望能够为应用程序的各个部分(因此是多个源)打开/关闭的级别.你不希望这些东西把Windows事件日志(log)弄得乱七八糟.有时会使用数据库,但更有可能是在一段时间后清除的滚动日志(log)文件.

此信息与应用程序日志(log)文件之间的一大区别在于它是非 struct 化的.虽然应用程序日志(log)可能有To、From、Amount等字段,但详细的调试跟踪可能是程序员输入的任何内容,例如"checking values X={value},Y=false",或随机注释/标记,如"Done it,trytime".

一个重要的实践是确保应用程序日志(log)文件或Windows事件日志(log)中的内容也以相同的细节(例如时间戳)记录到跟踪系统中.这允许您在调查时关联不同的日志(log).

如果由于具有复杂的相关性而计划使用特定的日志(log)查看器,例如服务跟踪查看器,则需要使用适当的格式,即XML.否则,一个简单的文本文件通常就足够了——在较低的级别上,信息基本上是非 struct 化的,因此您可能会发现数组转储、堆栈转储等.如果您可以在较高的级别上关联回更多 struct 化的日志(log),事情应该会好起来.

Q: If using files, do you use rolling logs or just a single file? How do you make the logs available for people to consume?

答:对于文件,通常您希望从可管理性的Angular 滚动日志(log)文件(使用System.Diagnostics只需使用VisualBasic.Logging.FileLogTraceListener).

可用性同样取决于系统.如果你只谈论文件,那么对于服务器/服务来说,滚动文件可以在必要时访问.(Windows事件日志(log)或数据库应用程序日志(log)将有自己的访问机制).

如果无法轻松访问文件系统,那么调试跟踪数据库可能会更容易.[即,实现一个数据库TraceListener].

我在Windows GUI应用程序中看到的一个有趣的解决方案是,它在运行时将非常详细的跟踪信息记录到"飞行记录器"中,然后当你关闭它时,如果没有问题,它只会删除文件.

但是,如果它崩溃或遇到问题,则该文件不会被删除.如果它捕捉到错误,或者下次运行时,它会注意到该文件,然后它可以采取措施,例如压缩它(例如7zip)并通过邮箱发送,或者以其他方式使其可用.

如今,许多系统将故障的自动报告整合到中央服务器上(在与用户进行判断后,例如出于隐私原因).


观看

Q: What tools to you use for viewing the logs?

答:如果出于不同原因有多个日志(log),那么您将使用多个查看器.

Notepad/vi/Notepad++或任何其他文本编辑器是纯文本日志(log)的基础.

如果您有复杂的操作,例如带有转移的活动,那么很明显,您将使用像服务跟踪查看器这样的专用工具.(但如果您不需要它,那么文本编辑器会更容易).

由于我通常会将高级信息记录到Windows事件日志(log)中,因此它提供了一种以 struct 化方式获取概述的快速方法(查看漂亮的错误/警告图标).如果日志(log)中没有足够的内容,只需要开始搜索文本文件,尽管至少日志(log)为您提供了一个起点.(在这一点上,确保日志(log)具有协调的实体变得很有用).

通常,Windows事件日志(log)也使这些重要事件可用于MOM或OpenView等监控工具.

Others --

如果登录到数据库,可以很容易地筛选和排序信息(例如放大特定的活动id.(对于文本文件,可以使用Grep/PowerShell或类似工具来筛选所需的部分GUID)

MS Excel(或其他Electron 表格程序).如果可以使用正确的分隔符导入 struct 化或半 struct 化信息,以便在不同的列中输入不同的值,那么这对于分析 struct 化或半 struct 化信息非常有用.

在调试/测试中运行服务时,为了简单起见,我通常将其托管在控制台应用程序中.我发现彩色控制台记录器非常有用(例如,红色表示错误,黄色表示警告等).您需要实现一个自定义跟踪侦听器.

请注意,该框架不包括彩色控制台记录器或数据库记录器,因此,如果需要,您现在需要编写它们(这并不太难).

有几个框架(log4net、EntLib等)浪费时间重新发明轮子,并重新实现了基本的日志(log)记录、过滤,以及对文本文件、Windows事件日志(log)和XML文件的日志(log)记录,每个框架都有各自不同的方式(日志(log)语句各不相同),这让我非常恼火;然后,每一个都实现了自己版本的数据库记录器,例如,其中大部分已经存在,所需要的只是为系统提供更多的跟踪侦听器.诊断学.谈论重复努力的巨大浪费.

Q: If you are building an ASP.NET solution, do you also use ASP.NET Health Monitoring? Do you include trace output in the health monitor events? What about Trace.axd?

这些功能可以根据需要打开/关闭.我发现Trace.axd对于调试服务器如何响应某些事情非常有用,但在频繁使用的环境或长期跟踪中通常不太有用.

Q: What about custom performance counters?

对于专业应用程序,特别是服务器/服务,我希望看到它完全配备了性能监视器计数器并记录到Windows事件日志(log)中.这些是Windows中的标准工具,应该使用.

您需要确保为您使用的性能计数器和事件日志(log)包含安装程序;这些应该在安装时创建(以管理员身份安装时).当应用程序正常运行时,它不需要具有管理权限(因此将无法创建丢失的日志(log)).

这是练习以非管理员身份开发的一个很好的理由(当您需要安装服务时,有一个单独的管理员帐户,等等).如果写入事件日志(log).NET将在您第一次写入时自动创建丢失的日志(log);如果你以非管理员的身份开发,你会很早发现这一点,并避免当客户安装了你的系统,然后因为他们不是以管理员的身份运行而无法使用时,你会感到意外.

Asp.net相关问答推荐

Dotnet core 2.0 身份验证多模式身份 cookie 和 jwt

IE10 SCRIPT5009:__doPostBack未定义

HttpResponse 的区别:SetCookie、AppendCookie、Cookies.Add

如何判断 IIS 是处于 32 位还是 64 位模式

如何在 Kendo UI 中获取下拉列表中选定项目的文本?

在 C# 中将 IHtmlContent/TagBuilder 转换为字符串

从 C# AsyncCTP 使用 ExecuteReaderAsync 的任何缺点

带有邮箱地址参数的 WebApi 方法从 HttpClient 返回 404

对于每个请求,RestClient 应该是单例还是新的

会话变量保存在哪里?

如何获取 ActionLink 的工具提示?

您如何在 .net WebApi2 应用程序中的 OAuth2 令牌请求中使用额外参数

如何在实体框架中添加表?

IISExpress 找不到使用 Visual Studio 2013 运行 localhost 的 ssl 页面

ASP.NET Excel 导出编码问题

盒式磁带包与 MVC4 包

在 ASP.NET MVC 中模拟 User.Identity

x-powered by是什么意思?

您可以从 web.config 文件中的其他位置提取 log4net AdoNetAppender 的 connectionString 吗?

您的下一个 ASP.NET 项目的 Select 是什么:Web 窗体还是 MVC?