我正在使用
在阅读和测试后,我对这种错误日志记录方法的可靠性表示担忧,特别是关于事件丢失或缺失的可能性。如果我的错误日志记录不起作用,我需要应用程序关闭(在我的情况下,它运行未报告的错误是不安全的)。在使用ETW和
显然,答案的一部分将取决于谁在监听这些事件。在我的情况下,我计划使用最新的MS企业库中的“语义日志应用程序块”。
以下是Microsoft讨论可能导致事件丢失的原因之一: 关于事件跟踪 在那里,他们列出了这些可能导致事件丢失的原因。
总事件大小超过64K。这包括ETW头以及数据或有效载荷。用户无法控制这些丢失的事件,因为应用程序配置了事件大小。
ETW缓冲区大小小于总事件大小。用户无法控制这些丢失的事件,因为应用程序记录事件时配置了事件大小。
对于实时日志记录,实时使用者未能快速消耗事件或根本不存在,然后备份文件正在填充。如果在记录事件时停止并启动事件日志服务,则可能会出现此问题。用户无法控制这些丢失的事件。
当记录到文件时,磁盘速度跟不上记录速度。
为了查看是否使用EventSource类(例如,它是否以某种方式截断大型有效载荷)来缓解这些问题,我进行了一些测试。我尝试记录长字符串,但在30,000至35,000个字符之间失败(与最大64KB事件有效载荷相吻合)。据我所知,对于太大的字符串,它只是静默地什么也不做,在我的语义日志应用程序块日志中根本没有事件。前后的事件都像往常一样被写入。
任何时候当我的有效载荷中有一个字符串,我都必须通过某种截断器传递它吗?我还需要手动避免生成“太快”的事件吗(如何可能)?
Microsoft Patterns and Practices 应该引导我们走向良好的...模式和实践...所以也许我在这里漏掉了什么。
更新:
好吧,显然在消费应用程序中有一些关于“事件过快”的通知。我今天第一次收到这个:
级别:警告,消息:由于跟踪会话中的缓冲区溢出或架构同步延迟,某些事件将丢失:Microsoft-SemanticLogging-Etw-svcRuntime 然后在关闭会话时:
级别:警告,消息:在跟踪会话“Microsoft-SemanticLogging-Etw-svcRuntime”中检测到 1 个事件的丢失。
更新2: 企业库开发人员指南描述了我刚提到的行为。
您需要监控由语义化日志应用程序块生成的日志消息,以确定是否存在缓冲区溢出和消息丢失的迹象。例如,具有事件ID 900和901的日志消息表示汇聚的内部缓冲区已经溢出;在进程外场景中,事件ID 806和807表示ETW缓冲区已经溢出。您可以修改汇聚器的缓冲配置选项,以降低缓冲区溢出的可能性。
EventSource
类对我的.NET 4.5应用程序进行仪表化,以发出ETW事件。目标是能够捕获其中的一些事件(错误级别事件)进行错误日志记录。在阅读和测试后,我对这种错误日志记录方法的可靠性表示担忧,特别是关于事件丢失或缺失的可能性。如果我的错误日志记录不起作用,我需要应用程序关闭(在我的情况下,它运行未报告的错误是不安全的)。在使用ETW和
EventSource
时,我如何确保我的错误被正确记录?显然,答案的一部分将取决于谁在监听这些事件。在我的情况下,我计划使用最新的MS企业库中的“语义日志应用程序块”。
以下是Microsoft讨论可能导致事件丢失的原因之一: 关于事件跟踪 在那里,他们列出了这些可能导致事件丢失的原因。
总事件大小超过64K。这包括ETW头以及数据或有效载荷。用户无法控制这些丢失的事件,因为应用程序配置了事件大小。
ETW缓冲区大小小于总事件大小。用户无法控制这些丢失的事件,因为应用程序记录事件时配置了事件大小。
对于实时日志记录,实时使用者未能快速消耗事件或根本不存在,然后备份文件正在填充。如果在记录事件时停止并启动事件日志服务,则可能会出现此问题。用户无法控制这些丢失的事件。
当记录到文件时,磁盘速度跟不上记录速度。
为了查看是否使用EventSource类(例如,它是否以某种方式截断大型有效载荷)来缓解这些问题,我进行了一些测试。我尝试记录长字符串,但在30,000至35,000个字符之间失败(与最大64KB事件有效载荷相吻合)。据我所知,对于太大的字符串,它只是静默地什么也不做,在我的语义日志应用程序块日志中根本没有事件。前后的事件都像往常一样被写入。
任何时候当我的有效载荷中有一个字符串,我都必须通过某种截断器传递它吗?我还需要手动避免生成“太快”的事件吗(如何可能)?
Microsoft Patterns and Practices 应该引导我们走向良好的...模式和实践...所以也许我在这里漏掉了什么。
更新:
好吧,显然在消费应用程序中有一些关于“事件过快”的通知。我今天第一次收到这个:
级别:警告,消息:由于跟踪会话中的缓冲区溢出或架构同步延迟,某些事件将丢失:Microsoft-SemanticLogging-Etw-svcRuntime 然后在关闭会话时:
级别:警告,消息:在跟踪会话“Microsoft-SemanticLogging-Etw-svcRuntime”中检测到 1 个事件的丢失。
更新2: 企业库开发人员指南描述了我刚提到的行为。
您需要监控由语义化日志应用程序块生成的日志消息,以确定是否存在缓冲区溢出和消息丢失的迹象。例如,具有事件ID 900和901的日志消息表示汇聚的内部缓冲区已经溢出;在进程外场景中,事件ID 806和807表示ETW缓冲区已经溢出。您可以修改汇聚器的缓冲配置选项,以降低缓冲区溢出的可能性。
我的问题仍然存在,我能否使用语义化日志记录同时确保我的应用程序在丢失错误时不运行?正常的跟踪事件可能会被丢弃...
我目前的想法是使用旧式的日志技术将"关键"错误记录到单独的类中,并将较不严重的错误(以及调试类型的事件)通过ETW管道进行处理。这并不太糟糕...如果找不到更好的建议,我可能会将其发布为解决方案。
更新3:
我收到的“缺少事件”警告与缓冲区溢出无关,事实证明,如果将空字符串作为有效载荷值传递,则会收到此消息。
Parallel.Foreach
的AggregateException
,但即使如此,这也不太可能。此时,我将“错误”记录到两个来源……一个是进程外的ETW,另一个是传统的日志管道,它在进程内阻塞,直到消息被写入。总的来说,这很好……我可能可以使用语义日志记录块完成所有这些工作(使用进程外组件进行各种日志记录/跟踪,并使用进程内事件侦听器进行实际错误记录)。 - TCC