spdlog日志库二次封装

目录

说明

类使用示例

封装类实现


说明

基于spdlog库做了一点封装,该类支持以下操作

  1. 自定义日志路径 (支持相对路径、绝对路径,支持路径包括目录)
  2. 支持日志输出模式 (同步、异步)
  3. 支持日志输出等级控制 (指定输出什么等级以上的消息)
  4. 支持日志输出位置 (控制台、文件、控制台+文件)

该文章只是简单的单日志文件处理,后续的优化都在gitee上,详细内容请跳转该地址:log: 基于C++ spdlog日志库的二次封装 - Gitee.com

日志输出实例图片

类使用示例

#pragma once
#include "Hlog.h"
 
int main()
{
	Hlog log;
	log.Init(".log/test.log", 1024*1024*1000, 10, 
			   Hlog::SYNC, Hlog::CONSOLE_AND_FILE, Hlog::LEVEL_WARN);

	LOG_TRACE("test {}", 1);
	LOG_DEBUG("test {:.2f}", 1.0000);
	LOG_INFO("test {}", 1.23456789);
	LOG_WARN("test {}", 'A');
	LOG_ERROR("test {}", "ABC");
	LOG_CRITI("test {}", std::string("abc"));
 
	return 0;
}

封装类实现

.h

#pragma once
#include "spdlog/spdlog.h"
#include "spdlog/async_logger.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/details/thread_pool.h"
#include "spdlog/details/thread_pool-inl.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/async.h" //support for async logging

//日志名称
#define LOG_NAME "multi_sink"
//封装宏,没有该宏无法输出文件名、行号等信息
#define LOG_TRACE(...) SPDLOG_LOGGER_CALL(spdlog::get(LOG_NAME), spdlog::level::trace, __VA_ARGS__)
#define LOG_DEBUG(...) SPDLOG_LOGGER_CALL(spdlog::get(LOG_NAME), spdlog::level::debug, __VA_ARGS__)
#define LOG_INFO(...) SPDLOG_LOGGER_CALL(spdlog::get(LOG_NAME), spdlog::level::info, __VA_ARGS__)
#define LOG_WARN(...) SPDLOG_LOGGER_CALL(spdlog::get(LOG_NAME), spdlog::level::warn, __VA_ARGS__)
#define LOG_ERROR(...) SPDLOG_LOGGER_CALL(spdlog::get(LOG_NAME), spdlog::level::err, __VA_ARGS__)
#define LOG_CRITI(...) SPDLOG_LOGGER_CALL(spdlog::get(LOG_NAME), spdlog::level::critical, __VA_ARGS__)


class Hlog
{
public:
	//日志输出位置
	enum OutPosition {
		CONSOLE				= 0x01,	//控制台
		FILE				= 0X02,	//文件
		CONSOLE_AND_FILE	= 0x03, //控制台+文件
	};

	enum OutMode {
		SYNC,	//同步模式
		ASYNC,	//异步模式
	};

	//日志输出等级
	enum OutLevel {
		LEVEL_TRACE		= 0,
		LEVEL_DEBUG		= 1,
		LEVEL_INFO		= 2,
		LEVEL_WARN		= 3,
		LEVEL_ERROR		= 4,
		LEVEL_CRITI		= 5,
		LEVEL_OFF		= 6,
	};

public:
	Hlog();
	~Hlog();

	/* func: 初始化日志通道
	* @para[in] nFileName    : 日志存储路径			(支持相对路径和绝对路径)
	* @para[in] nMaxFileSize : 日志文件最大存储大小	(默认1024*1024*10)
	* @para[in] nMaxFile     : 最多存储多少个日志文件	(默认10,超过最大值则循环覆盖)
	* @para[in] outMode      : 日志输出模式			(同步、异步)
	* @para[in] outPos       : 日志输出位置			(控制台、文件、控制台+文件)
	* @para[in] outLevel     : 日志输出等级			(只输出>=等级的日志消息)
	*/
	bool Init(const char* nFileName, const int nMaxFileSize = 1024 * 1024 * 10, const int nMaxFile = 10, 
			  const OutMode outMode = SYNC, const OutPosition outPos = CONSOLE_AND_FILE, const OutLevel outLevel = LEVEL_TRACE);
	void UnInit();
	
private:

public:
	std::shared_ptr<spdlog::logger> m_pLogger;
	bool m_bInit;
};

.cpp

#include "Hlog.h"
#include <fstream>
#include <iostream>
#include <string>
using namespace std;

Hlog::Hlog()
	:m_bInit(false)
{

}

Hlog::~Hlog()
{
	if (m_bInit)
	{
		this->UnInit();
	}
}

