在ISAPI过滤器中,对于多个进程的公共日志文件,什么是好方法?

时间:2009-10-02 19:08:08

标签: windows logging mutex isapi w3wp.exe

我有一个在IIS6或7上运行的ISAPI过滤器。当有多个工作进程(“Web园”)时,将在每个w3wp.exe中加载并运行过滤器。

如何有效地允许过滤器在单个统一日志文件中记录其活动?

  • 来自不同(并发)进程的日志消息不得相互干扰。换句话说,从任何w3wp.exe发出的单个日志消息必须在日志文件中实现为单个连续行。

  • 日志文件的争用应该是最小的。这些网站每秒可以提供100个请求。

  • 首选严格的时间排序。换句话说,如果w3wp.exe进程#1在t1发出消息,则进程#2在t2发出消息,然后进程#1在t3发出消息,消息应该以适当的时间顺序出现在日志文件中。

我目前的方法是每个进程拥有一个单独的日志文件。这有明显的缺点。

一些想法:

  • 指定其中一个w3wp.exe为“logfile owner”,并通过该特殊进程发送所有日志消息。这在工人流程回收的情况下存在问题。

  • 使用操作系统互斥锁来保护对日志文件的访问。这种高性能足够吗?在这种情况下,每个w3wp.exe在同一文件系统文件上都有一个FILE。每次写入后我必须刷新日志文件吗?这会有用吗?

有什么建议吗?

7 个答案:

答案 0 :(得分:2)

起初我会说我最喜欢你当前的方法,因为每个进程都没有任何共享,然后我意识到,嗯,他们可能都在下面共享同一个硬盘。因此,仍然存在争用发生的瓶颈。或者操作系统和硬盘驱动器控制器真的很聪明处理它?<​​/ p>

我认为你想要做的就是让日志的写入不会减慢正在进行实际工作的线程。

那么,在同一台机器上运行另一个进程(优先级较低?),它实际上将日志消息写入磁盘。使用非UDP建议与其他进程通信,而不是进程共享的内存。也很容易混淆,作为内存映射文件。有关memory mapped files的更多信息。在我的公司,我们发现内存映射文件要比环回TCP / IP快得多,以便在同一个盒子上进行通信,所以我假设它也会比UDP快。

对于初学者来说,你在共享内存中实际拥有的是一个std :: queue,其中push和pops使用互斥锁进行保护。您的ISAPI线程将获取互斥锁以将内容放入队列。日志记录过程将获取互斥锁以从队列中取出内容,释放互斥锁,然后将条目写入磁盘。互斥锁只能保护共享内存的更新,而不是文件的更新,因此从理论上讲,互斥锁可以保留更短的时间,从而减少瓶颈。

日志记录过程甚至可以重新排列其编写的顺序,以便按顺序获取时间戳。

这是另一个变体:Contine为每个进程都有一个单独的日志,但在每个进程中都有一个记录器线程,这样主时间关键线程就不必等待记录发生以便继续进行工作

我在这里写的所有内容的问题在于整个系统 - 硬件,操作系统,多核CPU L1 / L2缓存的工作方式,你的软件 - 太复杂了,不能通过思考它来轻松预测。编写一些简单的概念验证应用程序,对它们进行一些计时,并在真实硬件上进行测试。

答案 1 :(得分:1)

在这里登录数据库会有意义吗?

答案 2 :(得分:1)

我过去使用过基于UDP的日志系统,我很满意这种解决方案。

日志通过UDP发送到日志收集器进程,负责将其定期保存到文件中。

我不知道它是否可以在您的高性能环境中工作,但我对这种解决方案在压力较小的应用中感到满意。

我希望它有所帮助。

答案 3 :(得分:0)

而不是OS Mutex来控制对文件的访问,您可以使用带有LockFile()和UnlockFile()的Win32文件锁定机制。

答案 4 :(得分:0)

我的建议是将消息异步(UDP)发送到负责记录日志的进程 该过程将:
- 一个线程接收器将消息放入队列中;
- 一个线程负责从时间排序列表中删除队列中的消息;
- 一个线程监视列表中的消息,只有时间长度大于最小值的消息应保存在文件中(以防止延迟消息无序写入)。

答案 5 :(得分:0)

您可以继续记录单独的文件并查找/编写工具以便稍后合并(可能是自动化的,或者您可以在要使用文件的位置运行它。)

答案 6 :(得分:0)

Windows Vista及更高版本中包含的

Event Tracing for Windows为此提供了很好的功能。

摘录:

  

Windows事件跟踪(ETW)是一种高效的内核级跟踪工具,可让您将内核或应用程序定义的事件记录到日志文件中。您可以实时或从日志文件中使用事件,并使用它们来调试应用程序或确定应用程序中发生性能问题的位置。