文档章节

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

-悟空-
 -悟空-
发布于 2014/11/21 09:32
字数 627
阅读 1.1K
收藏 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

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

-悟空-

-悟空-

粉丝 144
博文 25
码字总数 35562
作品 0
海淀
高级程序员
私信 提问
加载中
请先登录后再评论。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
用vertx实现高吞吐量的站点计数器

工具:vertx,redis,mongodb,log4j 源代码地址:https://github.com/jianglibo/visitrank 先看架构图: 如果你不熟悉vertx,请先google一下。我这里将vertx当作一个容器,上面所有的圆圈要...

jianglibo
2014/04/03
4.4K
3
浅入浅出Android(003):使用TextView类构造文本控件

基础: TextView是无法供编辑的。 当我们新建一个项目MyTextView时候,默认的布局(/res/layout/activity_main.xml)中已经有了一个TextView: <TextView 运行效果如下: 修改其文本内容...

樂天
2014/03/22
718
1
我的架构演化笔记 功能1: 基本的用户注册

“咚咚”,一阵急促的敲门声, 我从睡梦中惊醒,我靠,这才几点,谁这么早, 开门一看,原来我的小表弟放暑假了,来南京玩,顺便说跟我后面学习一个网站是怎么做出来的。 于是有了下面的一段...

强子哥哥
2014/05/31
976
3
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
22

没有更多内容

加载失败,请刷新页面

加载更多

Hacker News 简讯 2020-08-15

最后更新时间: 2020-08-15 04:01 Welders set off Beirut blast while securing explosives - (maritime-executive.com) 焊工在固定炸药的同时引爆了贝鲁特爆炸 得分:215 | 评论:209 Factor......

FalconChen
今天
24
0
OSChina 周六乱弹 —— 老椅小猫秋乡梦 梦里石台堆小鱼

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @小小编辑 :《MOM》- 蜡笔小心 《MOM》- 蜡笔小心 手机党少年们想听歌,请使劲儿戳(这里) @狄工 :腾讯又在裁员了,35岁以上清退,抖音看到...

小小编辑
今天
61
1
构建高性能队列,你不得不知道的底层知识!

前言 本文收录于专辑:http://dwz.win/HjK,点击解锁更多数据结构与算法的知识。 你好,我是彤哥。 上一节,我们一起学习了如何将递归改写为非递归,其中,用到的数据结构主要是栈。 栈和队列...

彤哥读源码
今天
17
0
Anaconda下安装keras和tensorflow

Anaconda下安装keras和tensorflow 一、下载并安装Anaconda: Anaconda下载 安装步骤: 如果是多用户操作系统选择All Users,单用户选择Just Me 选择合适的安装路径 然后勾选这个,自动配置环境...

Atlantis-Brook
今天
15
0
滴滴ElasticSearch千万级TPS写入性能翻倍技术剖析

桔妹导读:滴滴ElasticSearch平台承接了公司内部所有使用ElasticSearch的业务,包括核心搜索、RDS从库、日志检索、安全数据分析、指标数据分析等等。平台规模达到了3000+节点,5PB 的数据存储...

滴滴技术
今天
13
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部