MengRao / fmtlog

fmtlog is a performant fmtlib-style logging library with latency in nanoseconds.
MIT License
807 stars 124 forks source link

Buffer满了之后的处理能否增加一个方式? #13

Closed WayneY closed 2 years ago

WayneY commented 3 years ago

因为感觉和 quill [ https://github.com/odygrd/quill ] 这个库很像,我跑了几天的benchmark做了对比,目前的结论是 fmtlog 在buffer未满或者满了直接丢的情况下确实比 quill 要快。但是当buffer满了后,开 FMTLOG_BLOCK 的情况下,异步日志秒变同步,速度就和 spdlog 不相上下了。相比之下 quill 使用的新开一块内存 的方式在速度上更有优势。

当日志生成速度大于输出时,buffer是早晚会满的。此时有三种处理方式:

  1. 丢弃,缺点是丢日志
  2. 阻塞输入,等空出来,缺点是影响业务处理速度
  3. 新开buffer,缺点是内存占用会不断增加

目前fmtlog 实现了1,2两种,而quill实现了1,3两种。能否考虑下对fmtlog也增加第三种处理方式,这样选择面更大一些?

另外 quill 那个库有个 dual_queue 模式的设计,似乎也比较有趣。不过极限速度下还是不如 fmtlog。

测试代码大致如下,基本用的bench里改的。因为quill只支持后台线程写日志的方式,所以增加了一个方法:

struct FmtLogBase
{
   void flush() { fmtlog::stopPollingThread(); }
  void prepare() { fmtlog::startPollingThread(); }
};

template<typename T>
void bench(T o) {
  const int RECORDS = 100000; // 加了个0,以让它buffer满
  std::chrono::high_resolution_clock::time_point t0, t1, t2;
  o.prepare();   //此处增加了一步
  t0 =std::chrono::high_resolution_clock::now()
  ......
} 

quill 的bench 也类似,但是因为它用的fmt v7 的api,不完全兼容,得分开编译。

···

struct QuillBase { void flush() { quill::flush(); } void prepare() { quill::start(); } };

···

MengRao commented 3 years ago

从设计上fmtlog不支持unbounded queue,如果默认的1M队列大小不够可以改大,改动地方在这里: image