C++中spdlog的简单使用示例
作者:二次元攻城狮
spdlog是一个开源、跨平台、无依赖、只有头文件的C++11日志库,所以这篇文章主要来和大家介绍一下一个简单的spdlog使用示例,感兴趣的小伙伴可以了解一下
spdlog是一个开源、跨平台、无依赖、只有头文件的C++11日志库,网上介绍的文章有很多这里就不过多的介绍了,GitHub链接:https://github.com/gabime/spdlog。
引用源码
先下载spdlog的源码,将源码的include文件夹复制到自己的项目文件夹下:
然后在项目属性中包含include目录,如下图所示:
封装Log头文件
一般的项目对日志要求都不高,主要是要求日志线程安全、异步写入文件、每天生成新日志、支持日志回调显示,spdlog稍微配置一下即可。
把spdlog相关的配置全放到Log.h文件中,封装成Log头文件有两个好处:
- 可以随时替换后台日志实现
- 对外只用暴露一个头文件
Log头文件的代码如下:
#pragma once #include "spdlog/spdlog.h" #include "spdlog/async.h" #include "spdlog/sinks/daily_file_sink.h" #include "spdlog/stopwatch.h" #include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/sinks/callback_sink.h" #include <iostream> void init_spdlog() { //异步日志,具有8k个项目和1个后台线程的队列 spdlog::init_thread_pool(8192, 1); //标准控制台输出 auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt >(); stdout_sink->set_level(spdlog::level::debug); //日志文件输出,0点0分创建新日志 auto file_sink = std::make_shared<spdlog::sinks::daily_file_sink_mt>("logs/log.txt", 0, 0); file_sink->set_level(spdlog::level::info); //日志回调 auto callback_sink = std::make_shared<spdlog::sinks::callback_sink_mt>([](const spdlog::details::log_msg& msg) { //日志记录器名称 std::string name(msg.logger_name.data(), 0, msg.logger_name.size()); //日志消息 std::string str(msg.payload.data(), 0, msg.payload.size()); //日志时间 std::time_t now_c = std::chrono::system_clock::to_time_t(msg.time); //回调的处理逻辑自己根据项目情况定义,比如实时显示到UI、保存到数据库等等 //.... 回调处理逻辑的示例 //std::tm localTime; //localtime_s(&localTime, &now_c); //char timeStr[50]; //std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &localTime); //// 获取毫秒数 //auto duration = msg.time.time_since_epoch(); //auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() % 1000; //std::cout << timeStr << "." << std::setfill('0') << std::setw(3) << milliseconds << " " ; //std::cout << to_string_view(msg.level).data() << " " << str << std::endl << std::endl << std::flush; }); callback_sink->set_level(spdlog::level::info); std::vector<spdlog::sink_ptr> sinks{ stdout_sink, file_sink,callback_sink }; auto log = std::make_shared<spdlog::async_logger>("logger", sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block); //设置日志记录级别,您需要用 %^ 和 %$ 括上想要彩色的部分 log->set_level(spdlog::level::trace); //设置格式 //参考 https://github.com/gabime/spdlog/wiki/3.-Custom-formatting //[%Y-%m-%d %H:%M:%S.%e] 时间 //[%l] 日志级别 //[%t] 线程 //[%s] 文件 //[%#] 行号 //[%!] 函数 //[%v] 实际文本 log->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %^[%l]%$ [%t] [%s %!:%#] %v"); //设置当出发 err 或更严重的错误时立刻刷新日志到 disk log->flush_on(spdlog::level::err); //3秒刷新一次队列 spdlog::flush_every(std::chrono::seconds(3)); spdlog::set_default_logger(log); } //单个日志记录器 std::shared_ptr<spdlog::logger> get_async_file_logger(std::string name) { auto log = spdlog::get(name); if (!log) { //指针为空,则创建日志记录器, log = spdlog::daily_logger_mt<spdlog::async_factory>(name, "logs/" + name + "/log.txt"); log->set_level(spdlog::level::trace); log->flush_on(spdlog::level::err); log->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %^[%l]%$ [%t] [%s %!:%#] %v"); //记录器是自动注册的,不需要手动注册 spdlog::register_logger(name); } return log; } #define INITLOG() init_spdlog() #define TRACE(...) SPDLOG_TRACE(__VA_ARGS__) #define DEBUG(...) SPDLOG_DEBUG(__VA_ARGS__) #define INFO(...) SPDLOG_INFO(__VA_ARGS__) #define WARN(...) SPDLOG_WARN(__VA_ARGS__) #define ERROR(...) SPDLOG_ERROR(__VA_ARGS__) #define CRITICAL(...) SPDLOG_CRITICAL(__VA_ARGS__) //单个日志文件 #define GETLOG(LOG_NAME) get_async_file_logger(LOG_NAME) #define LOGGER_TRACE(logger,...) SPDLOG_LOGGER_TRACE(logger,__VA_ARGS__) #define LOGGER_DEBUG(logger,...) SPDLOG_LOGGER_DEBUG(logger,__VA_ARGS__) #define LOGGER_INFO(logger,...) SPDLOG_LOGGER_INFO(logger,__VA_ARGS__) #define LOGGER_WARN(logger,...) SPDLOG_LOGGER_WARN(logger,__VA_ARGS__) #define LOGGER_ERROR(logger,...) SPDLOG_LOGGER_ERROR(logger,__VA_ARGS__) #define LOGGER_CRITICAL(logger,...) SPDLOG_LOGGER_CRITICAL(logger,__VA_ARGS__) //时间统计宏 #define LOGSW() spdlog::stopwatch()
上面的代码是用于初始化和配置spdlog库的日志记录器的代码。主要包括以下几个部分:
- init_spdlog()函数用于初始化spdlog库的配置。该函数创建了一个包含控制台、文件和回调三种sink的日志记录器,并设置将其设置为默认记录器。
- get_async_file_logger()函数获取一个单独的异步文件日志记录器,主要用于记录多线程日志,一般情况下用的比较少。
- 用于简化日志记录的操作一些宏,spdlog自带的有日志宏,这里只是简化一下并做隔离,实际上是对spdlog库的相应函数进行了封装。
- 定义了一个LOGSW()宏,用于方便地创建一个时间统计器,使用时不需要过多的关注统计类本身。
使用方法
使用方法如下:
#include "Log.h" #include <thread> #include <chrono> #include <iostream> int main() { INITLOG("path"); //单个日志 auto log1= GETLOG("Test1"); auto log2= GETLOG("Test1"); //原始调用方式 //SPDLOG_LOGGER_INFO(log1, "123"); LOGGER_INFO(log2, "123"); auto sw = LOGSW(); // 延时2秒 std::this_thread::sleep_for(std::chrono::seconds(2)); INFO("Elapsed {0} {1}","时间", sw); WARN("Elapsed {0} {1}", "时间", sw); //原始调用方式 //SPDLOG_INFO("TEST"); INFO("TEST"); }
最后生成的日志文件如下:
到此这篇关于C++中spdlog的简单使用示例的文章就介绍到这了,更多相关C++ spdlog内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!