如何在代码中启用/禁用 spdlog 日志记录?

Posted

技术标签:

【中文标题】如何在代码中启用/禁用 spdlog 日志记录?【英文标题】:How to enable/disable spdlog logging in code? 【发布时间】:2017-08-10 19:23:43 【问题描述】:

我正在我的应用程序中创建 c++ 库模块。要进行日志记录,我使用spdlog。但在生产环境中,我不希望我的 lib 模块进行任何日志记录。实现打开/关闭的一种方法是在我的代码中乱扔#ifdef 条件,例如...

#ifdef logging
  // call the logger here.
#endif

我正在寻找一种方法来避免编写这些条件。可能是一个包装函数,它执行#ifdef 检查并编写它。但是这种方法的问题是我必须为每个日志记录方法(例如 info、trace、warn、error ......)编写包装器

有没有更好的办法?

【问题讨论】:

查看github.com/gabime/spdlog/wiki/1.-QuickStart#debugtrace-macros 【参考方案1】:

您可以使用set_level() 禁用日志记录:

auto my_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic.txt");

#if defined(PRODUCTION)
    my_logger->set_level(spdlog::level::off);
#else
    my_logger->set_level(spdlog::level::trace);
#endif

spdlog::register_logger(my_logger);

【讨论】:

【参考方案2】:

您可以在编译代码之前通过添加以下宏(在包括 spdlog.h 之前)禁用所有日志记录:

#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_OFF
#include<spdlog.h>

在文件https://github.com/gabime/spdlog/blob/v1.x/include/spdlog/spdlog.h中解释为注释:

//
// enable/disable log calls at compile time according to global level.
//
// define SPDLOG_ACTIVE_LEVEL to one of those (before including spdlog.h):
// SPDLOG_LEVEL_TRACE,
// SPDLOG_LEVEL_DEBUG,
// SPDLOG_LEVEL_INFO,
// SPDLOG_LEVEL_WARN,
// SPDLOG_LEVEL_ERROR,
// SPDLOG_LEVEL_CRITICAL,
// SPDLOG_LEVEL_OFF
//

使用此宏还可以加快您的高效代码,因为日志记录调用已从您的代码中完全删除。因此这种方法可能比使用my_logger-&gt;set_level(spdlog::level::off);

但是,为了使完整的代码删除工作,您需要在记录时使用任一宏:

SPDLOG_LOGGER_###(logger, ...)

SPDLOG_###(...)

其中###TRACEDEBUGINFOWARNERRORCRITICAL 之一。

后一个宏使用默认记录器spdlog::default_logger_raw(),前者可以与您的自定义记录器一起使用。可变参数... 代表日志调用的常规参数:fmt 字符串,后跟一些要拼接到消息中的值。

【讨论】:

不知道是不是老版本,但是要写TRACE和DEBUG(其他关卡不行),需要在代码中加上spdlog::set_level(spdlog::level::###); @Kafka:没错。宏 SPDLOG_ACTIVE_LEVEL 在编译时设置“最高可用日志级别”。在运行时实际记录的级别仍然受您的记录器实例在运行时选择的内容的影响(例如,通过“spdlog::set_level”)。换句话说,您的最终日志级别将始终是 SPDLOG_ACTIVE_LEVEL 的最大值以及您使用“spdlog::set_level”设置的级别。由于后者的默认级别是 INFO,因此您没有看到 DEBUG 和 TRACE 消息。【参考方案3】:

我不知道 spdlog。

但是,您可以在常用的包含文件之一中定义一个宏,以将 logcall 替换为空,或者调用编译器优化器将消除的空内联函数。

在“app.h”中

#ifndef LOG

#ifdef logging
#define LOG spdlog
#endif

#ifndef logging
#define LOG noop
#endif

#endif

你明白了吗?

这让您的大部分代码保持不变

【讨论】:

是的,谢谢。正如我所检查的,它适用于普通功能。但是如果 spdlog 是一个具有成员 fns(如 trace()、info() 等)的类,则它不会编译。 我认为这种方法也应该适用于类。请记录您当前代码的外观。也许我或其他人会为您提供其他方法

以上是关于如何在代码中启用/禁用 spdlog 日志记录?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中启用/禁用日志级别?

如何在 Android 上启用/禁用蓝牙硬件初始化日志记录?

使用 spdlog (C++) 记录,记录器未将日志写入文件

带有 gtest 框架的 Spdlog 记录器无法正常工作

使用 syslog 时禁用/启用日志记录

如何将 Windows 调试记录器附加到 spdlog