【问题标题】:multithreaded logging for high performance application [duplicate]用于高性能应用程序的多线程日志记录
【发布时间】:2010-10-13 08:33:02
【问题描述】:

我有一个应用程序(服务器应用程序)需要实现大量的日志记录,并且不应该通过启用日志记录来影响性能。

应用程序有一个执行工作的工作线程的线程池。最初我打算只登录这些线程池线程,但后来我需要锁定几乎整个线程,所以我的“多线程”应用程序出现了。

我一直在寻找从多个线程进行日志记录的更好方法,我发现使用队列或环形缓冲区可能是一个想法。

任何人都可以建议(也许从经验中)任何好的方法来为多线程应用程序实现有效的日志记录(主要是到文件),同时也应该保持一定的性能?

我想使用 Boost 日志库。

【问题讨论】:

  • 可能值得指出一个显而易见的事实:一旦您开始执行异步日志记录,如果您的应用程序崩溃,您还有丢失最后几个日志条目的风险。由于应用程序在启动日志记录后立即恢复,因此您无法保证所有日志消息在任何给定时间都已实际写入磁盘。
  • @jalf:那你建议我怎么做?
  • 没有线索。取决于你的需要。在您的情况下,异步日志记录机制可能仍然是最好的方法,我只是指出您必须注意的一个重要警告。当然,一种可能的选择可能是将日志数据写入比硬盘驱动器更快的介质(SSD 磁盘?快速网络连接?),因此它不会像硬盘驱动器写入那样在宝贵的毫秒内阻塞主机应用程序。
  • 您可以添加一个在日志记录期间会阻塞的日志记录级别(严重?),这样至少您可以在调查期间确定您的日志。无论如何,比起记录崩溃,更喜欢 Postmortem(核心)。
  • 在此处查看更多信息:stackoverflow.com/questions/696321/…

标签: c++ multithreading logging


【解决方案1】:

Pantheios 是目前最快的 C++ 日志库,据我所知。我建议使用它而不是 Boost Logging。使用 Pantheios,您只需登录到文件,而无需关心来自哪个线程。如果需要,您可以将线程名称放在日志行前缀中,它会为您完成所有工作。

【讨论】:

  • 不一定是最快的!!您从哪里获得此数据的任何来源?
  • 也请看结论部分,他们有一种很好的免责声明!
【解决方案2】:

就我个人而言,我会研究 Pantheios,看了一眼,它看起来很有趣,将把它包含在我未来的项目中。

如果您真的想使用 boost 日志记录,我会使用同步队列来处理内部所有锁定,这样您的工作人员就不必担心这一点。

伪代码:

 class SynchedQueue {
      void write(text) { lock() logfile.write(text) unlock() }

或者,如果您真的想加快速度,请使用内部队列并一次从公共队列中分批传输 X 行。公共队列不必等待可能需要相对较长时间的文件 i/o,而私有队列很少收到行。虽然它可能仍然比 Pantheios 慢。

【讨论】:

  • +1 "一次 X 行批次"
【解决方案3】:

我最近在ddj上阅读了一篇使用Active Objects for mt logging的有趣文章:

http://www.drdobbs.com/high-performance-computing/227500074

一篇较早的文章还讨论了线程安全日志记录的一些设计注意事项:

http://www.drdobbs.com/cpp/201804215

【讨论】:

    【解决方案4】:

    Apache log4cxx。我已经看到很多地方广泛使用它。其中大多数是交易应用程序、多线程和低延迟应用程序。 log4cxx 并不逊色于任何日志库,它适用于 C++ 和 Java(Apache log4j),这两个我都用过。

    【讨论】:

    • @m_pGladiator - 从哪里来?任何链接或个人经验?
    • 个人经历。在选择 Pantheios 之前,我测试了几个库。 log4cxx 是其中一个库,我对它的体验非常糟糕。
    【解决方案5】:

    我正在使用并且非常喜欢Petru Marginean's logging system。它真的很轻快而且很整洁。我花了一点时间来理解它,所以我可以根据自己的喜好调整它,但是一旦你理解了它,它就是一种美,因为整个库实际上只有一个 250 行的头文件,它并不多通过。

    其中最慢的部分是它使用带有 ostringstream 的对象,但我怀疑你会找到更快的东西。至少不是 C 多于 C++。

    在他的second article and version 中,他展示了他如何使它成为线程安全的。

    如果找不到源代码,请告诉我,我有。我记得我不得不搜索一下。

    【讨论】:

    • 介意与我分享Petru的源代码吗?就是找不到。
    • @athos 据我所知,原文章还有代码链接,第二个版本是link
    【解决方案6】:

    我不熟悉 Boost Logging 库,因此无法对此发表评论。

    NLog 支持从 C/C++ 和 COM(以及托管 .NET 应用程序)进行日志记录。不确定它是否具有您所追求的性能特征。

    您也可以考虑ETW。它是在 Windows 内核中实现的高速日志系统。我没有使用过它,但微软似乎确实在推动它,让它在每个版本中更容易使用。它们肯定使托管代码更易于使用。就目前而言,在我看来,设置然后获取输出有点复杂。我从来没有认真考虑过实施 ETW,所以我无法评论它到底有多容易或有多困难。

    【讨论】:

    • ETW 很棒,记录没有侦听器的事件实际上是免费的,但即使有侦听器,我也发现单个日志事件远低于一微秒。但要注意创建跟踪值的成本,即随机 ToString 或隐式反射使用可能会取消速度提升
    猜你喜欢
    • 1970-01-01
    • 2019-06-14
    • 2011-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-17
    • 2020-07-11
    相关资源
    最近更新 更多