最新要闻
- 科大讯飞:类ChatGPT技术今年5月落地 AI学习机产品先用
- 天天速看:31.98万元!理想L7 Air发布:性能不变 无空气悬架
- 天天速读:三星S23 Ultra拍月亮100倍变焦的效果:把马斯克都惊艳到了
- 暴雪关停国服后 CEO发声:游戏行业被亚洲主宰 东西方竞争不平衡
- 累计交付27万台 李想:理想成为国内家庭消费者首选豪华SUV
- 世界最新:高通全球首发5G NR-Light基带:主打中端物联网、峰值速率220兆
- 城市行驶每公里仅1毛钱!理想L7出行成本不足宝马X5十分之一
- 宗申新款电动车闪电侠发布:续航超200公里 仪表盘可手机投屏
- 环球观速讯丨丢失两年的手机半夜仍被人试图解锁 被系统远程拍下照片
- 网友吐槽快递派送延误 韵达总部:人手紧张正调配
- 《狂飙》蜚声海外 英国小伙们沉迷剧集无法自拔:竟被打斗画面吸引
- 今日热文:大货车实线变道 女子科三被别停挂科当场发飙
- 全球热消息:土耳其一城市震后被海水倒灌:汽车泡在水里
- 环球观焦点:漂浮在数万米高空 你见到的“不明飞行物”:很可能就是一只气球
- 一加Ace 2支持双频GPS:发布会上没讲 结果被很多网友误伤
- 【天天播资讯】太火爆!ChatGPT多次因访问量激增而宕机
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
资讯:log4cxx配置日期回滚策略中增加MaxFileSize属性
- 1、背景
- 2、实现方式
- 2.1、DailyRollingFileAppender新增MaxFileSize属性
- 2.2、TimeBasedRollingPolicy策略新增maxFileSize的判断
- 3、总结
1、背景
C++ 项目,使用 log4cxx 日志库,需要按照日期生成日志目录,目录下存放日志文件,且日志文件不能过大,过大需要分片,例如,文件目录可以是:
(资料图片仅供参考)
.|-- log|---|-- 2022-10-02|---|---|-- log.log|---|---|-- log.log.1|---|---|-- log.log.2|---|---|-- log.log.3|---|-- 2022-10-03|---|---|-- log.log|---|---|-- log.log.1|---|---|-- log.log.2
log4cxx 库针对该需要有两个问题:
- DailyRollingFileAppender只能针对文件进行回滚,效果是在文件名后增加日期后缀,不能实现日期创建目录;
- RollingFileAppender支持文件过大分片(MaxFileSize属性),但是 DailyRollingFileAppender不支持;
针对问题一,已有解决方案,见文章:按照日期回滚不创建新目录的BUG
问题二,log4cxx 库确实不支持,只能自定义实现了
2、实现方式
先使用配置文件如下:
log4j.rootLogger=INFO,Rlog4j.appender.R=org.apache.log4j.DailyRollingFileAppenderlog4j.appender.R.ImmediateFlush=truelog4j.appender.R.Append=truelog4j.appender.R.MaxFileSize=1MBlog4j.appender.R.DatePattern="${LOG_HOMR_DIR}/${LOG_DIR}/"yyyy-MM-dd"/log.log"log4j.appender.R.layout=org.apache.log4j.PatternLayoutlog4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd hh:mm:ss.SSS} %-5p [%c] %m %n
正常情况下,MaxFileSize因为不是 DailyRollingFileAppender的属性,所以不会生效,我们需要进行如下修改
2.1、DailyRollingFileAppender新增MaxFileSize属性
配置中的属性直接对应 appender 的属性,所以添加属性的最外层应该是 appender
DailyRollingFileAppender类是配置文件中指定的 appender,所以属性先加在这里
代码文件 dailyrollingfileappender.h,增加属性和getter/setter
namespace log4cxx {... class LOG4CXX_EXPORT DailyRollingFileAppender : public log4cxx::rolling::RollingFileAppenderSkeleton { DECLARE_LOG4CXX_OBJECT(DailyRollingFileAppender) BEGIN_LOG4CXX_CAST_MAP() LOG4CXX_CAST_ENTRY(DailyRollingFileAppender) LOG4CXX_CAST_ENTRY_CHAIN(FileAppender) END_LOG4CXX_CAST_MAP() /** The date pattern used to initiate rollover. */ LogString datePattern; int maxFileSize;//新增属性,用于控制单个文件大小public: DailyRollingFileAppender(); //属性的getter/setter void setMaxFileSize( const LogString & value); long getMaxFileSize() const;...};LOG4CXX_PTR_DEF(DailyRollingFileAppender);}...
dailyrollingfileappender.cpp实现属性的获取和设置
DailyRollingFileAppender::DailyRollingFileAppender( const LayoutPtr& layout, const LogString& filename, const LogString& datePattern1) : datePattern(datePattern1), maxFileSize(0) {//构造函数进行maxFileSize属性初始化 setLayout(layout); setFile(filename); Pool p; activateOptions(p);}//getter/settervoid DailyRollingFileAppender::setMaxFileSize( const LogString & value) { //这里调用log4cxx的接口,进行单位转换 maxFileSize = OptionConverter::toFileSize(value, maxFileSize + 1);}long DailyRollingFileAppender::getMaxFileSize() const { return maxFileSize;}//activateOptions方法作用是激活配置,即将配置塞到policy中void DailyRollingFileAppender::activateOptions(log4cxx::helpers::Pool& pool) { TimeBasedRollingPolicyPtr policy = new TimeBasedRollingPolicy(); LogString pattern(getFile()); bool inLiteral = false; bool inPattern = false; for (size_t i = 0; i < datePattern.length(); i++) { if (datePattern[i] == 0x27 /* "\"" */) { inLiteral = !inLiteral; if (inLiteral && inPattern) { pattern.append(1, (logchar) 0x7D /* "}" */); inPattern = false; } } else { if (!inLiteral && !inPattern) { const logchar dbrace[] = { 0x25, 0x64, 0x7B, 0 }; // "%d{" pattern.append(dbrace); inPattern = true; } pattern.append(1, datePattern[i]); } } if (inPattern) { pattern.append(1, (logchar) 0x7D /* "}" */); } policy->setFileNamePattern(pattern); policy->setMaxFileSize(maxFileSize);//新增,将maxFileSize属性塞给policy policy->activateOptions(pool); setTriggeringPolicy(policy); setRollingPolicy(policy); RollingFileAppenderSkeleton::activateOptions(pool);}
2.2、TimeBasedRollingPolicy策略新增maxFileSize的判断
appender 把 maxFileSize 属性塞给了 policy,那么 policy 需要新增对应接口来接收,并做策略的判断
同时 policy 只是策略,roll 的具体操作在 action 中,policy 根据需要创建 action,然后由 action 来执行,具体见下面代码
DailyRollingFileAppender只使用了 TimeBasedRollingPolicy,所以我们只需要看 TimeBasedRollingPolicy的代码
timebasedrollingpolicy.h修改如下:
namespace log4cxx { namespace rolling { class LOG4CXX_EXPORT TimeBasedRollingPolicy : public RollingPolicyBase, public TriggeringPolicy { DECLARE_LOG4CXX_OBJECT(TimeBasedRollingPolicy) BEGIN_LOG4CXX_CAST_MAP() LOG4CXX_CAST_ENTRY(TimeBasedRollingPolicy) LOG4CXX_CAST_ENTRY_CHAIN(RollingPolicyBase) LOG4CXX_CAST_ENTRY_CHAIN(TriggeringPolicy) END_LOG4CXX_CAST_MAP() private: //新增以下三个属性 size_t maxFileSize;//单个文件的大小上限 bool fileSizeChanged;//当前记录的文件是否已经超出上限 int backupIndex;//rollover的index,即需要给备份文件增加的后缀 public: TimeBasedRollingPolicy();//maxFileSize属性的getter/setter void setMaxFileSize(size_t size); size_t getMaxFileSize() const; }; LOG4CXX_PTR_DEF(TimeBasedRollingPolicy); }}
timebasedrollingpolicy.cpp修改如下:
构造函数进行属性初始化,index从1开始,maxFileSize为0表示没有大小限制
TimeBasedRollingPolicy::TimeBasedRollingPolicy() : maxFileSize(0), fileSizeChanged(false), backupIndex(1) {}
新增 maxFileSize属性的 getter/setter
void TimeBasedRollingPolicy::setMaxFileSize(size_t size) { maxFileSize = size;}size_t TimeBasedRollingPolicy::getMaxFileSize() const { return maxFileSize;}
isTriggeringEvent()方法用于判断是否需要进行 rollover,修改如下:
lastFileName变量存放备份的日志的文件的绝对路径,不需要备份,则它应该和当前记录的日志文件一直,若我们需要备份,则该变量就是备份的文件
这里先检查日期是否变化,如果日志变化了,则无需判断文件大小
bool TimeBasedRollingPolicy::isTriggeringEvent( Appender* /* appender */, const log4cxx::spi::LoggingEventPtr& /* event */, const LogString& /* filename */, size_t fileLength) { if (apr_time_now() > nextCheck) { return true; } //maxFileSize <= 0 则不检查大小,当前日志文件超出限额,则需要rollover if (maxFileSize > 0 && fileLength >= maxFileSize) { fileSizeChanged = true;//置true,表示需要分片 //备份的文件增加后缀index,同时index加一 lastFileName = lastFileName + "." + std::to_string(backupIndex++); return true; } return false;}
rollover()方法是日志回滚的具体实现,修改如下:
RolloverDescriptionPtr TimeBasedRollingPolicy::rollover( const LogString& currentActiveFile, Pool& pool) { apr_time_t n = apr_time_now(); nextCheck = ((n / APR_USEC_PER_SEC) + 1) * APR_USEC_PER_SEC; LogString buf; ObjectPtr obj(new Date(n)); formatFileName(obj, buf, pool); LogString newFileName(buf); // // if file names haven"t changed, no rollover // //新增fileSizeChanged的判断,日志变化或者文件超限都需要执行rollover if (newFileName == lastFileName && !fileSizeChanged) { RolloverDescriptionPtr desc; return desc; } if (fileSizeChanged) { //如果是文件超限,表示不是日期变化的roll,重置flag fileSizeChanged = false; } else { //日期变化,则备份的文件后缀index重新从1开始 backupIndex = 1; } ActionPtr renameAction; ActionPtr compressAction; LogString lastBaseName( lastFileName.substr(0, lastFileName.length() - suffixLength)); LogString nextActiveFile( newFileName.substr(0, newFileName.length() - suffixLength)); // // if currentActiveFile is not lastBaseName then // active file name is not following file pattern // and requires a rename plus maintaining the same name if (currentActiveFile != lastBaseName) { //创建rename action,用于将当前的日志文件重命名,实现日志的备份 renameAction = new FileRenameAction( File().setPath(currentActiveFile), File().setPath(lastBaseName), true); nextActiveFile = currentActiveFile; } if (suffixLength == 3) { compressAction = new GZCompressAction( File().setPath(lastBaseName), File().setPath(lastFileName), true); } if (suffixLength == 4) { compressAction = new ZipCompressAction( File().setPath(lastBaseName), File().setPath(lastFileName), true); } lastFileName = newFileName; return new RolloverDescription( nextActiveFile, false, renameAction, compressAction);}
这里我们只需要创建 FileRenameAction,告诉他需要 rename 的文件和新的文件即可
3、总结
本次修改的修改综合来说只有以下几步:
- appender 解析属性;
- appender 在配置active的函数中将属性交给policy;
- policy 负责策略,需要判断是否要进行 roll,并构造 roll 需要的action;
- action 最后执行,action有多种,rename 是其中一个;
由此可见,log4cxx的框架层次分明,结构合理,便于修改和拓展,设计是相当优秀的,值得深入学习
-
当前关注:强大的Excel工具,简便Vlookup函数操作:通用Excel数据匹配助手V2.0
通用Excel数据匹配助手V2 0ForWindows通用Excel数据匹配助手是一款非常实用的数据匹配软件,可以用来代...
来源: 资讯:log4cxx配置日期回滚策略中增加MaxFileSize属性
天天看点:MySQL索引的基本理解
当前关注:强大的Excel工具,简便Vlookup函数操作:通用Excel数据匹配助手V2.0
通过python,将excel中的数据写入二维列表
天天日报丨爬虫基础
科大讯飞:类ChatGPT技术今年5月落地 AI学习机产品先用
天天速看:31.98万元!理想L7 Air发布:性能不变 无空气悬架
天天速读:三星S23 Ultra拍月亮100倍变焦的效果:把马斯克都惊艳到了
世界今头条!分布式配置nacos搭建踩坑指南(上)
焦点消息!TVS二极管
(七)elasticsearch 源码之元数据CulsterState
暴雪关停国服后 CEO发声:游戏行业被亚洲主宰 东西方竞争不平衡
累计交付27万台 李想:理想成为国内家庭消费者首选豪华SUV
世界最新:高通全球首发5G NR-Light基带:主打中端物联网、峰值速率220兆
城市行驶每公里仅1毛钱!理想L7出行成本不足宝马X5十分之一
消息!drf认证/权限/频率/分页-过滤-排序
报道:【时间基准】NTP网络时钟服务器助力智能农业系统
快播:C和Python实现快速排序-三数中值划分选择主元(非随机)
宗申新款电动车闪电侠发布:续航超200公里 仪表盘可手机投屏
环球观速讯丨丢失两年的手机半夜仍被人试图解锁 被系统远程拍下照片
网友吐槽快递派送延误 韵达总部:人手紧张正调配
《狂飙》蜚声海外 英国小伙们沉迷剧集无法自拔:竟被打斗画面吸引
今日热文:大货车实线变道 女子科三被别停挂科当场发飙
全球热消息:土耳其一城市震后被海水倒灌:汽车泡在水里
环球观焦点:漂浮在数万米高空 你见到的“不明飞行物”:很可能就是一只气球
一加Ace 2支持双频GPS:发布会上没讲 结果被很多网友误伤
【天天播资讯】太火爆!ChatGPT多次因访问量激增而宕机
程序员常用的6款效率工具,准时下班不是梦
世界看点:春节假期“清零”,任务管理飞项快速助你回到高效状态
全球最新:win10系统,软件不可用,无法调用摄像头
Linux内核跟踪和性能分析
要闻:14年了:“千年老二”微软终于有机会扳倒谷歌搜索
热消息:微星推出Cubi 5 12M迷你主机:仅0.66L、配备双网口
世界热点评!女生应聘被问是否单身!当事公司:要求单身正常 将起诉举报者
【全球时快讯】近50年来首次!日本沙滩惊现大量沙丁鱼 原因未知:开排核废水、也要大地震?
最新资讯:国产车开门红:1月比亚迪称王 大众沦落第三 合资腰斩
03-Pandas详解
今日热讯:ChatGPT能做什么?零基础教你免费使用ChatGPT和账号注册
当前速看:美团面试失败后,翻了两年前的面试题,发现根本不是一个难度的
当前简讯:Linux安装
Spring Boot发送GET/POST请求——RestTemplate的基本使用
当前报道:自研指令集没有侵权MIPS 国产CPU龙芯赢了:摆脱官司
当前讯息:自燃车辆引燃邻车 损失谁来赔?法院释疑
天天最新:基于 eBPF 的 Serverless 多语言应用监控能力建设
世界最新:构建亿级别的消息推送基础模型
全球热文:Linux开源工具之nethogs命令介绍
精选!COBOL教程_编程入门自学教程_菜鸟教程-免费教程分享
华硕发布新款Vivobook 13 Slate笔记本:Intel 7W超低功耗U
今日精选:3岁女童喊脚疼被确诊癌症晚期:神经母细胞瘤 儿童癌症之王
天天微速讯:剧版《三体》弹幕互动量破2000万!豆瓣涨至8.3分
【热闻】iPhone 15 Ultra狂堆料!价格可能贵出天际
环球热议:全球不足50人!宝鸡发现1例罕见黄金血型:比熊猫血更稀有
环球资讯:ASP.Net Core 教程_编程入门自学教程_菜鸟教程-免费教程分享
ChatGPT保姆级注册教程
group by 、concat_ws()、 group_caoncat()的使用
全球热头条丨Jedis那么低性能,还在用吗? lettuce时代开幕啦
热资讯!阿里IM技术分享(十):深度揭密钉钉后端架构的单元化演进之路
强震已致超7700人遇难!土耳其地震背后的人祸 建筑不达标、豆腐渣工程多
全球热议:全球首架国产大飞机C919首飞三亚 民航最高接待礼“过水门”接风
环球关注:iPhone 15 Pro系列拿到三星顶级屏幕!超出S23系列整整两代
全球消息!高级Excel教程_编程入门自学教程_菜鸟教程-免费教程分享
重点聚焦!Serverless 时代开启,云计算进入业务创新主战场
【天天报资讯】Go的参数是传值还是传引用问题
【环球聚看点】【踩坑记录】单测中@PostConstruct多次执行
免费无广告 微软电脑管家2.7公测版发布:任务栏被意外修改有救了
4599元!佳能EOS R50发布:329克超轻便 支持无裁切6K
天天信息:研发10几年、花费千亿:日本国产大飞机为何失败?就是畸形产物
全球微速讯:LV将涨价?国人排长龙抢购 买万元包像在赶集:世界首富曾感慨中国用户有钱
高级Excel图表教程_编程入门自学教程_菜鸟教程-免费教程分享
Apache ANT 教程_编程入门自学教程_菜鸟教程-免费教程分享
焦点播报:算法学习笔记(15): Trie(字典树)
今日讯!火山引擎 DataTester“智能发布”:覆盖产品研发、测试、上线全流程,一站式智能管理 A/B 实验
DB2教程_编程入门自学教程_菜鸟教程-免费教程分享
马斯克将于3月1日公布特斯拉宏图第三篇章 第二篇章已烂尾
世界观速讯丨国产车企1:1复刻几十年前的MINI外观专利 宝马抗议!结果判了
【独家焦点】真心没想到!五旬男子开车撞上护栏:只因刚割了双眼皮
全球热消息:全世界最后一只袋狼究竟是怎么死的?
民企第一只 京东仓储REIT上市:认购额超718亿元遭疯抢
当前视讯!C#(进制转换) NumberConversion
ChatGPT国内也能用吗?ChatGPT国内镜像站点分享给你们
微动态丨暴躁小钢炮!极氪X实车亮相:零百加速3秒级
环球微速讯:《仙剑奇侠传》《和平精英》梦幻联动:赵灵儿端枪吃鸡
啥身材都能包!真维斯连帽卫衣大促:日常100元 现价50到手
6年来苹果iPhone涨价近50% 还会继续涨 库克不怕没人买
《流浪地球2》导演郭帆:国产科幻片工业流程还是初级 吃饭都会出大错误
童话二分之一的大结局是什么?童话二分之一演员表
金棕色适合什么肤色?金棕色和金栗色茶色的区别有哪些?
回避型人格障碍的表现有哪些?回避型人格障碍怎么治疗?
天天快资讯丨袋鼠云数栈UI5.0焕新升级,全新设计语言DT Design,更懂视觉更懂你!
【世界热闻】芯驿电子发布车载系列产品全新品牌AUMO
速讯:仿制作图《这里是中国》封面
【天天播资讯】spring注解
升学宴是什么意思?学生升学宴家长答谢宴致辞
货柜标准尺寸是多少?货柜集装箱尺寸规格表
淘宝换购是什么意思?淘宝换购的东西是正品吗?
笔记本键盘怎么拆卸?笔记本电脑键盘拆卸方法
ddr2内存条还能用吗?ddr2和ddr3的区别有哪些?
爱奇艺弹幕开关在哪里?爱奇艺怎么关闭弹幕?
手机微信语音电话接不到是什么原因?手机微信语音没有声音是怎么回事?
观点:零跑汽车创始人:有信心在一些环节超越特斯拉