基于C++ spdlog日志库的完善封装

spdlog是一个C++编写的极速日志打印库,支持异步写日志以及多种模式和格式化选项。以下基于spdlog库封装了一个简单易用的功能类,采用的是header-only方式,便于项目集成。

代码

#pragma once
#include 
#include 
#include 
#include 
#include 
#include "spdlog/spdlog.h"
#include "spdlog/async.h"
#include "spdlog/sinks/stdout_color_sinks.h" // or "../stdout_sinks.h" if no color needed
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"static inline int NowDateToInt()
{time_t now;time(&now);// choose thread save version in each platformtm p;
#ifdef _WIN32localtime_s(&p, &now);
#elselocaltime_r(&now, &p);
#endif // _WIN32int now_date = (1900 + p.tm_year) * 10000 + (p.tm_mon + 1) * 100 + p.tm_mday;return now_date;
}static inline int NowTimeToInt()
{time_t now;time(&now);// choose thread save version in each platformtm p;
#ifdef _WIN32localtime_s(&p, &now);
#elselocaltime_r(&now, &p);
#endif // _WIN32int now_int = p.tm_hour * 10000 + p.tm_min * 100 + p.tm_sec;return now_int;
}class XLogger
{
public:static XLogger* getInstance(){static XLogger xlogger;return &xlogger;}std::shared_ptr getLogger(){return m_logger;}private:// make constructor private to avoid outside instanceXLogger(){// hardcode log pathconst std::string log_dir = "./log"; // should create the folder if not existconst std::string logger_name_prefix = "test_";// decide print to console or log filebool console = false;// decide the log levelstd::string level = "debug";try{// logger name with timestampint date = NowDateToInt();int time = NowTimeToInt();const std::string logger_name = logger_name_prefix + std::to_string(date) + "_" + std::to_string(time);if (console)m_logger = spdlog::stdout_color_st(logger_name); // single thread console output fasterelse//m_logger = spdlog::create_async(logger_name, log_dir + "/" + logger_name + ".log"); // only one log filem_logger = spdlog::create_async(logger_name, log_dir + "/" + logger_name + ".log", 500 * 1024 * 1024, 1000); // multi part log files, with every part 500M, max 1000 files// custom formatm_logger->set_pattern("%Y-%m-%d %H:%M:%S.%f  [%l] [%@] %v"); // with timestamp, thread_id, filename and line numberif (level == "trace"){m_logger->set_level(spdlog::level::trace);m_logger->flush_on(spdlog::level::trace);}else if (level == "debug"){m_logger->set_level(spdlog::level::debug);m_logger->flush_on(spdlog::level::debug);}else if (level == "info"){m_logger->set_level(spdlog::level::info);m_logger->flush_on(spdlog::level::info);}else if (level == "warn"){m_logger->set_level(spdlog::level::warn);m_logger->flush_on(spdlog::level::warn);}else if (level == "error"){m_logger->set_level(spdlog::level::err);m_logger->flush_on(spdlog::level::err);}}catch (const spdlog::spdlog_ex& ex){std::cout << "Log initialization failed: " << ex.what() << std::endl;}}~XLogger(){spdlog::drop_all(); // must do this}void* operator new(size_t size){}XLogger(const XLogger&) = delete;XLogger& operator=(const XLogger&) = delete;private:std::shared_ptr m_logger;
};// use embedded macro to support file and line number
#define XLOG_TRACE(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::trace, __VA_ARGS__)
#define XLOG_DEBUG(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::debug, __VA_ARGS__)
#define XLOG_INFO(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::info, __VA_ARGS__)
#define XLOG_WARN(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::warn, __VA_ARGS__)
#define XLOG_ERROR(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::err, __VA_ARGS__)int main()
{// print log test, you can transfer any param to do formatint param = 1;XLOG_TRACE("this is trace log record, param: {}", ++param); // int type param is okXLOG_DEBUG("this is debug log record, param: {}", ++param);XLOG_INFO("this is info log record, param: {}", ++param);XLOG_WARN("this is warn log record, param: {}", double(++param)); // double type param is okXLOG_ERROR("this is error log record, param: {}", std::to_string(++param)); // string type param is okreturn 0;
}
  • 支持打印到控制台和文件两种方式
  • 采用单例模式,多种日志级别的宏调用封装
  • 格式化打印,尽可能的打印调试所需信息
  • 可以选择将每一行都立即刷新到文件,但要注意级别,尽量不要在info或者debug级别上开启,这个选项会导致日志刷新时间戳延迟

输出

例如,日志文件:test_20201230_154656.log

2020-12-30 15:46:56.681969  [debug] [main.cpp:135] this is debug log record, param: 2
2020-12-30 15:46:56.681969  [info] [main.cpp:136] this is info log record, param: 3
2020-12-30 15:46:56.682457  [warning] [main.cpp:137] this is warn log record, param: 4
2020-12-30 15:46:56.682457  [error] [main.cpp:138] this is error log record, param: 5


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部