日志库的重要性:
编程中打印日志的作用:
1)追踪程序运行过程,快速定位问题
2)日志易于记忆和比对
3)成功地调试程序、监控和错误报告地关键是【日志】
4) 追踪数据的变化 ,显示程序运行状态
5) 状态监控:通过实时分析日志,可以监控系统的运行状态,做到早发现问题、早处理问题。
C++中的日志库有很多,以下是其中比较知名的一些:
- spdlog:Speed + Log,是一个高速异步日志库,支持多线程和旋转文件日志,适合用于高负载的系统。
- glog:Google出品,提供了多种级别的日志输出、多个日志目录的分布式日志存储、快速同步日志到磁盘等功能。
- Boost.Log:由Boost库提供的日志记录工具,支持多个不同的后端日志器,可以定制多种记录格式。
- log4cxx:Apache开发的一个C++日志库,设计灵活,可通过配置文件进行调整,同时也支持多种输出方式。
- Poco.Log:Poco库的LOG模块,结构简单,易于集成到其他应用程序中,支持多个日志记录器和过滤器。
本文主要介绍spdlog的用法以及二次封装,也是我目前在用的日志库:
spdlog
是一个开源、快速、只有头文件的C++11日志库,code地址在https://github.com/gabime/spdlog,基础示例在https://github.com/gabime/spdlog#readme
第一步:以上地址是源码,可以下载下来。进行初步的配置
第二步:初步配置验证,用到自己的工程中,需要吧include文件夹copy到自己的工程目录下,配置包含目录为include目录
第三步:二次封装成动态库调用使用
.h文件和cpp文件
#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_OUTPUT_FORMAT "%^[ %Y-%m-%d %H:%M:%S.%e ] <thread %t> [%n] [%l]\n%@,%!\n%v%$\n"
//日志名称
#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,
};
enum ErrorInfo {
};
public:
__declspec(dllexport) Hlog();
__declspec(dllexport) ~Hlog();
/* func: 初始化日志通道
* @para[in] nFileName : 日志存储路径 (支持相对路径和绝对路径)
* @para[in] nMaxFileSize : 日志文件最大存储大小 (默认1024*1024*10)
* @para[in] nMaxFile : 最多存储多少个日志文件 (默认100,超过最大值则循环覆盖)
* @para[in] outMode : 日志输出模式 (同步、异步)
* @para[in] outPos : 日志输出位置 (控制台、文件、控制台+文件)
* @para[in] outLevel : 日志输出等级 (只输出>=等级的日志消息)*/
__declspec(dllexport) 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);
//日期文件(在每天的指定时间生成一个日志文件, 文件名以日期命名)
//@pLoggerName [in]: 记录器名称
//@pFileName [in]: 日志名称
//@nHour [in]: 指定生成时间的时
//@nMinute [in]: 指定生成时间的分
//@eLevel [in]: 日志输出等级
bool AddDailyFile(const char* pLoggerName, const char* pFileName, const int nHour, const int nMinute, const OutLevel eLevel = LEVEL_TRACE);
//释放所有logger
__declspec(dllexport) void UnInit();
/* func: 设置日志错误码
* @para[in] errorCode : 错误信息*/
static __declspec(dllexport) std::string SetErrorCode(long long errorCode);
private:
public:
std::shared_ptr<spdlog::logger> m_pLogger;
bool m_bInit;
};