目录
介绍
二次封装
介绍
spdlog 是C++开源的第三方日志库,整个项目在 spdlog 命名空间中。
在 spdlog 命名空间的 level 命名空间里定义了枚举类型,把日志分为了 5 个等级:trace debug info warn err critical
enum level_enum : int {trace = SPDLOG_LEVEL_TRACE,debug = SPDLOG_LEVEL_DEBUG,info = SPDLOG_LEVEL_INFO,warn = SPDLOG_LEVEL_WARN,err = SPDLOG_LEVEL_ERROR,critical = SPDLOG_LEVEL_CRITICAL,off = SPDLOG_LEVEL_OFF,n_levels};
spdlog::logger 类是基类(是整个项目其他日志类的基类)。spdlog::spdlog::async_logger 类是异步日志类。不过我们用该项目的时候不直接使用类实例化对象,而是用工厂类帮我们实例化对象。
那么我们现在只需认识 spdlog::logger 类的几个接口即可
//设置日志输出最低等级,参数为 spdlog::level::level_enumvoid set_level();//以什么等级输出日志,参数为要输出的内容(字符串)void trace()void debug()void info()void warn()void error()void critical()
在 spdlog 项目中,占位符用 {}
几个重要的全局接口
//输出等级设置接口
void set_level(level::level_enum log_level);
//日志刷新策略-每隔 N 秒刷新一次
void flush_every(std::chrono::seconds interval)
//日志刷新策略-触发指定等级立即刷新
void flush_on(level::level_enum log_level);
工厂类的接口就不介绍了,可以到项目源码的下面查看,作者给出了很多详细示例。工厂类的返回值为 std::shared_ptr<spdlog::logger> ,也就是智能指针指向基类,用智能指针管理日志类资源。
GitHub - gabime/spdlog: Fast C++ logging library.
二次封装
代码如下
#include <spdlog/spdlog.h>
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
#include <chrono> //C++ 标准库namespace LOG
{std::shared_ptr<spdlog::logger> log_ptr;bool init_logger_ok = false;//mode 为 true 表示在调试模式下输出日志,trace 等级以上的日志全部输出,且输出到显示器上,否则就是在发布模式下输出日志,只会输出 level 及以上等级的日志//interval 表示多少毫秒刷新一次日志//flie_path 表示发布模式下,异步日志刷新到哪个文件里void init_logger( bool mode = true, int interval = 1000, spdlog::level::level_enum level = spdlog::level::level_enum::trace, std::string flie_path = "test.log"){//间隔多长时间刷新一次spdlog::flush_every(std::chrono::duration<double, std::ratio<1, 1000>>(interval));//触发指定等级立即刷新spdlog::flush_on(spdlog::level::level_enum::err);spdlog::flush_on(spdlog::level::level_enum::critical);if(true == mode){//在调试模式下输出日志log_ptr = spdlog::stderr_color_mt("stdout_logger");log_ptr->set_level(level); }else{//在运行模式下,采用异步日志的方式log_ptr = spdlog::basic_logger_mt<spdlog::async_factory>("async_logger", flie_path);log_ptr->set_level(level);}//设置输出格式log_ptr->set_pattern("%H:%M:%S [%n][%-7l]%v");init_logger_ok = true;}#define LOG_DEBUG(format, ...) false == LOG::init_logger_ok ? throw "未初始化日志" : LOG::log_ptr->debug(std::string("[{:>10s}:{:<4d}] ")+format, __FILE__, __LINE__, ##__VA_ARGS__)#define LOG_INFO(format, ...) false == LOG::init_logger_ok ? throw "未初始化日志" : LOG::log_ptr->info(std::string("[{:>10s}:{:<4d}] ")+format, __FILE__, __LINE__, ##__VA_ARGS__)#define LOG_WARN(format, ...) false == LOG::init_logger_ok ? throw "未初始化日志" : LOG::log_ptr->warn(std::string("[{:>10s}:{:<4d}] ")+format, __FILE__, __LINE__, ##__VA_ARGS__)#define LOG_ERROR(format, ...) false == LOG::init_logger_ok ? throw "未初始化日志" : LOG::log_ptr->error(std::string("[{:>10s}:{:<4d}] ")+format, __FILE__, __LINE__, ##__VA_ARGS__)
}
用 LOG::init_logger 初始化日志类,可以选择两种模式:
调试模式:同步的方式输出日志,最低日志等级为 trace 。
发布模式:异步方式输出日志,最低输出日志等级自己决定。
std::chrono::duration<double, std::ratio<1, 1000>> 表示间隔多少个 1 / 1000 秒。
常见的输出格式如下:
%t - 线程 ID(Thread ID)。 |
%n - 日志器名称(Logger name)。 |
%l - 日志级别名称(Level name),如 INFO, DEBUG, ERROR 等。 |
%v - 日志内容(message)。 |
%Y - 年(Year)。 |
%m - 月(Month)。 |
%d - 日(Day)。 |
%H - 小时(24-hour format)。 |
%M - 分钟(Minute)。 |
%S - 秒(Second)。 |
在使用时要链接两个库,makefile 如下示例
main : main.ccg++ -std=c++17 $^ -o $@ -lspdlog -lfmt