> 文章列表 > 【C++】Spdlog日志库

【C++】Spdlog日志库

【C++】Spdlog日志库

一、Spdlog介绍

参考文献:

  1. Github: https://github.com/gabime/spdlog
  2. https://blog.csdn.net/tutou_gou/article/details/121284474

二、 日志封装

#pragma once
#include <iostream>
#include <string>
#include <memory>
#include <time.h>
#include <chrono>
#include <assert.h>
#include "spdlog/spdlog.h"
#include "spdlog/async.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"#ifndef LOG_LEVEL
#define LOG_LEVEL "info"
#endif#define LOG_DIR "./log"#ifndef LOG_DIR
#define LOG_CONSOLE true
#else
#define LOG_CONSOLE false
#endifstatic inline int NowDateToInt()
{time_t now;time(&now);tm p;
#ifdef _WIN32localtime_s(&p, &now);
#elselocaltime_r(&now, &p);
#endifint 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);tm p;
#ifdef _WIN32localtime_s(&p, &now);
#elselocaltime_r(&now, &p);
#endifint 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<spdlog::logger> getLogger(){return m_logger;}private:// make constructor private to avoid outside instanceXLogger(){// hardcode log pathconst std::string log_dir = LOG_DIR;const std::string logger_name_prefix = "tvcore_";// decide print to console or log filebool console = LOG_CONSOLE;// decide the log levelstd::string level = LOG_LEVEL;try{int 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 fasterelsem_logger = spdlog::create_async<spdlog::sinks::rotating_file_sink_mt>(logger_name,log_dir + "/" + logger_name + ".log", 100 * 1024 * 1024, 10); // 10 * 100M// custom formatm_logger->set_pattern("%Y-%m-%d %H:%M:%S.%f <thread %t> [%l] [%@] %v");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);}else if (level == "off"){m_logger->set_level(spdlog::level::off);m_logger->flush_on(spdlog::level::off);}}catch (const spdlog::spdlog_ex& ex){std::cout << "Log initialization failed: " << ex.what() << std::endl;}}~XLogger(){spdlog::drop_all(); // must do this}XLogger(const XLogger&) = delete;XLogger& operator=(const XLogger&) = delete;private:std::shared_ptr<spdlog::logger> m_logger;
};// use embedded macro to support file and line number
#define LOG_DEBUG(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::debug, __VA_ARGS__)
#define LOG_INFO(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::info, __VA_ARGS__)
#define LOG_WARN(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::warn, __VA_ARGS__)
#define LOG_ERROR(...) SPDLOG_LOGGER_CALL(XLogger::getInstance()->getLogger().get(), spdlog::level::err, __VA_ARGS__)#define DBG_ASSERT(x) do {\\if (!(x)) {\\LOG_ERROR("Assert Error!");\\}\\} while(0)

1. 终端日志

 m_logger = spdlog::stdout_color_st(logger_name); // single thread console output faster

2. 单一文件日志

auto my_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic.txt");

basic log 日志文件会一直被写入,不断变大。使用较少。

  • mt 多线程异步,速度慢一点
  • st 单线程,速度较快

3. 循环日志文件

  • 当日志条数在一个文件中足够大时,必须分割为多个文件
  • 保证日志文件的数量不会无限增长
 auto file_logger = spdlog::rotating_logger_mt("file_logger", "myfilename", 1024 * 1024 * 5, 10);
  • 日志产生者的名字,自定义即可
  • 日志文件路径
  • 单一日志文件的最大值。超过则会产生新的文件。第三个参数指定,如上面指定的5M
  • 保留文件数量,超过数量的文件会直接删除以节省空间。

4. daily log

每天会新建一个日志文件,新建日志文件的时间可以自己设定

auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
  • 每天 2点 30会创建新文件。

5. 异步文件日志

auto file_logger = spdlog::rotating_logger_mt<spdlog::async_factory>("file_logger", "mylogs", 1024 * 1024 * 5, 100);
  • 在初始化的时候使用异步工厂 spdlog::async_factory 即可。