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, &