跳至主要內容

LincZero大约 11 分钟

FAQ


Q:常用的c/c++日志库,特别标注一下高性能的库。这些日志库使用了哪些好用的技术


在 C 和 C++ 中,有很多常用的日志库。其中一些性能较高的库包括:

  1. spdlog:一款非常高性能且功能丰富的 C++ 日志库,支持格式化和多线程。
  2. glog:谷歌开发的 C++ 日志库,性能优秀且易于使用。
  3. log4cpp:基于 C++ 的日志库,具有良好的性能和灵活性,类似于 Java 的 log4j。

这些日志库使用了如下技术来提高性能和易用性:

  • 高效的字符串格式化。
  • 缓冲区和内存管理技术,减少内存分配和释放的开销。
  • 异步日志记录,减少 I/O 阻塞。
  • 多线程支持,充分利用多核处理器的能力。

Q:另外有几个小问题:

  1. 使用printf应该是由于cout性能会很慢百倍于printf?
  2. 但是不同于cout和printf的关系,c++文件流似乎又比c的写入性能高?
  3. C++新特性中有一个宏编程或者模板元编程的概念,日志库是否可以使用这种技术来提高性能?
  4. 比如像下面这个代码的原理是什么?是使用预处理来在编译阶段进行优化?应该不属于宏编程或模板元编程的范畴吧
#define SYS_LOG(level, fmt, ...) \
    do_log(level, sysLogFp, nullptr, basename((char *)__FILE__), __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__);

关于您的几个小问题:

  1. printf 相对于 cout 的性能确实更高,因为 printf 是基于 C 语言的,更底层且简单。cout 基于 C++ 的 iostream 库,其性能相对较慢,但具有更好的类型安全和扩展性。实际上,性能差异可能并非百倍,具体取决于编译器优化和使用场景。
  2. C++ 文件流和 C 的文件 I/O 写入性能之间的差异主要取决于底层实现和缓冲策略。在某些情况下,C++ 文件流可能具有更好的性能,这是因为 C++ 的 I/O 流库在设计时充分考虑了性能优化。
  3. 宏编程和模板元编程可以在某种程度上提高性能,因为它们允许在编译期间进行代码优化。 然而,这些技术主要用于生成和优化编译期计算的代码,而不是运行时日志记录。尽管如此,日志库可以利用这些技术生成更高效的代码。
  4. 您提供的代码是一个宏定义,主要用于在编译阶段生成日志记录调用。这不属于宏编程或模板元编程范畴,而是 C/C++ 中的预处理指令。这个宏的原理是,当您使用 SYS_LOG 时,它将在编译时展开成一个 do_log 函数调用,并在调用中传递文件名、行号和函数名等参数。这样做的目的是为了提供更丰富的上下文信息,方便调试和排查问题。

Q:具体讲,spdlog glog log4cpp 各自优缺点,以及选用


下面是关于 spdlog、glog 和 log4cpp 的比较,包括各自的优缺点,以帮助您根据需求做出选择。

  • spdlog

    • 优点
    -   高性能:spdlog 在性能方面表现出色,可以很好地满足高吞吐量日志记录的需求。
    
    -   丰富的功能:spdlog 支持多种日志级别、格式化、日志输出目标(如文件、控制台等)以及多线程。
    
    -   简单易用:spdlog 的 API 设计简洁,易于理解和使用。
    
    -   头文件库:spdlog 是一个**纯头文件库**,无需编译,只需将其包含到项目中即可使用。
    
    • 缺点
      • 相对于 glog 和 log4cpp,spdlog 的社区规模较小,可能在一些特定问题上找不到现成的解决方案。
  • glog

    • 优点
    -   谷歌背景:glog 是由谷歌开发的,具有较强的稳定性和可靠性保障。
    
    -   性能优秀:glog 的性能相对较好,适用于对性能有要求的场景。
    
    -   简洁的 API:glog 的 API 设计简洁,易于上手。
    
    -   支持条件日志:glog 支持在满足特定条件时记录日志,便于调试和排查问题。
    
    • 缺点
      • 功能相对简单:glog 的功能相对于 spdlog 较为简单,可能无法满足一些复杂需求。
  • log4cpp

    • 优点
    -   灵活性高:log4cpp 具有很高的灵活性,可以通过配置文件轻松地更改日志策略。
    
    -   可扩展性强:log4cpp 支持自定义日志输出目标、格式化等。
    
    -   类似于 log4j:log4cpp 的设计参考了 Java 的 log4j,如果您熟悉 log4j,那么上手 log4cpp 会非常容易。
    
    • 缺点
      • 性能相对较低:与 spdlog 和 glog 相比,log4cpp 的性能可能略逊一筹。

