分析EventLog Monitor
一位朋友给了我老外写的一个工具, 该工具可以监视Windows event log, 在特定的事件发生的时候, 触发一个自己定义的批处理文件的执行. 这是个非常有用的工具. 比如说, 你的event log中偶尔会有某种错误报出来, 你想要抓取network monitor trace, 或者是performance trace, 亦或是SQL的PSSDiag, 然而你无法预计下一次它将会在什么时候再次发生, 这些抓取动作就很难在合适的时候进行. 在这个工具的帮助下, 你就可以自动化地完成抓取日志的动作了.
我很好奇这个工具是如何实现的. 于是使用反汇编工具Reflector来看了一下. 得出的结论记录如下:
最关键的类 – EventMonitorService
=================
该类包含以下类的对象
- System.Diagnostics.EventLog 这个类允许你访问或自定义Windows Event Logs, Windows Event Logs会记录关于硬件, 软件的重要事件, 你可以从Event logs中读取条目, 写入条目, 创建或删除事件laiyuan,还可以响应log entries.
- System.Diagnostics.EventEntry 这个类包装了event log中的一条记录.
- System.Timers.Timer 这个类用于在应用程序中产生一个重复的事件.
- 一个delegate对象
看到这里, 你应该有些idea了吧. 现在我们把原理研究一下.
1. EventMonitorService对象在构造的时候, 会以"Application"为参数,创建EventLog的实例, 用来读取应用程序日志. 创建Timer的实例, 并为Timer的Elapsed事件绑定处理程序. 然后开启Timer.
2. 在Timer所绑定的事件处理程序中, 设定一个EventEntry对象作为哨兵, 让它保存当读取到的最后一条event log中的记录. 以后通过它, 每次都可以分辨出哪些日志记录是最新生成的.
3. 遍历最新生成的event log entry, 判断它们是否符合预先设定的被监视的事件的条件, 如果符合, 就用这条记录作为参数, 触发EventMonitorService类型的代理对象.
EventMonitorService类的消费者
==================
这个消费者类在构造时, 为EventMonitorService的代理对象绑定事件处理程序.
在这里的事件处理程序中, 新起一个Thread对象, 在Thread的对象中指定一个函数. 在这个函数中启动一个进程, 让这个进程运行事先写好的批处理程序.
贴出启动进程并执行批处理的代码如下:
Process p = new Process(); ProcessStartInfo psi = new ProcessStartInfo("cmd"); psi.Arguments = "/c " + CommandString; p.StartInfo = psi; p.Start(); p.WaitForExit();
小知识点: cmd /c CommandString 中的/c参数的意义是: 执行commandString所指定的命令, 然后结束掉控制台程序.