期望结果:按日期生成文件夹,在最底层文件夹中记录日志,如:2019/03/11,在11这个文件夹下记录11号的日志,03和2019均为11的父文件夹。

API:log4j

主要步骤:继承log4j的org.apache.log4j.RollingFileAppender类,重写setFile、subAppend方法

配置文件:修改log4j的配置文件,将使用的类指向自己写的继承的类,改写日志文件目录格式

java代码:

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;import org.apache.log4j.RollingFileAppender;
import org.apache.log4j.helpers.CountingQuietWriter;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;//继承log4j的RollingFileAppender类
public class Log4jFileUpdate extends RollingFileAppender {private long nextRollover = 0;private static Map<String, BeginFileData> fileMaps = new HashMap<String, BeginFileData>();private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");public void rollOver () {File target;File file;int maxBackupIndexLeng = String.valueOf(maxBackupIndex).length();if (qw != null) {long size = ((CountingQuietWriter) qw).getCount();LogLog.debug("rolling over count=" + size);nextRollover = size + maxFileSize;}LogLog.debug("maxBackupIndex=" + maxBackupIndex);String nowDateString = sdf.format(new Date());String newFileName = (fileName.indexOf(".") != -1 ? fileName.substring(0,fileName.lastIndexOf(".")) : fileName);boolean renameSucceeded = true;if (maxBackupIndex > 0) {file = new File(newFileName + '.' + nowDateString + '.'+ getIndex(maxBackupIndex, maxBackupIndexLeng));if (file.exists()) {renameSucceeded = file.delete();}for (int i = maxBackupIndex - 1; (i >= 1 && renameSucceeded); i--) {file = new File(newFileName + '.' + nowDateString + '.'+ getIndex(i, maxBackupIndexLeng));if (file.exists()) {target = new File(newFileName + '.' + nowDateString + '.'+ getIndex(i + 1, maxBackupIndexLeng));LogLog.debug("Renaming file " + file + " to " + target);renameSucceeded = file.renameTo(target);}}if (renameSucceeded) {BeginFileData beginFileData = fileMaps.get(fileName);System.out.println("fileName= " + fileName + "\tbeginFileData="+ beginFileData);// 在每天一个日志目录的方式下,检测日期是否变更了,如果变更了就要把变更后的日志文件拷贝到变更后的日期目录下。if (newFileName.indexOf(nowDateString) == -1&& beginFileData.getFileName().indexOf("yyyy/MM/dd") != -1) {newFileName = beginFileData.getFileName().replace("yyyy/MM/dd",nowDateString);newFileName = (newFileName.indexOf(".") != -1 ? newFileName.substring(0, newFileName.lastIndexOf(".")) : newFileName);}target = new File(newFileName + '.' + nowDateString + '.'+ getIndex(1, maxBackupIndexLeng));this.closeFile();file = new File(fileName);LogLog.debug("Renaming file " + file + " to " + target);renameSucceeded = file.renameTo(target);if (!renameSucceeded) {try {this.setFile(fileName, true, bufferedIO, bufferSize);} catch (IOException e) {LogLog.error("setFile(" + fileName + ", true) call failed.", e);}}}}//// if all renames were successful, then//if (renameSucceeded) {try {this.setFile(fileName, false, bufferedIO, bufferSize);nextRollover = 0;} catch (IOException e) {LogLog.error("setFile(" + fileName + ", false) call failed.", e);}}}/*** 文件个数的长度补零,如果文件个数为10那么文件的个数长度就是2位,第一个文件就是01,02,03....* * @param i* @param maxBackupIndexLeng* @return*/private String getIndex (int i, int maxBackupIndexLeng) {String index = String.valueOf(i);int len = index.length();for (int j = len; j < maxBackupIndexLeng; j++) {index = "0" + index;}return index + ".log";}/*** This method differentiates RollingFileAppender from its super class.* * @since 0.9.0*/protected void subAppend (LoggingEvent event) {super.subAppend(event);if (fileName != null && qw != null) {String nowDate = sdf.format(new Date());// 检测日期是否已经变更了,如果变更了就要重创建日期目录if (!fileMaps.get(fileName).getDate().equals(nowDate)) {rollOver();return;}long size = ((CountingQuietWriter) qw).getCount();if (size >= maxFileSize && size >= nextRollover) {rollOver();}}}@Overridepublic synchronized void setFile (String fileName, boolean append,boolean bufferedIO, int bufferSize) throws IOException {String nowDate = sdf.format(new Date());// 如果文件路径包含了“yyyy-MM-dd”就是每天一个日志目录的方式记录日志(第一次的时候)if (fileName.indexOf("yyyy/MM/dd") != -1) {String beginFileName = fileName;fileName = fileName.replace("yyyy/MM/dd", nowDate);fileMaps.put(fileName, new BeginFileData(beginFileName, nowDate));}BeginFileData beginFileData = fileMaps.get(fileName);// 检测日期是否已经变更了,如果变更了就要把原始的字符串给fileName变量,把变更后的日期做为开始日期if (!beginFileData.getDate().equals(nowDate)) {// 获取出第一次的文件名beginFileData.setDate(nowDate);fileName = beginFileData.getFileName().replace("yyyy/MM/dd", nowDate);fileMaps.put(fileName, beginFileData);}// D:/data/test/yyyy-MM-dd/test.log 替换yyyy-MM-dd为当前日期。File file = new File(fileName);File parentFile = file.getParentFile();if (!parentFile.exists()) {parentFile.mkdirs();}super.setFile(fileName, append, this.bufferedIO, this.bufferSize);}private class BeginFileData {public BeginFileData (String fileName, String date) {super();this.fileName = fileName;this.date = date;}private String fileName;private String date;public String getFileName () {return fileName;}public void setFileName (String fileName) {this.fileName = fileName;}public String getDate () {return date;}public void setDate (String date) {this.date = date;}}
}

