TCC*_*TCC 21 .net logging etw etw-eventsource
我正在检测我的.NET 4.5应用程序以使用EventSource该类发出ETW事件.目标是能够捕获一些这些事件(错误级别事件)以进行错误记录.
在做了一些阅读和测试之后,我担心这种错误记录方法的可靠性,特别是关于事件丢失或丢失的可能性.如果我的错误记录无法正常工作,我需要关闭应用程序(在我的情况下,运行未报告的错误是不安全的).使用ETW时EventSource,如何确定我的错误被正确记录?
显然,部分答案取决于听取事件的内容.在我的情况下,我计划使用最新的MS企业库中的"语义记录应用程序块".
以下是微软谈论错过事件可能原因的一个来源: 关于事件追踪
在那里,他们列出了失踪事件的这些可能原因
总事件大小大于64K.这包括ETW标头加上数据或有效负载.由于事件大小由应用程序配置,因此用户无法控制这些丢失的事件.
ETW缓冲区大小小于总事件大小.由于事件大小由记录事件的应用程序配置,因此用户无法控制这些丢失的事件.
对于实时日志记录,实时消费者不会足够快地消耗事件或者不完全存在,然后支持文件就会填满.如果在记录事件时停止并启动事件日志服务,则会导致此问题.用户无法控制这些丢失的事件.
记录到文件时,磁盘速度太慢,无法跟上日志记录速率.
要查看是否使用EventSource类以某种方式减轻了这些问题(比如,它是否以某种方式截断了大型有效负载),我做了一些测试.我尝试记录长字符串,但对于我而言,它在30,000到35,000个字符之间失败(与64KB最大事件有效负载一致).它只是在我的语义记录应用程序块日志中对于太大的字符串,根本没有任何事件,我只能默默地做什么.之前和之后的事件都像往常一样写.
所以每当我在我的有效载荷中有一个字符串时,我必须通过一些截断器传递它?我是否需要手动避免生成"太快"的事件(以及如何实现)?
微软模式和实践应该引导我们进行良好的模式和实践...所以也许我只是在这里遗漏了一些东西.
更新:
显然,消费应用程序中有一些关于"事件太快"情况的通知.我今天第一次收到这个:
级别:警告,消息:由于跟踪会话中的缓冲区溢出或架构同步延迟,某些事件将丢失:Microsoft-SemanticLogging-Etw-svcRuntime
然后在关闭会话时:
级别:警告,消息:在跟踪会话"Microsoft-SemanticLogging-Etw-svcRuntime"中检测到丢失1个事件.
UPDATE2:
" 企业库开发人员指南"描述了我刚才提到的行为.
您应该监视语义记录应用程序块生成的日志消息,以获取有缓冲区溢出和丢失消息的任何指示.例如,带有事件ID 900和901的日志消息表明接收器的内部缓冲区已溢出; 在进程外方案中,事件ID 806和807指示ETW缓冲区已溢出.您可以修改接收器的缓冲配置选项,以减少缓冲区因典型工作负载而溢出的可能性.
我的问题仍然存在,我是否可以使用语义记录,同时确保如果错误被丢弃,我的应用程序不会运行?正常的跟踪事件可能会被删除......
我目前的想法是使用老式的日志记录技术使用单独的类记录"严重"错误,并通过ETW管道保持较少的关键错误(以及调试类型事件).这真的不会太糟糕......如果我找不到更好的建议,我可以将其作为解决方案发布.
更新3:
我收到的"丢失事件"警告与缓冲区溢出无关,事实证明,如果您将null string作为有效负载值传递,则会获得此消息.
该EventSource班有两个版本,一个包含在NuGet包.NET Framework和其它微软的EventSource库.我假设你使用NuGet包,因为它包含更新的代码.
EventSource基类的构造函数有一个重载,它带有一个throwOnEventWriteErrors带有以下文档的布尔参数(NuGet包版本1.0.26.0):
默认情况下,调用'WriteEvent'方法不会抛出错误(它们会默默地丢弃该事件).这是因为在大多数情况下,用户认为记录不是"宝贵的",并且不希望记录失败导致程序崩溃.但是对于那些日志记录很"珍贵"的应用程序,如果它失败,调用者希望做出反应,设置'throwOnEventWriteErrors'将导致在WriteEvent失败时抛出异常.注意EventWrite成功的事实并不一定意味着事件只到写入它的操作没有失败才到达目的地.
不幸的是,最后一句包含一个警告,但是如果你查看源代码,EventSource你可以看到来自OS调用的底层返回代码用于为NoFreeBuffers和EventTooBig(以及其他错误)抛出不同的异常.
因此,如果您打开,throwOnEventWriteErrors如果EventSource班级无法将事件传递给ETW ,您将获得例外.但是,如果ETW由于其他原因而失败,您将不会得到任何异常但是如果您确保您的ETW通道配置正确,那么很少会发生.但是,由于您无法容忍丢失任何错误事件,因此您应该测试极端错误情况,以确保ETW按预期运行.
小智 7
有一点是在上面的讨论中没有明确的两个要点.
与丢弃事件相关的所有问题都与ETW(Windows事件跟踪)有关,而与EventSource无关.这在逻辑上是EventSOurces与EventListeners的对话,并且有内置的监听器可以转发给ETW.显然,当您谈论丢弃的事件时,链中任何链接的约束都会影响流经链的数据.因此,保证完全可靠性的一种方法是使用不使用ETW但直接到达数据所在位置的EventListener.我相信(语义记录应用程序块)有这样的倾听者.
ETW已被成功用于可靠地转发事件,但您必须生活在上述限制范围内(事件的大小必须保持<64K并且您必须控制事件率.请注意,如果率是太高你会知道这一点,因为WriteEvent会失败,所以你可以重试(暂停后),从而做出完全可靠的东西(以减慢程序为代价).注意这种数据丢失不是一个有趣的问题,如果你真的在谈论错误(不应该以极快的速度发生,如果它们发生在高速率,它们可能是多余的(同样的事情快速发射).
总而言之,EventSource默认支持可靠事件,ETW默认情况下不支持它,但可以支持它,但ETW的默认值通常都很好.
| 归档时间: |
|
| 查看次数: |
7634 次 |
| 最近记录: |