一、简介
spdlog是基于C++ 11的日志组件,它非常轻量,使用时你仅仅需要引入头文件就可以了。
https://github.com/gabime/spdlog
https://github.com/gabime/spdlog/wiki/3.-Custom-formatting
二、线程安全
命名空间 spdlog:: 下面的大多数方法是线程安全的。已知以下三个是线程不安全的,使用时请注意:
void spdlog::set_pattern(const std::string&);
void spdlog::set_formatter(formatter_ptr);
void spdlog::set_error_handler(log_err_handler);
日志对象的大部分方法也是线程安全的,除了以下三个:
void spdlog::logger::set_pattern(const std::string&);
void spdlog::logger::set_formatter(formatter_ptr);
void spdlog::set_error_handler(log_err_handler);
三、使用示例
函数名带后缀_mt的意思是multi thread(速度稍微慢一点点,考虑了多线程并发),_st的意思是single thread(速度较块)。所有以_mt结尾的SINK都是线程安全的,以_st结尾的则不是。
#include "spdlog/spdlog.h"
auto console = spdlog::stdout_color_mt( "console" );
auto logger = spdlog::basic_logger_mt("basic_logger", "logs/basic.txt");
auto logger = spdlog::rotating_logger_mt("file_logger", "myfilename", 1024 * 1024 * 5, 3);
spdlog::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
auto daily_sink = std::make_shared<spdlog::sinks::daily_file_sink_mt>("logfile", 23, 59);
auto net_logger = std::make_shared<spdlog::logger>("net", daily_sink);
auto hw_logger = std::make_shared<spdlog::logger>("hw", daily_sink);
auto db_logger = std::make_shared<spdlog::logger>("db", daily_sink);
std::vector<spdlog::sink_ptr> sinks;
sinks.push_back( std::make_shared<spdlog::sinks::stdout_sink_st>());
sinks.push_back( std::make_shared<spdlog::sinks::daily_file_sink_st>( "logfile", 23, 59 ));
auto combined_logger = std::make_shared<spdlog::logger>( "name", begin( sinks ), end( sinks ));
spdlog::register_logger( combined_logger );
spdlog::set_async_mode(8192);
spdlog::register_logger(net_logger);
auto logger = spdlog::get(net_logger);
console->set_level(spdlog::level::debug);
console->debug("Hello World") ;
console->info("Hello {}" ,"World");
console->warn("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);
console->info("Support for floats {:03.2f}", 1.23456);
console->error("{:<30}", "left aligned");
console->info("Positional args are {1} {0}..", "too", "supported");
#include <spdlog/fmt/ostr.h>
std::ostream& operator<<(std::ostream& os, const Duck& duck){
return os << duck.getName();
console->info("custom class with operator<<: {}..", duck);
四、我个人的使用示例
#define SPDLOG_NAME "SmartDispenser"
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE
#include <spdlog/spdlog.h>
#include <spdlog/sinks/rotating_file_sink.h>
bool CInitSoft::initLog(void)
CString strFilePath = FILEMANAGE->GetLogsDir() + _T("\\logApp.txt");
std::string logpath = CT2A(strFilePath.GetBuffer());
strFilePath.ReleaseBuffer();
auto rotating_logger = spdlog::rotating_logger_mt(SPDLOG_NAME, logpath, 1024 * 1024 * 1, 3);
spdlog::set_default_logger(rotating_logger);
rotating_logger->set_level(spdlog::level::debug);
rotating_logger->set_pattern("[%Y-%m-%d %H:%M:%S.%e][thread %t][%@,%!][%l] : %v");
rotating_logger->debug("test1");
spdlog::get(SPDLOG_NAME)->info("test2");
SPDLOG_LOGGER_DEBUG(rotating_logger, "test3 {}", 3);
SPDLOG_LOGGER_DEBUG(rotating_logger, "test4 {}", a);
catch (const spdlog::spdlog_ex& ex)
std::cout << "Log initialization failed: " << ex.what() << std::endl;
info.Format(_T("log init failed: %s\n"), ex.what());
addInitInfo(theApp.MyMsgString(_T("日志初始化失败!"), info));
请重点关注:
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE//必须定义这个宏,才能输出文件名和行号
SPDLOG_LOGGER_DEBUG(rotating_logger, "test3 {}", 3);//会输出文件名和行号
五、姊妹篇
《Qt日志重定向qInstallMessageHandler,输出至文件及网络》
《Qt日志库Log4Qt的使用,支持文件名/行号/函数名的打印输出》