选择建议

  • 如果您对性能有较高要求,并希望获得丰富的功能和简单易用的 API,那么 spdlog 是一个很好的选择。

  • 如果您希望使用一个稳定可靠、性能优秀的日志库,并且对功能需求不是特别复杂,那么可以选择 glog。

  • 如果您的项目需要高度灵活性和可扩展性,或者您熟悉 log4j,那么可以选择 log4cpp。


Q:我不理解你说的高灵活性和高扩展性有多么灵活,我将向你讲述我的日志库使用需求:

  1. 分三个类型的日志,SYS_LOG、TEST_LOG、HTTP_LOG
  2. SYS_LOG 记录程序从开始到结束的全局类的输出
  3. TEST_LOG 记录程序的一些运行的测试的输出(全局可以有多个不同的test,每个test的输出分别记录在他们对应的文件里)
  4. 日志需要支持日志级别、打印输出时所在的线程 文件 函数 行数 时间、如果是TEST_LOG还需要打印测试id

根据您的需求,可以看出您需要一个支持多种日志类型、灵活的日志级别设置、丰富的日志上下文信息(线程、文件、函数、行数、时间)以及测试 ID 的日志库。在 spdlog、glog 和 log4cpp 之间进行选择时,可以根据以下标准进行考虑:

  1. 多种日志类型:spdlog、glog 和 log4cpp 都支持多种日志类型。在 spdlog 和 log4cpp 中,您可以创建多个日志实例,分别对应 SYS_LOG、TEST_LOG 和 HTTP_LOG。在 glog 中,您可以使用不同的日志级别来表示这三种类型的日志,或者根据需要创建自定义的日志接收器。
  2. 灵活的日志级别设置:spdlog、glog 和 log4cpp 都支持灵活的日志级别设置,可以根据需要启用或禁用不同级别的日志。
  3. 丰富的日志上下文信息:spdlog 和 log4cpp 都支持自定义日志格式,可以方便地包含线程、文件、函数、行数、时间等信息。glog 在默认情况下会包含文件、函数、行数、时间等信息,但如果需要包含线程信息和测试 ID,则需要对其进行一定的扩展。
  4. 测试 ID:在 spdlog 和 log4cpp 中,您可以通过自定义日志格式或自定义日志接收器来包含测试 ID。在 glog 中,您需要进行一定程度的扩展以支持测试 ID。

综上,对于您的需求,spdlog 和 log4cpp 都是不错的选择,它们在灵活性和扩展性方面的优势可以帮助您实现所需的功能。具体而言,spdlog 提供了更高的性能,而 log4cpp 提供了更高的灵活性和可扩展性。

您可以根据自己的喜好以及对性能和灵活性的权衡来选择 spdlog 或 log4cpp。如果您对性能要求较高,建议选择 spdlog;如果您希望更灵活地自定义日志格式和接收器,那么 log4cpp 是一个更好的选择。


Q:他们之间的性能差距有多大,例如单纯打印一条系统日志需要分别耗时多少ms


在实际应用中,日志库之间的性能差异很难以精确的毫秒数来衡量,因为这取决于许多因素,如编译器优化、系统环境、硬件和程序的具体使用情况。然而,我们可以大致了解这几个库之间的性能差异。

spdlog 通常被认为是这三个库中性能最高的。它利用了高效的字符串格式化、缓冲区管理和异步日志记录技术,因此在高吞吐量的日志记录场景下表现尤为出色。根据 spdlog 官方的基准测试,它可以在极短的时间内(纳秒级别)完成单条日志的记录。

glog 的性能也相对较好,尽管可能略逊于 spdlog。glog 的优点在于其稳定性和谷歌背景,因此在对性能要求较高但不追求极致性能的场景下,它仍然是一个非常好的选择。

log4cpp 的性能相对较低,但仍然可以满足大多数应用的需求。它的主要优势在于灵活性和可扩展性,可以轻松地自定义日志格式和接收器。

