我正在检测我的.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作为有效负载值传递,则会获得此消息.
所有方法System.ServiceModel.Channels.Message只允许您读取消息体一次,如果在读取消息后调用则失败并返回异常.msdn文档确认只能读取消息正文.但是,如果你打电话ToString()给已经读过的信息,你似乎可以找回整个肥皂信封,身体和所有信息.
所以在我的情况下,即使只有方法允许,它似乎也可以访问身体.
这里有什么我想念的吗?ToString()在某些情况下使用是否可以使身体不可靠?
就我而言,我正在为一些WCF操作进行一些错误记录,并从中获取原始消息OperationContext.RequestContext.RequestMessage.我正在记录消息ToString()因为这是我能够找到的唯一方法来允许我记录消息正文.
我正在使用SQL Server 2008-R2,但我也对更通用的答案感兴趣...
我有一个包含数亿行的表,每行都有一个"DateModified"字段(datetime2(7))
现在,我经常使用类似的查询来轮询该表
select * from table where DateModified > @P1
Run Code Online (Sandbox Code Playgroud)
这里的参数总是最近的(就像在最后几分钟内一样)并且可能只有少数记录与该值匹配.
我发现我在整个表上维护一个大索引,当我永远不会将索引用于其中的许多值时...所以这听起来像是一个完美的使用Filtered Index我只索引我的行可能会查询...
但在这种情况下,过滤器看起来像什么?我唯一的想法是过滤
where DateModified > [yesterday]
Run Code Online (Sandbox Code Playgroud)
其中[yesterday]是日期文字,但是我必须定期重新定义过滤器,否则过滤器的优势会随着时间的推移而减少.
我一时兴起,ModifiedDate > DATEADD(d,-1,GETDATE())但却给出了一个不起眼的错误......不确定这是怎么回事.
有没有其他方法来实现这一目标?
最后,如果有办法做到这一点,我应该期望统计数据在我的情况下是非常错误的,这会影响我的查询性能吗?
我对这些统计数据的关注来自这篇文章.
我试图通过一些断开连接的数据将更改从一个系统传播到另一个系统...如果您想建议一种完全替代的方法来轮询"DateModified",我很乐意考虑它.