首页 > 其他分享 >DailyRollingFileAppender 支持设置最大日志数量

DailyRollingFileAppender 支持设置最大日志数量

时间:2022-12-14 18:39:22浏览次数:50  
标签:return DailyRollingFileAppender File appender 设置 日志 logfile log4j


Log4j现在已经被大家熟知了,所有细节都可以在网上查到,Log4j支持Appender,其中DailyRollingFileAppender是被经常用到的Appender之一。

最常用的Appender——RollingFileAppender

下面是RollingFileAppender的一个Log4j配置样例(配置1):

根据文件大小进行进行回滚。

log4j.appender.R=org.apache.log4j.RollingFileAppender  
log4j.appender.R.Threshold=DEBUG
log4j.appender.R.File=test.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%5p] - %c -%F(%L) -%m%n
log4j.appender.R.MaxFileSize=20MB
log4j.appender.R.MaxBackupIndex=10

RollingFileAppender使用MaxFileSize设置一个日志文件的最大大小,当产生多个日志时,会在日志名称后面加上".1"、".2"、……这样的后缀,我们可以看到RollingFileAppender有个属性MaxBackupIndex,这个属性通过限制日志文件名后缀".n"中的n大小来限制日志数量,比如上面MaxBackupIndex=10,其实最大日志数量为11。我们知道这个有这个限制是很必要的,当我们的程序在服务器上运行时,随着时间的迁移,日志会越来越多,如果对日志数量没有限制,日志大小会越来越大,最后甚至占满整个硬盘。

可以按照周期时间来滚动日志文件的Appender——DailyRollingFileAppender

下面是DailyRollingFileAppender的一个Log4j配置样例(配置2):

log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfile.File=test.log
log4j.appender.logfile.DataPattern='.'yyyy-MM-dd-HH-mm
log4j.appender.logfile.Threshold=debug
log4j.appender.logfile.encoding=UTF-8
log4j.appender.logfile.Append=false
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern= [%d{yyyy-MM-dd HH\:mm\:ss}]%-5p %c(line\:%L) %x-%m%n

DailyRollingFileAppender特点是固定周期时间生成一个日志文件,比如,默认情况是每天生成一个文件。这种日志可以方便根据时间来定位日志位置,使日志清晰易查。但是这种日志有个不好地方是,不能限制日志数量,MaxBackupIndex属性和MaxFileSize在DailyRollingFileAppender中是无效的,我们上面已经提到限制日志数量的必要性。这里有两个解决办法:

  • linux上crontab+shell
  • java进程里面起一个线程,定期扫描日志文件夹。

重写DailyRollingFileAppender——CustomDailyRollingFileAppender

查看DailyRollingFileAppender源代码,发现rollOver()方法是用来生成文件的,当调用subAppend()方法时会根据判断当前时间是否大于应该生成新文件的时间了(具体实现可以查看源码,逻辑还是比较清晰的),如果大于,就生成。首先把当前日志重命名,命名格式为test.log.yyyy-MM-dd-HH-mm,然后重新建test.log文件。看到这里我们就可以想,在rollOver()方法里面加上删除过多的日志就不行了吗,的确可以这么做:

package org.apache.log4j;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.text.ParseException;
import java.util.*;


public class CustomDailyRollingFileAppender extends DailyRollingFileAppender {


private static Logger logger = LoggerFactory.getLogger(CustomDailyRollingFileAppender.class);

private int maxFileSize = 5;

@Override
void rollOver() throws IOException {
super.rollOver();

logger.debug("保留文件数量" + maxFileSize + ",日志文件名称为:" + fileName);
List<File> fileList = getAllLogs();
sortFiles(fileList);
logger.debug(fileList.toString());
deleteOvermuch(fileList);
}

/**
* 删除过多的文件
* @param fileList 所有日志文件
*/
private void deleteOvermuch(List<File> fileList) {
if (fileList.size() > maxFileSize) {
for (int i = 0;i < fileList.size() - maxFileSize;i++) {
fileList.get(i).delete();
logger.debug("删除日志" + fileList.get(i));
}
}
}

/**
* 根据文件名称上的特定格式的时间排序日志文件
* @param fileList
*/
private void sortFiles(List<File> fileList) {
Collections.sort(fileList, new Comparator<File>() {
public int compare(File o1, File o2) {
try {
if (getDateStr(o1).isEmpty()) {
return 1;
}
Date date1 = sdf.parse(getDateStr(o1));

if (getDateStr(o2).isEmpty()) {
return -1;
}
Date date2 = sdf.parse(getDateStr(o2));

if (date1.getTime() > date2.getTime()) {
return 1;
} else if (date1.getTime() < date2.getTime()) {
return -1;
}
} catch (ParseException e) {
logger.error("", e);
}
return 0;
}
});
}

private String getDateStr(File file) {
if (file == null) {
return "null";
}
return file.getName().replaceAll(new File(fileName).getName(), "");
}

/**
* 获取所有日志文件,只有文件名符合DatePattern格式的才为日志文件
* @return
*/
private List<File> getAllLogs() {
final File file = new File(fileName);
File logPath = file.getParentFile();
if (logPath == null) {
logPath = new File(".");
}

File files[] = logPath.listFiles(new FileFilter() {
public boolean accept(File pathname) {
try {
if (getDateStr(pathname).isEmpty()) {
return true;
}
sdf.parse(getDateStr(pathname));
return true;
} catch (ParseException e) {
// logger.error("", e);
return false;
}
}
});
return Arrays.asList(files);
}
public int getMaxFileSize() {
return maxFileSize;
}

public void setMaxFileSize(int maxFileSize) {
this.maxFileSize = maxFileSize;
}
}

