文档章节

log4j 每次运行生成新文件 功能

-悟空-
 -悟空-
发布于 2014/11/21 09:32
字数 627
阅读 363
收藏 10

开发中我有个需求就是,每次运行都生成新的log文件,因为我主要跑的测试,有些数据想比对还不想都放在一个文件中,这样查找起来不方便。在网上找了些发现log4j配置上没有办法满足我的需求,所以就写了个自定义类PerRunRollingFileAppender。

大致逻辑为:

读取配置文件中你配置文件的路径,遍历这个路径如果文件已经存在就重命名生成新的文件,哦对了,我这里还有在配置文件名前加了个前缀PerRunRollingFileAppender.LoggerNamePrefix,这样你可以在使用相同配置的时候,让每个测试类中生成的日志文件名不同。

只要在启动PropertyConfigurator.configure("./conf/log4j_default.properties");之前,配置PerRunRollingFileAppender.LoggerNamePrefix值就可以了。

note:有参考了他人代码,附上地址How to create a new log file for each time the application runs? ,但是他的可能没有测试,有个小bug,各位可以跑下亲自测下。

以下是我的代码:

package com.logger;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.spi.ErrorCode;

public class PerRunRollingFileAppender extends FileAppender {

	public static String LoggerNamePrefix="default";
	private static final String DOT = ".";
	private static final String UNDERLINE="_";
	public PerRunRollingFileAppender() {
	}

	public PerRunRollingFileAppender(Layout layout, String filename, boolean append,
			boolean bufferedIO, int bufferSize) throws IOException {
		super(layout, filename, append, bufferedIO, bufferSize);
	}

	public PerRunRollingFileAppender(Layout layout, String filename, boolean append)
			throws IOException {
		super(layout, filename, append);
	}

	public PerRunRollingFileAppender(Layout layout, String filename)
			throws IOException {
		super(layout, filename);
	}

	public void activateOptions() {
		if (fileName != null) {
			try {
				fileName = getNewLogFileName();
				setFile(fileName, fileAppend, bufferedIO, bufferSize);
			} catch (Exception e) {
				errorHandler.error("Error while activating log options", e,
						ErrorCode.FILE_OPEN_FAILURE);
			}
		}
	}

	private String getNewLogFileName() {
		if (fileName != null) {
			
			final String LEFTPARENTHESIS="(";
			final String RIGHTPARENTHESIS=")";
			final File logFile = new File(fileName);
			final String fileName = logFile.getName();
			final int dotIndex = fileName.indexOf(DOT);
			String newFileName = "";
			Integer number = -1;

			File[] files = logFile.getParentFile().listFiles(new CustomFilter());
			Pattern pattern = Pattern.compile("(?<=\\()[\\d]+");  
			  
			if(files!=null&&files.length>0){
				number++;
				for (File file : files) {
					
					Matcher matcher = pattern.matcher(file.getName());
					if(matcher.find()){
						if(number<Integer.valueOf(matcher.group(0))){
							
							number=Integer.valueOf(matcher.group(0));
						}
					}
				}
			}
			
			
				
			if (dotIndex != -1) {
				// the file name has an extension. so, insert the time stamp
				// between the file name and the extension
				String tempFileName = fileName.substring(0,dotIndex);
				final int parenthesis = tempFileName.indexOf(LEFTPARENTHESIS);
				if(parenthesis!=-1){
					tempFileName=tempFileName.substring(parenthesis);
				}
				
				if(number>-1){
					newFileName = LoggerNamePrefix + UNDERLINE+ tempFileName   
							+ LEFTPARENTHESIS+(++number)+RIGHTPARENTHESIS
							+ fileName.substring(dotIndex);
				}else{
					newFileName = LoggerNamePrefix + UNDERLINE+ tempFileName   
							+ fileName.substring(dotIndex);
				}
				
			} else {
				
				//是否存在文件名中存在()
				if(number>-1){
					newFileName = LoggerNamePrefix
									+ UNDERLINE
									+ fileName
									+ LEFTPARENTHESIS+(++number)+RIGHTPARENTHESIS;
				}else{
					newFileName = LoggerNamePrefix + UNDERLINE+ fileName;  
				}
				
			}
			return logFile.getParent() + File.separator + newFileName;
		}
		return null;
	}
	
	
	class CustomFilter implements FilenameFilter{  
		
