IT评测·应用市场-qidao123.com

标题: 第三部分:Spdlog 日志库的实现原理 [打印本页]

作者: 十念    时间: 2023-4-4 14:18
标题: 第三部分:Spdlog 日志库的实现原理
! https://zhuanlan.zhihu.com/p/617432495

Spdlog 是一个快速、异步的 C++ 日志库,被广泛应用于 C++ 项目中。在这篇文章中,我们将探讨 Spdlog 日志库的实现原理。
Spdlog 的结构

Spdlog 由五个主要组件构成:Loggers、Sinks、Formatters、Async Logger 和 Registry。每个组件都扮演着不同的角色,共同协作记录并输出日志消息。

Spdlog 记录日志的流程

当应用程序调用 Spdlog 记录日志时,Spdlog 的流程如下:
Spdlog 的流程非常简单,但是每个组件都扮演着重要的角色。Loggers 负责记录日志消息,Sinks 决定了日志消息的输出位置,Formatters 负责将日志消息转换为特定格式,Async Logger 异步地将日志消息写入到目标 Sink 中,Registry 用于管理这些组件。
Spdlog 的线程安全性

spdlog 允许我们自由创建线程安全和非线程安全(单线程)的日志,其设置在基类base_skin 中,
  1. template<typename Mutex>
  2. class SPDLOG_API base_sink : public sink
  3. {
  4. public:
  5.     void log(const details::log_msg &msg) final;
  6. protected:
  7.     Mutex mutex_;
  8. }
  9. template<typename Mutex>
  10. void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::log(const details::log_msg &msg)
  11. {
  12.     std::lock_guard<Mutex> lock(mutex_);
  13.     sink_it_(msg);
  14. }
复制代码
每个sink都会继承 base_sink,通过模板参数  Mutex 传入锁。可以看到写日志函数 log 调用了 std::lock_guard  来使用锁。
Mutex 可以自定义,需要提供下面两个接口:
  1. void lock();
  2. void unlock();
复制代码
在实际使用中如果想要线程安全,可以传入c++的 mutex(c++11开始支持),也可以自定义。如下是一个声明线程安全例子:
  1. using kafka_sink_mt = kafka_sink<std::mutex>;
复制代码
当然spdlog 也为我们提供了单线程的 mutex:
  1. struct null_mutex
  2. {
  3.     void lock() const {}
  4.     void unlock() const {}
  5. };
  6. using kafka_sink_st = kafka_sink<spdlog::details::null_mutex>;
复制代码
Spdlog 的同步和异步模式

同步模式

在同步模式下,Spdlog 将日志消息直接写入目标 Sink,不使用内存队列。这种模式下,应用程序在记录日志消息时,必须等待消息写入目标 Sink 后才能继续执行。同步模式可以保证日志消息的实时性,但是可能会影响程序的性能,特别是在大量记录日志消息时。如果应用程序不需要实时记录日志消息,可以使用异步模式来提高性能。
异步模式

在异步模式下,日志消息被加入到一个内存队列中,然后异步地写入目标 Sink。异步模式可以提高日志记录的性能,尤其是在多线程环境下,因为它可以避免多个线程同时访问 Sink,从而提高线程安全性。
在 Spdlog 中,异步模式由 Async Logger 实现。Async Logger 在后台运行一个线程,负责从内存队列中获取日志消息,并将其写入目标 Sink 中。Async Logger 可以配置多个 Sink,每个 Sink 都会有一个独立的内存队列。
Spdlog 提供了两种内存队列实现:unbounded 和 bounded。unbounded 内存队列没有大小限制,可以一直增长,直到内存耗尽。bounded 内存队列有一个固定的大小,超过大小限制后,新的消息将被丢弃。
在使用异步模式时,需要注意以下事项:
异步模式可以大大提高日志记录的性能,但是也需要谨慎使用和测试。如果内存队列大小限制不当或处理不当,可能会导致内存占用过高或日志消息丢失等问题。
Spdlog 的性能

Spdlog 是一个高性能的日志库,它的性能优于其他许多日志库。Spdlog 的异步记录器和多线程支持使得它能够快速地记录大量的日志消息。
下面是spdlog性能:
同步模式:
  1. [info] **************************************************************
  2. [info] Single thread, 1,000,000 iterations
  3. [info] **************************************************************
  4. [info] basic_st         Elapsed: 0.17 secs        5,777,626/sec
  5. [info] rotating_st      Elapsed: 0.18 secs        5,475,894/sec
  6. [info] daily_st         Elapsed: 0.20 secs        5,062,659/sec
  7. [info] empty_logger     Elapsed: 0.07 secs       14,127,300/sec
  8. [info] **************************************************************
  9. [info] C-string (400 bytes). Single thread, 1,000,000 iterations
  10. [info] **************************************************************
  11. [info] basic_st         Elapsed: 0.41 secs        2,412,483/sec
  12. [info] rotating_st      Elapsed: 0.72 secs        1,389,196/sec
  13. [info] daily_st         Elapsed: 0.42 secs        2,393,298/sec
  14. [info] null_st          Elapsed: 0.04 secs       27,446,957/sec
  15. [info] **************************************************************
  16. [info] 10 threads, competing over the same logger object, 1,000,000 iterations
  17. [info] **************************************************************
  18. [info] basic_mt         Elapsed: 0.60 secs        1,659,613/sec
  19. [info] rotating_mt      Elapsed: 0.62 secs        1,612,493/sec
  20. [info] daily_mt         Elapsed: 0.61 secs        1,638,305/sec
  21. [info] null_mt          Elapsed: 0.16 secs        6,272,758/sec
复制代码
异步模式:
  1. [info] -------------------------------------------------
  2. [info] Messages     : 1,000,000
  3. [info] Threads      : 10
  4. [info] Queue        : 8,192 slots
  5. [info] Queue memory : 8,192 x 272 = 2,176 KB
  6. [info] -------------------------------------------------
  7. [info]
  8. [info] *********************************
  9. [info] Queue Overflow Policy: block
  10. [info] *********************************
  11. [info] Elapsed: 1.70784 secs     585,535/sec
  12. [info] Elapsed: 1.69805 secs     588,910/sec
  13. [info] Elapsed: 1.7026 secs      587,337/sec
  14. [info]
  15. [info] *********************************
  16. [info] Queue Overflow Policy: overrun
  17. [info] *********************************
  18. [info] Elapsed: 0.372816 secs    2,682,285/sec
  19. [info] Elapsed: 0.379758 secs    2,633,255/sec
  20. [info] Elapsed: 0.373532 secs    2,677,147/sec
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4