【问题标题】:When should a Logger flush?Logger 应该什么时候刷新?
【发布时间】:2018-08-27 03:42:04
【问题描述】:

我想知道 Logging 类应该何时或多久刷新一次其流 - 为什么?它应该在每个日志之后刷新,还是等待流缓冲区填充然后刷新,还是介于两者之间?

为了进一步说明我的问题:

我的日志记录类引用了一些std::ostream stream 并使用operator<< 进行输入。我可以在每行输入后刷新,比如说使用std::endl; - 但我没有,而是我use stream << "\n" 只是强制换行。当流缓冲区已满或流 /logger 销毁时,我让刷新发生。

【问题讨论】:

  • 一种合理的方法是根据日志消息级别刷新,即应该立即传递致命/错误消息,而不太关键的消息可以在缓冲区中停留一段时间。
  • @Ron 在 C++ 中,流是标准定义的非常明确的概念。这个问题对于 C++ 程序员来说是非常清楚的。
  • @RobertAndrzejuk 您想到了哪个流? std::ostreamstd::stringstreamstd::fstream 或者ios_base 类作为起点?在time of asking,这些都不是问题。
  • 第一次提出的问题没有“进一步说明我的问题:”部分。我已根据 Ron 的建议对其进行了编辑,但没有将他的评论归功于他。我的错。

标签: c++ c++11 logging


【解决方案1】:

尽可能频繁,以便在崩溃时不会丢失任何条目,并在程序运行时获得更好的实时信息。

尽可能少地避免写入文件的开销。

这些要求相互冲突,因此您需要找到适合您需求的平衡点。

您可能需要考虑某些日志消息可能不如其他日志消息重要,并且您可能会使用它来影响您的刷新策略。

您可以使用信号处理程序(或类似的操作系统特定技术)在崩溃前立即刷新缓冲区。请注意,从技术上讲,刷新 std::stream 是不允许在信号处理程序中执行的操作(尽管这可能取决于其实现),但它可能有效,而且通常比崩溃要好。

【讨论】:

  • 谢谢,非常感谢。
  • 奇闻轶事:我在一个跨平台服务器(Linux/Windows)上工作,我们使用了 POCO C++ 库中的日志基础设施。我们在 Windows 上的日志记录性能很差,而 Linux 性能通常可以接受。查看 POCO 源代码,我发现 Linux 实现基本上做了(IIRC)fwrite+fflush,它将日志刷新到操作系统,但在 Windows 上它做了WriteFile +FlushFileBuffers,前者已经将所有内容写入操作系统,然后后者刷新到磁盘,更安全但速度慢得多(它对应于 POSIX 的fsync)。
【解决方案2】:

在 C++ 中,iostreams 库有 2 个用于记录的类。 两者都绑定到stderr

cerr - 在每次输入格式化后刷新,这意味着在每次调用之后。

clog - 在缓冲区被填充或手动调用时刷新(例如:endlflush())。

想法是,您希望尽快输出错误。 但是日志可以批量输出。

【讨论】:

    【解决方案3】:

    视情况而定。虽然日志记录通常被缩小以表示某些与错误相关的消息传递机制,但它并不总是与错误相关联。相反,有时它甚至被明确地与错误分开(例如clog vs. cerr)。另一个例子一般是tracing。因此,由您(日志系统的设计者)来决定您希望通过特定日志达到哪个完整性级别。

    基于流的日志记录是报告错误的一种简单方法。这不是最后一类的特点,但作为记录致命错误唯一方法是不明智的。总比没有好(特别是在强调可移植性的情况下)...当你不得不依赖这种方式时,尽快刷新它。

    【讨论】:

      猜你喜欢
      • 2018-09-21
      • 1970-01-01
      • 2021-02-26
      • 2010-09-22
      • 2014-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多