        public boolean accept(File dir,String name){  
        	
        	File logFile = new File(fileName);
        	String fileName = logFile.getName();
        	int indexDot = fileName.lastIndexOf(DOT);
        	if(indexDot!=-1){
        		return name.startsWith(LoggerNamePrefix+UNDERLINE+fileName.substring(0,indexDot));
        	}else{
        		return name.startsWith(LoggerNamePrefix+UNDERLINE+fileName);
        	}
              
        }  
    }  
}

配置文件:

log4j.logger.info=info
log4j.appender.info=com.logger.PerRunRollingFileAppender
log4j.appender.info.File=/mnt/log/info.log
log4j.appender.console.Threshold = DEBUG
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=%d{hh:mm:ss}:%p %t  %l - %m%n

这样就可以啦,希望能帮助到其他人。

© 著作权归作者所有

共有 人打赏支持
-悟空-

-悟空-

粉丝 141
博文 25
码字总数 35562
作品 0
海淀
高级程序员
log4j:WARN Please initialize the log4j system p...

log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext). log4j:WARN Please initialize the log4j system properly. S......

进击的方便面
2013/09/26
0
0
log4j.properties配置详解

Log4J的配置文件(Configuration File)就是用来设置记录器的级别、存放器和布局的,它可接key=value格式的设置或xml格式的设置信息。通过配置,可以创建出Log4J的运行环境。 1. 配置文件 Log4...

sfilyh
2012/03/30
0
0
Java混乱的日志体系(logback)(转)

作为一名 Java 程序员,日常开发工作中肯定会接触日志系统,但是众多的框架,包括 Log4j、Log4j2、Logback、Slf4j、Apache Common logging 等等,引用的 maven 依赖众多,到底可以去掉哪些,...

easonjim
2017/12/27
0
0
log4j WARN 的解决办法

log4j 是什么 Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们...

黑泽明军
06/21
0
0
logback与Log4J的区别

Logback和log4j是非常相似的,如果你对log4j很熟悉,那对logback很快就会得心应手。下面列了logback相对于log4j的一些优点: 更快的实现 Logback的内核重写了,在一些关键执行路径上性能提升...

凯文加内特
2015/05/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Android JNI 开发系列(九)JNI调用Java的静态方法&实例方法

JNI调用Java的静态方法&实例方法 package org.professor.jni.bean;import android.util.Log;/** * Created by peng on 2018/10/11. */ public class Person { /*C/CPP 调用......

蔡小鹏
12分钟前
0
0
Flink 原理与实现:Window 机制

Flink 认为 Batch 是 Streaming 的一个特例,所以 Flink 底层引擎是一个流式引擎,在上面实现了流处理和批处理。而窗口(window)就是从 Streaming 到 Batch 的一个桥梁。Flink 提供了非常完...

xtof
14分钟前
0
0
Fabric.js高级点的教程2--添加表格的方法

有时候我们先在画布上画一个表格类似一下设计软件那种。一方面作为参考线,一方面给人一直专业的赶脚。。。 先贴上一段网上(不是我写的)可以运行的代码 https://codepen.io/rodan8888/pen/e...

xmqywx
14分钟前
0
0
Java中Lambda表达式的使用

Java中Lambda表达式的使用 简介 (译者注:虽然看着很先进,其实Lambda表达式的本质只是一个"语法糖",由编译器推断并帮你转换包装为常规的代码,因此你可以使用更少的代码来实现同样的功能。本人...

DemonsI
17分钟前
0
0
深入理解Java中停止线程

一.停止线程会带来什么? 对于单线程中,停止单线程就是直接使用关键字return或者break,但是在停止多线程时是让线程在完成任务前去开启另外一条线程,必须放弃当前任务,而这个过程是不可预...

Ala6
26分钟前
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部