关于Log4Ccpp的引入使用,不是基础介绍,是项目中使用的方式
时间:2021-11-30
本文章向大家介绍关于Log4Ccpp的引入使用,不是基础介绍,是项目中使用的方式,主要包括关于Log4Ccpp的引入使用,不是基础介绍,是项目中使用的方式使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
需求:我们项目中需要一个本地的日志记录,且保存日志需要半年的时间。
引入:下载 log4cplus-1.2.1 源码,默认是带有 msvc10工程的,编译源码可以生产 log4cplusUD.dll log4cplusU.dll等文件。不赘述关于编译的过程
使用:在Windows Qt环境下使用
Pro文件设置:
INCLUDEPATH += $$PWD/thirdparty DEPENDPATH += $$PWD/thirdparty win32:{ CONFIG(debug, debug|release):{ LIBS +=-L$$PWD/thirdparty -llog4cplusUD }else:CONFIG(release, debug|release):{ LIBS +=-L$$PWD/thirdparty -llog4cplusU }
log4cpp配置文件:
其中使用的appender: RollingFileAppender、DailyRollingFileAppender、TimeBasedRollingFileAppender
其中每种appender都有支持的参数,而且这些参数也不是通用的,只有在指定的appender模式下才有效,有时经常弄错。
分享一种了解参数的方式(千万别网上搜,因为千千万都是没细了解过得),可以直接打开源码搜索指定的appender名称
举例说明:DailyRollingFileAppender
具体我自己使用的配置如下:
#日志级别定义:TRACE(跟踪)、DEBUG(调试)、INFO(通知)、WARN(警告)、ERROR(错误)、FATAL(致命错误) #日志文件转储频率:MONTHLY(每月)、WEEKLY(每周)、DAILY(每日)、TWICE_DAILY(每两天)、DAILY(每天)、HOURLY(每时)、MINUTELY(每分) #----------Category:指定的log优先级是TRACE,其Appender为MML_ALL_MSGS,也可以定义多个Appender log4cplus.logger.VisheeMmlLoggerInstance=TRACE,MML_ALL_MSGS #----------Appender:指定输出源属性 #所有消息(TRACE) 按日期回卷文件,即日期分割策略、文件到达某个大小的时候产生一个新的文件 #log4cplus.appender.MML_ALL_MSGS=log4cplus::RollingFileAppender #(DailyRollingFileAppender有效)设置日志转储的频率 #注意:DailyRollingFileAppender模式下需要正常关闭程序才能分割,如果没有释放日志对象,会一直往一个日志文件中输出,且不会按转储频率分割 #log4cplus.appender.MML_ALL_MSGS.Schedule=HOURLY #(RollingFileAppender有效)设置生成日志最大大小,默认10MB #log4cplus.appender.MML_ALL_MSGS.MaxFileSize=10MB #设置生成日志最大个数 #log4cplus.appender.MML_ALL_MSGS.MaxBackupIndex=5 #log4cplus.appender.MML_ALL_MSGS.File=./logs/MML_LIB_TRACE.log #所有消息(TRACE) 按照时间日期来写文件 log4cplus.appender.MML_ALL_MSGS=log4cplus::TimeBasedRollingFileAppender log4cplus.appender.MML_ALL_MSGS.FilenamePattern=./logs/MML_LIB_TRACE.%d{yyyy-MM-dd}.log log4cplus.appender.MML_ALL_MSGS.MaxHistory=180 log4cplus.appender.MML_ALL_MSGS.Schedule=DAILY log4cplus.appender.MML_ALL_MSGS.RollOnClose=false #----------Loyout设置日志打印格式,PatternLayout表示可以灵活指定布局模式 log4cplus.appender.MML_ALL_MSGS.layout=log4cplus::PatternLayout log4cplus.appender.MML_ALL_MSGS.layout.ConversionPattern=[%D{%Y-%m-%d %H:%M:%S.%Q} %t %-5p] - [%l] %m %n #----------Filter选择过滤器设置 log4cplus.appender.MML_ALL_MSGS.filters.1=log4cplus::spi::LogLevelRangeFilter log4cplus.appender.MML_ALL_MSGS.filters.1.LogLevelMin=TRACE log4cplus.appender.MML_ALL_MSGS.filters.1.LogLevelMax=FATAL log4cplus.appender.MML_ALL_MSGS.filters.1.AcceptOnMatch=true #首先执行filters.2的过滤条件,关闭所有过滤器,然后执行filters.1 log4cplus.appender.MML_ALL_MSGS.filters.2=log4cplus::spi::DenyAllFilter
封装使用类VisheeLogger.h:
/******************************************************************** * created: 2018/03/22 16:26:13 * author : chenshi * contact: chenshi@vishee.com * * description: log4cplus 日志库应用封装 *******************************************************************/ #ifndef VISHEELOGGER_H #define VISHEELOGGER_H #include "log4cplus/logger.h" #include "log4cplus/configurator.h" #include "log4cplus/loggingmacros.h" using namespace log4cplus; class VisheeLogger { public: VisheeLogger(); ~VisheeLogger(); /** @brief : 单例函数 * @return : 其他=成功 NULL=错误 */ static VisheeLogger* instance(); public: /** @brief : 获取日志实体 * @return : 日志实体 */ const Logger& GetLogger() { return m_logger; } protected: /** @brief : 初始化日志功能 * @return : true=成功 false=错误 */ bool initialize(); /** @brief : 反初始化日志功能 * @return : true=成功 false=错误 */ bool uninitialize(); private: static VisheeLogger* m_spInstance; // 日志类单例实体 Logger m_logger; // 日志实体 const log4cplus::tstring m_sLoggerName; // 日志实体的名称 const log4cplus::tstring m_sLoggerConfig; // 日志配置文件的路径 }; //函数追踪宏 #define VISHEE_TRACE_METHOD() \ LOG4CPLUS_TRACE_METHOD ( VisheeLogger::instance()->GetLogger(), \ LOG4CPLUS_TEXT(LOG4CPLUS_MACRO_FUNCTION())) /** @brief : 日志写入宏 * * LogLevel = { TRACE_LOG_LEVEL, DEBUG_LOG_LEVEL, * INFO_LOG_LEVEL, WARN_LOG_LEVEL, * ERROR_LOG_LEVEL, FATAL_LOG_LEVEL } * * @param[in] : LogLevel logLevel 写入日志等级 * @param[in] : const char* logEvent 写入日志内容 * @return : 空 */ #define VISHEE_LOG(logLevel, logEvent) \ LOG4CPLUS_MACRO_BODY (VisheeLogger::instance()->GetLogger(), logEvent, logLevel) ///** @brief : 字符格式化 // * @param[in] : fmt 参考sprintf的格式 // * @param[in] : ... 根据格式输入参数 // * @return : 字符=成功 空=错误 // */ //QString g_FormatBuffer(const char *fmt, ...); #endif // VISHEELOGGER_H
VisheeLogger.cpp
/******************************************************************** * created: 2018/03/22 16:26:13 * author : chenshi * contact: chenshi@vishee.com * * description: log4cplus 日志库应用封装 *******************************************************************/ #include "VisheeLogger.h" #include <QFile> #include <QDir> #include <QDebug> // 单例实体初始化 VisheeLogger* VisheeLogger::m_spInstance = NULL; VisheeLogger::VisheeLogger() : m_sLoggerName( LOG4CPLUS_TEXT("VisheeMmlLoggerInstance") ) , m_sLoggerConfig( LOG4CPLUS_TEXT("./config/MzrmyyMedisignLib.log") ) { initialize(); } VisheeLogger::~VisheeLogger() { uninitialize(); } /** @brief : 单例函数 * @return : NULL=错误 其他=成功 */ VisheeLogger* VisheeLogger::instance() { if ( NULL == m_spInstance ) { m_spInstance = new VisheeLogger; } return m_spInstance; } /** @brief : 初始化日志功能 * @return : true=成功 false=错误 */ bool VisheeLogger::initialize() { // 判断日志实体是否已经创建 if ( !Logger::exists( m_sLoggerName ) ) { // 加载日志功能配置文件 PropertyConfigurator::doConfigure( m_sLoggerConfig ); // if ( Logger::getRoot().getAllAppenders().empty() ) // { // // 加载配置文件失败 // qDebug() << "加载日志配置文件失败"; // return false; // } // 创建日志实体 m_logger = Logger::/*getRoot().*/getInstance( m_sLoggerName ); //LOG 日志功能正常启动... LOG4CPLUS_INFO( m_logger, "--------------------------------------程序初始化日志功能启动.dll版本:V1.1.0.211129--------------------------------------" ); return true; } return false; } /** @brief : 反初始化日志功能 * @return : true=成功 false=错误 */ bool VisheeLogger::uninitialize() { // 判断日志实体是否存在 if ( Logger::exists( m_sLoggerName ) ) { // 终止日志实体 m_logger.shutdown(); return true; } return false; } ///** @brief : 字符格式化 // * @param[in] : fmt 参考sprintf的格式 // * @param[in] : ... 根据格式输入参数 // * @return : 字符=成功 空=错误 // */ //QString g_FormatBuffer(const char *fmt, ...) //{ // char buffer[1024] = {0}; // va_list ap; // va_start(ap, fmt); // int size = vsprintf (buffer, fmt, ap); // va_end(ap); // return QString::fromLocal8Bit(buffer, size); //}
一般调用方式:
// 函数从开始到结束追踪 VISHEE_TRACE_METHOD(); // 写入日志 VISHEE_LOG(INFO_LOG_LEVEL, QString("path:%1").arg(fullPath).toLocal8Bit().data()); VISHEE_LOG(INFO_LOG_LEVEL, QString("request:%1").arg(request).toLocal8Bit().data());
更高级功能,例如C/S模式,或者自定义appender之类的自己研究吧,我也还没需求去用。
引用的带上原文地址哈,谢谢。
原文地址:https://www.cnblogs.com/walkies/p/15623884.html
- 数据挖掘算法(logistic回归,随机森林,GBDT和xgboost)
- 关于修改数据库参数的测试(r3笔记第18天)
- 50多条实用mysql数据库优化建议
- 关于查询转换的一些简单分析(一) (r3笔记第37天)
- 简单实用的sql小技巧(第一篇) (r3笔记第36天)
- 关于修改分区表的问题总结 (r3笔记35天)
- 利用Python绘制MySQL数据图实现数据可视化
- 生产环境sql语句调优实战第九篇(r3笔记第34天)
- python数据分析之股票实战
- 使用Python编写网络爬虫抓取视频下载资源
- 通过shell定制ash脚本(r3笔记第33天)
- 使用shell定制awr脚本(r3笔记第32天)
- 用python对人们使用自行车情况分析与预测
- 由一条sql语句导致的系统IO问题(r3笔记第31天)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Go 开发十种常犯错误
- SpringBoot缓存应用实践
- 为什么应该使用 Go module proxy
- 谁能想到,我给技术总监“上了一课”
- 设计模式速览
- 序列模型——吴恩达深度学习课程笔记(五)
- 30分钟学会pyecharts数据可视化
- 用Keras从零开始6步骤训练神经网络
- Keras结构化数据预处理范例——Titanic生存预测
- 从原理上搞懂如何设置线程池参数大小?
- Keras图像数据预处理范例——Cifar2图片分类
- Keras文本数据预处理范例——IMDB影评情感分类
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof 使用详解
- Go 垃圾回收
- 如何在SpringBoot中异步请求和异步调用