首先,要注意的就是怎么判断日志文件夹中的日志是否是日志还是另外不相关的文件,比如备份的日志、控制台日志等。我使用的方法就是判断sdf.parse(name.replaceAll(file.getName(), ""))是否报异常,如果不报异常就说明这个文件是日志,当然不排除有的文件命名恰好符合这个格式,但是这样的文件在日志文件夹下,我们认为它就是一个日志文件也是合理的。然后我们根据sdf.parse(name.replaceAll(file.getName(), ""))解析出来的Date为所有日志进行升序排序放到一个队列中,再保留这个队列最后maxFileSize个文件的情况下,删除多余的日志文件。

然后,我们注意到我们上面的逻辑中用了maxFileSize这个变量,这个变量在MyDailyRollingFileAppender中,这个变量是怎么赋值的呢?

  log4j.appender.logfile.MaxFileSize=5  在设置时但是没有生效,如果各位知道问题,请各位看官留言。

log4j.appender.logfile=org.apache.log4j.MyDailyRollingFileAppender
log4j.appender.logfile.File=test.log
log4j.appender.logfile.DatePattern='.'yyyy-MM-dd-HH-m
log4j.appender.logfile.MaxFileSize=5
log4j.appender.logfile.Append=false
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern= [%d{yyyy-MM-dd HH\:mm\:ss}]%-5p %c(line\:%L) %x-%m%n

 

标签:return,DailyRollingFileAppender,File,appender,设置,日志,logfile,log4j
From: https://blog.51cto.com/u_15461374/5938145

相关文章

  • Elasticsearch+Logstash+Kiabana 日志管理
       日志是分析线上问题的重要手段,通常我们会把日志输出到控制台或者本地文件中,排查问题时通过根据关键字搜索本地日志,但越来越多的公司,项目开发中采用分布式的架构,日......
  • Gateway 代理日志记录 Filter
    前言我们在使用网关的时候,有时候客户端会有莫名其妙的问题需要服务端辅助定位,这时候有一份完全的请求的信息的日志会非常有帮助,这里提供一种基于过滤器的实现方式。我的实......
  • 使用Power Automate设置定时任务,调用Action
    使用PowerAutomate设置定时任务,调用Action前言使用PowerAutomate设置定时任务,调用的Action是我之前写的那边文章中的Action,附文章:创建自定义Action(全局)1.打开PowerAu......
  • SpringBoot 设置动态定时任务
    前言SpringBoot项目中简单使用定时任务,不过由于要借助cron表达式且都提前定义好放在配置文件里,不能在项目运行中动态修改任务执行时间,不是太灵活,改文章是主要是实现在固定的......
  • C++ 如果设置日期 & 时间基础篇
        ......
  • win 设置环境变量
    1.输入sysdm.cpl检索2、在系统属性界面内选择高级,然后点击环境变量。3、在这里我们可以看到所显示的变量,单机新建就能新建一个环境变量。选中自己要设置更改的变量再......
  • 今日份JS解密日志
    今天拿到手的JS加密源代码如下functionenterKeyDown(_0x28623b){const_0x32979d=_0x58fe;const_0xde64a8=_0x1d66;try{let_0x1f57e5=msgIn......
  • Python用telnet设置,抓UDP抓采样点并显示
    ====main.bat====echooffrem"d:\Program\WiresharkPortable64\App\Wireshark\tshark.exe"--list-interfacesrem"d:\Program\WiresharkPortable64\App\Wireshark\tsha......
  • EasyExcel导出样式设置(注解)
    EasyExcel导出样式设置(注解)参考资料链接1:EasyExcel--自定义表头(标题)样式策略参考资料链接2:EasyExcel常用注解参考资料链接3:EasyExcel注解大全@HeadRowHeight......
  • 组策略中软件限制策略设置为所有软件都不允许后,无法登录桌面的解决办法
    今天,由于不当操作,以为该设置只针对用户安装的软件不针对系统软件,所以设置成所有软件都不允许结果重启电脑登录后无法显示桌面无法再次启动组策略恢复设置  通过思考......