目录
1.引言
2.使用工厂函数记录日志记录器
3.使用spdlog::get(“...”)访问记录器
4.创建旋转文件记录器
5.创建异步记录器
6.手动创建记录器
7.创建具有多个接收器的记录器
8.使用相同的输出文件创建多个文件记录器
1.引言
每个记录器都包含一个或多个std::shared_ptr<spdlog::sink>的向量。
在每次日志调用时(如果日志级别正确),记录器将调用每个日志的sink(log_msg)函数。
spdlog的接收器具有_mt(多线程)或_st(单线程)后缀,以指示线程安全性。虽然单线程接收器不能同时从多个线程中使用,但由于没有使用锁定,它们可能会更快。
2.使用工厂函数记录日志记录器
// 创建并返回一个多线程控制台日志记录器的 shared_ptr。
#include "spdlog/sinks/stdout_color_sinks.h"
auto console = spdlog::stdout_color_mt("some_unique_name");
这将创建一个控制台记录器,在spdlog的全局注册表中注册它,id为“some_unique_name”,并将其作为shared_ptr返回。
3.使用spdlog::get(“...”)访问记录器
使用线程安全的spdlog::get(“logger_name”)可以从任何地方访问记录器,它返回一个共享指针。
注意:spdlog::get可能会减慢代码的速度,因为它锁定了一个互斥体,因此请谨慎使用。建议保存返回的shared_ptr<spdlog::logger>并直接使用它,至少在热代码路径中是这样。
一个好的方法是在构造函数中设置一个shared_ptr<spdlog::logger>类型的私有成员:
class MyClass
{
private:
std::shared_ptr<spdlog::logger> _logger;
public:
MyClass()
{
//set _logger to some existing logger
_logger = spdlog::get("some_logger");
//or create directly
//_logger = spdlog::rotating_file_logger_mt("my_logger", ...);
}
};
注2:手动创建的记录器(即您直接构建的记录器,请参阅手动创建记录器)不会自动注册,也不会被get(“…”)调用找到。
如果要注册此类记录器,请使用register_logger(…)函数:
spdlog::register_logger(my_logger);
...
auto the_same_logger = spdlog::get("mylogger");
4.创建旋转文件记录器
//Create rotating file multi-threaded logger
#include "spdlog/sinks/rotating_file_sink.h"
auto file_logger = spdlog::rotating_logger_mt("file_logger", "logs/mylogfile", 1048576 * 5, 3);
...
auto same_logger= spdlog::get("file_logger");
5.创建异步记录器
#include "spdlog/async.h"
void async_example()
{
// 在创建异步记录器之前,可以修改默认线程池设置:
// spdlog::init_thread_pool(8192, 1); // 队列包含8k个项目和1个支持线程。
auto async_file = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/async_log.txt");
// alternatively:
// auto async_file = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("async_file_logger", "logs/async_log.txt");
}
对于异步日志记录,spdlog使用具有专用消息队列的共享全局线程池。
为此,它在消息队列中创建了固定数量的预分配插槽(64位中每个插槽约256字节),并且可以使用spdlog::init_thread_pool(queue_size,backing_threads_count)进行修改。
当尝试记录消息并且队列已满时,调用者将阻塞(默认行为),直到插槽可用(默认),或者立即用新消息溢出队列中最旧的消息(如果记录器是用async_overflow_policy==overrun_oldest构造的)。
6.手动创建记录器
auto sink = std::make_shared<spdlog::sinks::stdout_sink_mt>();
auto my_logger = std::make_shared<spdlog::logger>("mylogger", sink);
// 可选择注册记录器。只有当你想用spdlog::get(“mylogger”)访问它时,才需要这样做spdlog::get("mylogger")
spdlog::register_logger(my_logger);
7.创建具有多个接收器的记录器
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back(std::make_shared<spdlog::sinks::stdout_sink_st>());
sinks.push_back(std::make_shared<spdlog::sinks::daily_file_sink_st>("logfile", 23, 59));
auto combined_logger = std::make_shared<spdlog::logger>("name", begin(sinks), end(sinks));
//register it if you need to access it globally
spdlog::register_logger(combined_logger);
8.使用相同的输出文件创建多个文件记录器
如果你想让不同的记录器写入同一个输出文件,它们必须共享同一个接收器。否则,你可能会得到奇怪的结果。
auto sharedFileSink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("fileName.txt");
auto firstLogger = std::make_shared<spdlog::logger>("firstLoggerName", sharedFileSink);
auto secondLogger = std::make_unique<spdlog::logger>("secondLoggerName", sharedFileSink);