`

Log4j扩展的一个按天滚动的appender类,同时支持动态日志

阅读更多

扩展的一个按天滚动的appender类 暂时不支持datePattern设置,但是可以配置maxBackupIndex,该源代码来自网上,因为需要生成动态日志,做了一点点扩展.

log4j.properties 

log4j.rootLogger=info,stdout,file
log4j.logger.org=info

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
log4j.appender.file=com.dmx.log4jext.DayRollingFileAppender
log4j.appender.file.File=/opt/logs/log.log
log4j.appender.file.vmProperty=weblogic.Name
log4j.appender.file.maxBackupIndex=7
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{HH\:mm\:ss} %-5p [%t] (%13F\:%L) %3x - %m%n

 

 java代码:

package com.dmx.log4jext;

import org.apache.log4j.FileAppender;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Layout;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;

/**
 * 扩展的一个按天滚动的appender类 暂时不支持datePattern设置,但是可以配置maxBackupIndex
 */
public class DayRollingFileAppender extends FileAppender {

	// 不允许改写的datepattern
	private final String datePattern = "'.'yyyy-MM-dd";

	// 最多文件增长个数
	private int maxBackupIndex = 2;

	// 文件名+上次最后更新时间
	private String scheduledFilename;

	// 系统参数属性 根据系统属性动态生成日志文件名
	private String vmProperty;

	// The next time we estimate a rollover should occur
	private long nextCheck = System.currentTimeMillis() - 1;

	Date now = new Date();

	SimpleDateFormat sdf;

	public DayRollingFileAppender() {
	}

	public DayRollingFileAppender(Layout layout, String vmProperty,
			String filename, int maxBackupIndex) throws IOException {

		super(layout, filename, true);
		this.vmProperty = vmProperty;
		this.maxBackupIndex = maxBackupIndex;
		activateOptions();
	}

	/**
	 * 初始化本Appender对象的时候调用一次
	 */
	public void activateOptions() {
		super.activateOptions();
		if (fileName != null) { // perf.log
			now.setTime(System.currentTimeMillis());
			sdf = new SimpleDateFormat(datePattern);
			File file = new File(fileName);
			// 获取最后更新时间拼成的文件名
			scheduledFilename = fileName
					+ sdf.format(new Date(file.lastModified()));
		} else {
			LogLog.error("File is not set for appender [" + name + "].");
		}
		if (maxBackupIndex <= 0) {
			LogLog.error("maxBackupIndex reset to default value[2],orignal value is:"
					+ maxBackupIndex);
			maxBackupIndex = 2;
		}
	}

	/**
	 * 滚动文件的函数: 1.对文件名带的时间戳进行比较,确定是否更新 2.if需要更新,当前文件rename到文件名+日期, 重新开始写文件
	 * 3.针对配置的maxBackupIndex,删除过期的文件
	 */
	void rollOver() throws IOException {

		String datedFilename = fileName + sdf.format(now);
		// 如果上次写的日期跟当前日期相同,不需要换文件
		if (scheduledFilename.equals(datedFilename)) {
			return;
		}

		// close current file, and rename it to datedFilename
		this.closeFile();

		File target = new File(scheduledFilename);
		if (target.exists()) {
			target.delete();
		}

		File file = new File(fileName);
		boolean result = file.renameTo(target);
		if (result) {
			LogLog.debug(fileName + " -> " + scheduledFilename);
		} else {
			LogLog.error("Failed to rename [" + fileName + "] to ["
					+ scheduledFilename + "].");
		}

		// 删除过期文件
		if (maxBackupIndex > 0) {
			File folder = new File(file.getParent());
			List<String> maxBackupIndexDates = getMaxBackupIndexDates();
			for (File ff : folder.listFiles()) { // 遍历目录,将日期不在备份范围内的日志删掉
				if (ff.getName().startsWith(file.getName())
						&& !ff.getName().equals(file.getName())) {
					// 获取文件名带的日期时间戳
					String markedDate = ff.getName().substring(
							file.getName().length());
					if (!maxBackupIndexDates.contains(markedDate)) {
						result = ff.delete();
					}
					if (result) {
						LogLog.debug(ff.getName() + " ->deleted ");
					} else {
						LogLog.error("Failed to deleted old DayRollingFileAppender file :"
								+ ff.getName());
					}
				}
			}
		}

		try {
			// This will also close the file. This is OK since multiple
			// close operations are safe.
			this.setFile(fileName, false, this.bufferedIO, this.bufferSize);
		} catch (IOException e) {
			errorHandler.error("setFile(" + fileName + ", false) call failed.");
		}
		scheduledFilename = datedFilename; // 更新最后更新日期戳
	}

	/**
	 * Actual writing occurs here. 这个方法是写操作真正的执行过程!
	 */
	protected void subAppend(LoggingEvent event) {
		long n = System.currentTimeMillis();
		if (n >= nextCheck) { // 在每次写操作前判断一下是否需要滚动文件
			now.setTime(n);
			nextCheck = getNextDayCheckPoint(now);
			try {
				rollOver();
			} catch (IOException ioe) {
				LogLog.error("rollOver() failed.", ioe);
			}
		}
		super.subAppend(event);
	}

	/**
	 * 获取下一天的时间变更点
	 * 
	 * @param now
	 * @return
	 */
	long getNextDayCheckPoint(Date now) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(now);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);// 注意MILLISECOND,毫秒也要置0.。。否则错了也找不出来的
		calendar.add(Calendar.DATE, 1);
		return calendar.getTimeInMillis();
	}

/**
	* 根据maxBackupIndex配置的备份文件个数,获取要保留log文件的日期范围集合
	* 
	* @return list<'fileName+yyyy-MM-dd'>
	*/
	List<String> getMaxBackupIndexDates() {
		List<String> result = new ArrayList<String>();
		if (maxBackupIndex > 0) {
			for (int i = 1; i <= maxBackupIndex; i++) {
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(now);
				calendar.set(Calendar.HOUR_OF_DAY, 0);
				calendar.set(Calendar.MINUTE, 0);
				calendar.set(Calendar.SECOND, 0);
				calendar.set(Calendar.MILLISECOND, 0);// 注意MILLISECOND,毫秒也要置0.。。否则错了也找不出来的
				calendar.add(Calendar.DATE, -i);
				result.add(sdf.format(calendar.getTime()));
			}
		}
		return result;
	}

	public int getMaxBackupIndex() {
		return maxBackupIndex;
	}

	public void setMaxBackupIndex(int maxBackupIndex) {
		this.maxBackupIndex = maxBackupIndex;
	}

	public String getDatePattern() {
		return datePattern;
	}

	public String getVmProperty() {
		return vmProperty;
	}

	public void setVmProperty(String vmProperty) {
		this.vmProperty = vmProperty;

		// 改变fileName的值
		if (null != vmProperty && !"".equals(vmProperty)) { // if-one
			// 从jvm中获取系统参数
			String vmValue = System.getProperty(vmProperty);

			if (vmValue != null && !"".equals(vmValue)) {// if-two
				fileName = this.parseFile(fileName, vmValue);
			}// end if-two

		}// end if-one

	}

	private String parseFile(String str, String parseStr) {

		if (str != null && !"".equals(str) && parseStr != null
				&& !"".equals(parseStr)) {
			// 对配置文件中的File进行解析看是否带有路径
			String tempStr = str.replaceAll("\\/", "@").replaceAll("\\\\", "@");
			// String[] strArr = str.split("\\/").length>0 ? str.split("\\/") :
			// str.split("\\\\");
			String[] strArr = tempStr.split("@");
			String temp = parseStr + "-" + strArr[strArr.length - 1];
			str = str.replace(strArr[strArr.length - 1], temp);
			return str;
		} else {
			return str;
		}

	}

	public static void main(String[] args) {
		DayRollingFileAppender aa = new DayRollingFileAppender();
		String path = "E:\\opt\\apps\\log\\portal-vpg.log";
		path = "/opt/apps/logs/portal-vpg.log";
		String bb = aa.parseFile(path, "dianbo113");
		System.out.println(bb);
	}
}

 

分享到:
评论

相关推荐

    log4j日志驱动包

    log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000 # 发送日志给邮件 log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender log4j.appender....

    log4j 同时按日期和文件大小分割日志

    已经封装好,把log4j.appender.fileout=org.apache.log4j.Log4JDateAndSizeSplit 即可,其余和原api一样: log4j.appender.fileout.MaxFileSize=10240KB log4j.appender.fileout.MaxBackupIndex=20

    log4j按照不同appender生成日志例子

    log4j按照不同appender生成日志例子,log4j按照不同接口生成各自日志文件小例子。

    log4j 根据日期和文件大小切分日志

    由公司的项目需要根据日期和文件大小切分log4j日志,所以实现来该appender。本人测试通过,并且在公司的其它项目中已有线上使用,暂时还没发现问题。本人代码有写得不好或者错误的地方,欢迎大家指正,谢谢!!!

    Log4j日志包

    # 每天一个日志文件 ################### log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender log4j.appender.A1.File=c\:\\SampleMessages.html log4j.appender.A1.DatePattern=yyyyMMdd-HH log4j....

    log4j常用Appender配置

    这个文档是本人自己打开log4j源码自己总结的,希望对大家有用。

    log4j中配置日志文件相对路径方法分析

    解决的办法自然是用相对路径代替绝对路径,其实log4j的FileAppender本身就有这样的机制,如:log4j.appender.logfile.File=${WORKDIR}/logs/app.log 其中“${WORKDIR}/”是个变量,会被System Property中的“WORKDIR...

    log4j(二):动态配置日志输出路径

    NULL 博文链接:https://1017401036.iteye.com/blog/2332210

    log4j-1.2.9

    设置log4j的根目录,值为 日志等级(DEBUG,INFO,WARN,ERROR,FATAL) , 输出目标名称 log4j.rootLogger=DEBUG,A1 设置输出方式,常用的有: ConsoleAppender 在控制器中输出信息 RollingFileApperder 在文件中输出...

    log4j.CustomLogAppender 限制log4j文件保存天数

    每天生成一个log4j日志文件,如果只需要将最近一段时间内的日志文件保留,以前或更早的文件不用保留。例如只保留最近一周的日志,日志文件保留3天等等这些。。。通过这个jar包就可以实现。 log4j.properties文件在...

    Log4j日志管理系统简单使用说明

     禁用与使用日志请求只是Log4j其中的一个小小的地方,Log4j日志系统允许把日志输出到不同的地方,如控制台(Console)、文件(Files)、根据天数或者文件大小产生新的文件、以流的形式发送到其它地方等等。...

    aliyun-log-log4j-appender:aliyun-log-log4j-appender

    Apache log4j是一个Apache软件基础项目。 您可以通过Log4j控制日志的目的地。 它可以是控制台,文件,GUI组件,套接字,NT事件日志,系统日志。 您也可以控制每个日志的输出格​​式。 您可以通过日志级别控制日志...

    (转)如何自建appender扩展Log4j框架

    NULL 博文链接:https://ghl116.iteye.com/blog/1476308

    log4j.jar各个版本

    apache-log4j-1.2.15.jar, apache-log4j-extras-1.0.jar, apache-log4j-extras-1.1.jar, apache-log4j.jar, log4j-1.2-api-2.0.2-javadoc.jar, log4j-1.2-api-2.0.2-sources.jar, log4j-1.2-api-2.0.2.jar, log4j-...

    log4j_properties配置详解

    ### set log levels ###log4j.rootLogger = debug , stdout , D , E### 输出到控制台 ###log4j.appender.stdout =org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target =System.outlog4j.appender.stdout....

    log4j配置文件

    log4j.rootLogger=info, stdout, log, errorlog log4j.Logger=search,Test ###Console ### log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j....

    activemq-log4j-appender-5.10.0-sources.jar

    标签:activemq-log4j-appender-5.10.0-sources.jar,activemq,log4j,appender,5.10.0,sources,jar包下载,依赖包

    log4j根据日期和文件大小切分日志

    由公司的项目需要根据日期和文件大小切分log4j日志,所以实现来该appender。本人测试通过,并且在公司的其它项目中已有线上使用,暂时还没发现问题。本人代码有写得不好或者错误的地方,欢迎大家指正,谢谢!!!

    log4j-1.2.14

    设置log4j的根目录,值为 日志等级(DEBUG,INFO,WARN,ERROR,FATAL) , 输出目标名称 log4j.rootLogger=DEBUG,A1 设置输出方式,常用的有: ConsoleAppender 在控制器中输出信息 RollingFileApperder 在文件中输出...

Global site tag (gtag.js) - Google Analytics