总之,这三个库在性能上的差距可能对大多数应用场景来说并不显著。当然,在对性能要求极高的场景下,选择 spdlog 可能会带来更好的性能体验。根据您的需求,建议您在 spdlog 和 log4cpp 之间进行选择,权衡它们在性能和灵活性方面的优劣。


Q:将glog进行排除,后续的讨论不再考虑该库。在log4cpp与spdlog的衡量中我选择了后者。

截止到20230425的其他比较

  • 开源

    • spdlog:开源17.7k star,开源地址:https://github.com/gabime/spdlog,wiki&快速入门:https://github.com/gabime/spdlog/wiki/1.-QuickStart,上次更新0423,MIT 许可证
    • log4cpp:开源在sourceforge上,开源地址:https://sourceforge.net/projects/log4cpp/files/,上次更新0312,LGPL 许可证
    • glog:开源6.1k star,开源地址:https://github.com/google/glog,上次更新0228,BSD 许可证
  • 跨平台性

    • spdlog:跨平台
    • log4cpp:跨平台
    • glog:跨平台
  • 速度

    • spdlog:github上的:

      [info] **************************************************************
      [info] Single thread, 1,000,000 iterations
      [info] **************************************************************
      [info] basic_st         Elapsed: 0.17 secs        5,777,626/sec
      [info] rotating_st      Elapsed: 0.18 secs        5,475,894/sec
      [info] daily_st         Elapsed: 0.20 secs        5,062,659/sec
      [info] empty_logger     Elapsed: 0.07 secs       14,127,300/sec
      [info] **************************************************************
      [info] C-string (400 bytes). Single thread, 1,000,000 iterations
      [info] **************************************************************
      [info] basic_st         Elapsed: 0.41 secs        2,412,483/sec
      [info] rotating_st      Elapsed: 0.72 secs        1,389,196/sec
      [info] daily_st         Elapsed: 0.42 secs        2,393,298/sec
      [info] null_st          Elapsed: 0.04 secs       27,446,957/sec
      [info] **************************************************************
      [info] 10 threads, competing over the same logger object, 1,000,000 iterations
      [info] **************************************************************
      [info] basic_mt         Elapsed: 0.60 secs        1,659,613/sec
      [info] rotating_mt      Elapsed: 0.62 secs        1,612,493/sec
      [info] daily_mt         Elapsed: 0.61 secs        1,638,305/sec
      [info] null_mt          Elapsed: 0.16 secs        6,272,758/sec
      
  • 其他

    • spdlog:支持异步模式


Q:我留意到了log4cpp的开源平台不在github而在sourceforce上,这个平台我偶尔见过但远不如github用得多,为什么会有的人选择在sourceforce这个平台上开源?该平台相较于其他有什么好的功能或优势吗


SourceForge 是一个为开源项目提供托管服务的平台,创建于 1999 年,比 GitHub 更早。在 GitHub 成为主流的开源代码托管平台之前,SourceForge 是最受欢迎的托管平台之一。许多早期的开源项目都选择在 SourceForge 上托管,包括 log4cpp。

相较于 GitHub,SourceForge 提供了一些不同的功能和优势:

  1. 长期稳定性:SourceForge 有着较长的历史和稳定的运营,对于那些已经在 SourceForge 上建立的项目,维持现状可能是一个稳妥的选择。
  2. 项目下载统计:SourceForge 提供了详细的项目下载统计,方便开发者了解其项目的受欢迎程度和下载趋势。
  3. 镜像站点:SourceForge 提供了全球镜像站点,可以加速项目的下载速度,为用户提供更好的下载体验。

然而,随着 GitHub 和 GitLab 等现代代码托管平台的出现和普及,SourceForge 的优势逐渐减弱。这些新平台提供了更强大的功能,如更好的版本控制、协作工具、持续集成/持续部署(CI/CD)以及更活跃的开发者社区。许多项目已经从 SourceForge 迁移到了 GitHub 或其他平台,以获得更好的支持和参与度。

总之,SourceForge 曾是开源项目托管的主流选择,但随着 GitHub 和其他现代平台的兴起,它的地位逐渐被削弱。尽管如此,一些早期的项目可能仍然会继续在 SourceForge 上托管,以保持稳定性和向后兼容性。