主要由logger(记录器)和sink(接收器)两部分组成。
spdlog的高可拓展体现在logger和sink的可由用户自定义。
主要关注几个要点:
logger类型
输出格式(fmt)
日志队列的容量及线程数(并行下的日志顺序问题)
日志级别(level)
flush时机
对于sink主要关注输出位置
spdlog内部为每个进程都维护一张全局Logger记录表,记载了用户每个进程中通过factory method
创建的Logger实例(某些情况需要用户手动注册)。因而,在使用Logger时极其方便,只需要知道创建时指定的名称即可。
因此,我们可以通过工厂方法创建一个名为async_file_logger异步Logger,输出到/logs/async_log.txt
auto async_file = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/async_log.txt");
在需要用的get
auto logger = spdlog::get("async_file_logger");
logger->info("some things want to say.");
在默认情况下,spdlog为我们设置了写到标准输出的logger,
我们可以通过set_default_logger进行调整
spdlog::set_default_logger(some_other_logger);
一般情况下,我们需要Logger同时具备日志切割及异步输出的功能,在spdlog中我们可以使用factory methd —— rotating_logger_mt
更多具体的例子请参考spadlog wiki, 里面的具有丰富的sample、tutorial、api描述以及注意事项,比log4cpp要健全得多。
拥有完善的文档是对所有开发者最大的敬意。
主要实现以下功能
#define DEBUG
#include "log.h"
int main(void) {
init_logger();
// ... ...
spdlog::info("Log Demo");
return 0;
}
#ifdef DEBUG
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
// #define SPDLOG_DEBUG_ON
#endif
#include <spdlog/spdlog.h>
#include <spdlog/async.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
/* basic */
constexpr const char* filename = "logs/log.txt";
/* rotating file config */
constexpr int file_size = 10*1024*1024; // 10M
constexpr int back_count = 5;
/* async sink config */
constexpr int task_count = 1024 * 8;
constexpr int tp_size = 1;
static inline void init_logger(){
// create console_sink
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::warn);
// create rotating file sink
auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(filename, file_size, back_count, false);
#ifdef DEBUG
file_sink->set_level(spdlog::level::debug);
#else
file_sink->set_level(spdlog::level::info);
#endif
// sink's bucket
spdlog::sinks_init_list sinks{console_sink, file_sink};
// create async logger, and use global threadpool
spdlog::init_thread_pool(task_count, tp_size);
auto logger = std::make_shared<spdlog::async_logger>("aslogger", sinks, spdlog::thread_pool());
// ajust level.
#ifdef DEBUG
logger->set_level(spdlog::level::debug);
#else
logger->set_level(spdlog::level::info);
#endif
spdlog::register_logger(logger);
spdlog::set_default_logger(logger);
}
若你希望看到DEBUG或是TRACE级别的信息,你需要使用以下东西:
// 或 SPDLOG_LEVEL_TRACE
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
// 或 spdlog::set_level(spdlog::level::trace);
spdlog::set_level(spdlog::level::debug);
经过笔者测试(TRACE也是同理,不多赘述)
spdlog::set_level(spdlog::level::debug)
而不设置宏SPDLOG_ACTIVE_LEVEL
时,spdlog::debug()
spdlog::set_level(spdlog::level::debug)
并设置SPDLOG_ACTIVE_LEVEL
spdlog::debug()
SPDLOG_DEBUG()
SPDLOG_LOGGER_DEBUG()
SPDLOG_ACTIVE_LEVEL
为DEBUG级别时,所有DEBUG及以下级别的输出都将被忽略。注意: 如果你使用spdlog::set_level
,而且是手动构造的logger,那么最好将logger先通过spdlog::register_logger
将相应的logger注册到全局表中。因为,在通常的情况下,形如spdlog::*
的相关设置只会影响已经注册到全局表中的logger。相似的,spdlog::initialzie_logger
被用于设置log level和 formatter(输出格式)的同时将logger注册到全局表中。
参考: spdlog::set_default_logger(logger) will cause spdlog::set_level(spdlog::level::debug) to fail