bool Hlog::Init(const char* nFileName, const int nMaxFileSize, const int nMaxFile,
				const OutMode outMode, const OutPosition outPos, const OutLevel outLevel)
{
	if (m_bInit)
	{
		printf("It's already initialized\n");
		return false;
	}
	m_bInit = true;

	try 
	{
		const char* pFormat = "[%Y-%m-%d %H:%M:%S.%e] <thread %t> [%^%l%$]\n[%@,%!]\n%v\n";
		//sink容器
		std::vector<spdlog::sink_ptr> vecSink;

		//控制台
		if (outPos & CONSOLE)
		{
			auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
			//console_sink->set_level(spdlog::level::trace);
			console_sink->set_pattern(pFormat);
			vecSink.push_back(console_sink);
		}

		//文件
		if (outPos & FILE)
		{
			auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(nFileName, nMaxFileSize, nMaxFile);
			//file_sink->set_level(spdlog::level::trace);
			file_sink->set_pattern(pFormat);
			vecSink.push_back(file_sink);
		}

		//设置logger使用多个sink
		if (outMode == ASYNC)//异步
		{
			spdlog::init_thread_pool(102400, 1);
			auto tp = spdlog::thread_pool();
			m_pLogger = std::make_shared<spdlog::async_logger>(LOG_NAME, begin(vecSink), end(vecSink), tp, spdlog::async_overflow_policy::block);
		}
		else//同步
		{
			m_pLogger = std::make_shared<spdlog::logger>(LOG_NAME, begin(vecSink), end(vecSink));
		}
		m_pLogger->set_level((spdlog::level::level_enum)outLevel);

		//遇到warn级别,立即flush到文件
		m_pLogger->flush_on(spdlog::level::warn);
		//定时flush到文件,每三秒刷新一次
		spdlog::flush_every(std::chrono::seconds(3));
		spdlog::register_logger(m_pLogger);
	}
	catch(const spdlog::spdlog_ex& ex)
	{
		std::cout << "Log initialization failed: " << ex.what() << std::endl;
		return false;
	}
	return true;
}

void Hlog::UnInit()
{
	spdlog::drop_all();
	spdlog::shutdown();
}


  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
好的,下面是一个使用spdlog封装日志系统的示例代码: ```cpp #include <spdlog/spdlog.h> #include <spdlog/sinks/basic_file_sink.h> class Logger { public: enum class Level { Trace, Debug, Info, Warn, Error, Critical, Off }; static void init(const std::string& filename, Level level = Level::Debug) { auto logger = spdlog::basic_logger_mt("logger", filename); spdlog::set_default_logger(logger); spdlog::set_level(static_cast<spdlog::level::level_enum>(level)); } static std::shared_ptr<spdlog::logger> get() { return spdlog::default_logger(); } }; #define LOG_TRACE(...) Logger::get()->trace(__VA_ARGS__) #define LOG_DEBUG(...) Logger::get()->debug(__VA_ARGS__) #define LOG_INFO(...) Logger::get()->info(__VA_ARGS__) #define LOG_WARN(...) Logger::get()->warn(__VA_ARGS__) #define LOG_ERROR(...) Logger::get()->error(__VA_ARGS__) #define LOG_CRITICAL(...) Logger::get()->critical(__VA_ARGS__) ``` 首先,我们包含了必要的头文件,包括spdlog和basic_file_sink头文件,用于向文件中记录日志。 接下来,我们定义了一个Logger类,它有一个公共的init函数,用于初始化日志系统。该函数接受一个文件名和一个日志级别参数。在该函数中,我们创建了一个基本的文件日志器,并将其设置为默认日志器。我们还设置了日志级别,该级别将转换为spdlog的level_enum类型。 接下来,我们定义了一组宏,用于记录不同级别的日志。这些宏调用spdlog默认日志器的相应函数,如trace、debug、info、warn、error和critical。这些宏可以在我们的应用程序中的任何地方使用,以记录相应级别的日志。 最后,我们使用这些宏来记录日志。例如: ```cpp int main() { Logger::init("logs/log.txt", Logger::Level::Debug); LOG_INFO("Starting application..."); LOG_DEBUG("Some debug information..."); LOG_WARN("A warning message..."); LOG_ERROR("An error occurred!"); LOG_CRITICAL("A critical error occurred!"); return 0; } ``` 这将初始化我们的日志系统,并使用LOG_INFO、LOG_DEBUG、LOG_WARN、LOG_ERROR和LOG_CRITICAL宏记录不同级别的日志。这些日志将被记录在“logs/log.txt”文件中。 希望这个封装的示例代码可以帮助您设计一个高级的spdlog日志系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值