这里写自定义目录标题
- 封装的原因
- 封装的思想
- 初始化接口的封装
- 对日志输出接口进行宏的封装
封装的原因
1.避免单例的锁冲突,因此直接创建全局的线程安全的日志器进行使用
2.因为日志输出没有文件名行号,因此使用宏进行二次封装输出日志的文件名和行号
3.封装出一个初始化接口,便于使用:调试模式则输出到标准输出,否则输出到文件中
封装的思想
封装出一个全局接口,用户进行日志器的创建与初始化
1.初始化接口接收一个参数:运行模式-bool
2.初始化接口接收一个参数:输出文件名 – 用于发布模式
3.初始化接口接收一个参数:输出日志等级 – 用于发布模式
对日志输出的接口,进行宏的封装,加入文件名行号的输出
初始化接口的封装
std::shared_ptr<spdlog::logger> g_default_logger; // 全局的日志器对象
// mode - 运行模式: true-发布模式; false调试模式
void init_logger(bool mode, const std::string &file, int32_t level)
{
if (mode == false)
{
// 如果是调试模式,则创建标准输出日志器,输出等级为最低
g_default_logger = spdlog::stdout_color_mt("default-logger");
g_default_logger->set_level(spdlog::level::trace);
g_default_logger->flush_on(spdlog::level::level_enum::trace);
}
else
{
// 否则是发布模式,则创建文件输出日志器,输出等级根据参数而定
g_default_logger = spdlog::basic_logger_mt("default-logger", file);
g_default_logger->set_level((spdlog::level::level_enum)level);
g_default_logger->flush_on((spdlog::level::level_enum)level);
}
g_default_logger->set_pattern("[%n][%H:%M:%S][%t][%-8l]%v");
}
spdlog::stdout_color_mt是创建一个同步的标准输出日志器,他会返回一个 std::shared_ptr< spdlog::logger > 的智能指针对象。
basic_logger_mt是创建一个文件输出日志器,第一个参数是指定日志器的名称,第二个参数是指定日志器输出的文件路径。该日志器也是同步的。
如果需要创建异步日志器,则需要显示指定模板类型basic_logger_mt<spdlog::async_factory > 这样创建的日志器就是异步日志器。
set_level是设置日志输出等级,只有在这个等级及以上的日志才会进行输出,这里的trace是最低的等级,及所有日志都会输出。
flush_on(level)表示当日志输出达到这个级别时,日志会被立即刷新到目标,而不是存在缓存中。
std_pattern则是设置日志输出格式,%n为日志器名称,
%H%M%S代表时分秒,
%t代表线程ID,
%l为日志等级,这里加上-8是为了方便观看日志,8是站8个字符,-是左对齐,。
%v是 要打印的内容
对日志输出接口进行宏的封装
#define LOG_TRACE(format, ...) g_default_logger->trace(std::string("[{}:{}] ") + format, __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_DEBUG(format, ...) g_default_logger->debug(std::string("[{}:{}] ") + format, __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_INFO(format, ...) g_default_logger->info(std::string("[{}:{}] ") + format, __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_WARN(format, ...) g_default_logger->warn(std::string("[{}:{}] ") + format, __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_ERROR(format, ...) g_default_logger->error(std::string("[{}:{}] ") + format, __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_FATAL(format, ...) g_default_logger->critical(std::string("[{}:{}] ") + format, __FILE__, __LINE__, ##__VA_ARGS__)
使用方法:
init_logger(true,"log.txt",2);
LOG_TRACE("你好,{}","雷康明");
LOG_DEBUG("你好,{}","雷康明");
LOG_INFO("你好,{}","雷康明");
LOG_WARN("你好,{}","雷康明");
LOG_ERROR("你好,{}","雷康明");
LOG_FATAL("你好,{}","雷康明");
spdlog中不是用%d,%s,而是使用{}来代表一个类型。
这里的"你好,{}“,就传递给了format,后面的”雷康明“就传递给了…
而这里面的两个{},被替换成了文件名和行号.
g_default_logger->trace(std::string("[main.cc:10] ") + format, __FILE__, __LINE__, ##__VA_ARGS__)
在拼接上format就变成了
“[main.cc:10] 你好,雷康明”,这段字符串就是我们上面设置的set_pattern中的%v。
最后完整的日志打印为