0. spdlog简单介绍
spdlog 是一个快速的 C++ 日志库,只包含头文件,兼容 C++11。项目地址
特性:
非常快
只包含头文件
无需依赖第三方库
支持跨平台 – Linux / Windows on 32/64 bits
支持多线程
可对日志文件进行循环输出
可每日生成日志文件
支持控制台日志输出
可选的异步日志
支持日志输出级别
可自定义日志格式
上述内容来源于 开源中国关于spdlog的介绍)
1. sinks
在spdlog中,sink指向实际的输出目标,例如
stdout
sysloglinux系统日志)
ostream
file
…
代码路径: spdlog-master/include/spdlog/sinks
1.1 sink
class sink
{
public:
sink)
{
_level = level::trace;
}
virtual ~sink) {}
virtual void logconst details::log_msg& msg) = 0;
virtual void flush) = 0;
bool should_loglevel::level_enum msg_level) const;
void set_levellevel::level_enum log_level);
level::level_enum level) const;
private:
level_t _level;
};
sink类的两个纯虚函数 log flush 是子类需要实现的接口。
1.2 base_sink
没啥好说的直接上代码,这里仅列出主要内容。
template<class Mutex>
class base_sink:public sink
{
public:
//.....
void logconst details::log_msg& msg) override
{
std::lock_guard<Mutex> lock_mutex);
_sink_itmsg);
}
protected:
virtual void _sink_itconst details::log_msg& msg) = 0;
Mutex _mutex;
};
模板类**base_sink继承sink,同时实现了log接口,通过Mutex决定类是工作在单线程
还是多线程下。而子类通过实现接口_sink_it输出日志。
在spdlog中,如果在多线程中base_sink形式如下:
base_sink<std::mutex>;
单线程:
base_sink<spdlog::details::null_mutex>;
而null_mutex什么都不做。
1.3 rotating_file_sink
通过文件饶接这个例子看下在spdlog中具体的sink是怎么实现的。
template<class Mutex>
class rotating_file_sink : public base_sink < Mutex >
{
public:
//......
protected:
void _sink_itconst details::log_msg& msg) override
{
_current_size += msg.formatted.size);
if _current_size > _max_size)
{
_rotate);
_current_size = msg.formatted.size);
}
_file_helper.writemsg);
}
private:
//......
void _rotate)
{
for auto i = _max_files; i > 0; --i)
{
// 修改文件名,转储文件
//......
}
//......
};
typedef rotating_file_sink<std::mutex> rotating_file_sink_mt;
typedef rotating_file_sink<details::null_mutex>rotating_file_sink_st;
_sink_it实现了在文件超过限制后通过_rotate转储文件,同时使用文件进行输出。输出的对象是msg
实际的日志内容)。
代码的最后两行分别定义了rotating_file_sink_mt和rotating_file_sink_st。前者使用在多线程中,
后者使用在单线程。其中的区别在1.2中已经说明。