log4j配置文件:

log4j.rootLogger=console,logErrFile,logfile
log4j.additivity.org.apache=true
log4j.logger.org.apache=off
log4j.logger.com.mchange=off
## (console)
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DUBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}:%p %t %c - %m%nlog4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss:SSS}:%p %t %l - %m%n## (file: ERROR)
log4j.appender.logErrFile=util.Log4jFileUpdate
log4j.appender.logErrFile.Threshold=ERROR
log4j.appender.logErrFile.ImmediateFlush=true
log4j.appender.logErrFile.Append=true
log4j.appender.logErrFile.File=logger/yyyy/MM/dd/error_logs.log
log4j.appender.logErrFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logErrFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}:%p %t %c - %m%n
##log4j.appender.logErrFile.DatePattern =yyyyMMddlog4j.appender.logfile=util.Log4jFileUpdate
log4j.appender.logfile.File=logger/yyyy/MM/dd/all.log
log4j.appender.logfile.MaxFileSize=10MB
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss\:SSS}\: %p %t %l - %m%n

效果:

附:

效果二:将java代码和配置文件中的yyyy/MM/dd改成yyyy-MM-dd即可

日志 log4j按日期生成文件夹相关推荐

  1. Log4j 重写 RollingFileAppender 实现按日期生成文件夹文件名

    Log4j 不支持按日期生成不同的文件夹,通过重写 RollingFileAppender  的 rollOver . genFileName . subAppend . setFile 方法,实现我 ...

  2. 按日期生成文件夹,并删除之前的文件夹

    //获取unix时间戳的当前时间 $addtime=date("ymd",time()); //创建文件夹 $testdir="./python/out/dada&quo ...

  3. 啊哈哈哈哈 C#按日期生成文件夹,并在文件夹中写入文件

    我的天哪 我终于写出来了 using System; using System.Collections.Generic; using System.ComponentModel; using Syst ...

  4. Excel与bat批量生成文件夹,修改文件夹名称

    用Excel与bat批量生成文件夹,修改文件夹名称 一.批量生成文件夹 excel一列输入文件名序列:另一列用公式生成要写入bat文件的序列,之后复制该列写入.txt文件,保存为.bat文件,双击运行 ...

  5. java创建linux文件_Java生成文件夹

    1.说明 判断文件夹是否存在,如果不存在就创建该文件夹,并打印其路径:如果存在,打印其路径 2.实现源码 /** * @Title:BuildFolder.Java * @Package:com.yo ...

  6. python如何生成excel文件夹_用python脚本通过excel生成文件夹树结构

    大概这样写标题是对的吧... 目标: 通过excel目录结构文档生成文件夹树结构. 也就是: 通过下面的excel 生成下面的文档树结构: 方法: 1.分析:一般文档结构都是事先构思好.可以在txt文 ...

  7. linux文件自动改名,C#如何在生成文件夹或者文件时候自动重命名

    C#如何在生成文件夹或者文件时候自动重命名 如果你在一个文件夹里面, 连续添加文件夹或者文件(不改名字), 那么系统会自动加上(1),(2),(3)... 这个效果我在网上搜不到, 自己写一下也不太难 ...

  8. python生成文件夹以及压缩文件夹

    ''' @Description 生成文件夹 @params (path) 文件夹路径 @params (title) 文件名称 @params (content) html 文件代码 @params ...

  9. 根据图片名字生成文件夹并归类+批量重命名照片名

    最近在处理手头的部分图片数据,所以码了点code,也许质量不高,供大家参考, 欢迎各路大神纠正问题!! 1.该代码根据照片的名字来生成文件夹,并且将同类照片放置同一文件夹creat_dir.py #- ...

最新文章

  1. 蓝桥杯基础练习题3(16进制转8进制)1
  2. c++中override的应用
  3. 机器学习经典必读书,李航《统计学习方法》出视频课了!
  4. Uipath 学习栏目基础教学:8、uipath 屏幕抓取获取文本
  5. Linux下重要目录功能介绍
  6. Kubernetes 的2020年“野望”
  7. MySQL 基础模块的面试题总结
  8. HTTP / HTTPS抓包工具-Fiddler
  9. php绕过验证,PHP-Nuke绕过识别码验证漏洞
  10. python list函数使用总结_python——list总结
  11. Prompt Learning | 一文带你概览Prompt工作新进展
  12. 石川:未知风险,错误定价,还是数据迁就?
  13. 软件测试常见面试题汇总大纲
  14. 分库分表中间件 sharding
  15. 苹果电脑怎样禁用首字母自动大写?
  16. 什么是情感化设计?UI设计中情感化设计的目的
  17. jsLint 检查分析
  18. java应届毕业生面试技巧
  19. centos8搭建ftp虚拟用户登录
  20. 如何给刚刚出厂的服务器配置IP地址(华为RH2288 v3)

热门文章

  1. firefox 1.0中添加自定义搜索引擎——北大天网搜索引擎
  2. SWIFT PLM 介绍|基于微服务架构的Swift PLM云平台
  3. 无线串口NRF24L01的使用与调试
  4. relpos函数解读
  5. nginx请求的11个阶段
  6. 初学编程,学哪种语言比较好?
  7. 电子工程软件android版,电子工程世界app下载-电子工程世界 安卓版v1.0-PC6安卓网...
  8. 数据预处理——离散化
  9. nRF52833-QIAA-R nordic无线收发芯片
  10. 春困夏乏 ,8种食物提神抗疲劳