LOG4J实现日切或者时切
来源:互联网 发布:电脑安装软件出现乱码 编辑:程序博客网 时间:2024/04/29 16:35
LOG4J 存在一个问题,一段时间内没有打印日志,LOG4J日志归档会空缺一些日志文件。
如果有监控系统对日志文件进行监控,可能就会导致误判。
如果在程序中定时向LOG4J中打印日志或者空格(打一个空格也会存在一个换行)也可以,但是会破坏日志的完整性,监控程序可能会解析出错等。
经过研究,提供一种方法,修改LOG4J的源码,保证无日志打印,日志文件也会定时归档。
1、重写 DailyRollingFileAppende 类。
package com.pouyang.log4j;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Locale;import java.util.TimeZone;import java.util.Timer;import java.util.TimerTask;import org.apache.log4j.FileAppender;import org.apache.log4j.Layout;import org.apache.log4j.helpers.LogLog;import org.apache.log4j.spi.LoggingEvent;public class UmpDailyRollingFileAppender extends FileAppender{ static final int TOP_OF_TROUBLE = -1; static final int TOP_OF_MINUTE = 0; static final int TOP_OF_HOUR = 1; static final int HALF_DAY = 2; static final int TOP_OF_DAY = 3; static final int TOP_OF_WEEK = 4; static final int TOP_OF_MONTH = 5; private String datePattern = "'.'yyyy-MM-dd"; private String scheduledFilename; private long nextCheck = System.currentTimeMillis() - 1L; private String categoryName = "MPSP"; Date now = new Date(); SimpleDateFormat sdf; RollingCalendar rc = new RollingCalendar(); Timer timer; org.slf4j.Logger _log ; int checkPeriod = -1; static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT"); public UmpDailyRollingFileAppender() { System.out.println("UmpDailyRollingFileAppender()"+this); } public UmpDailyRollingFileAppender(Layout layout, String filename, String datePattern) throws IOException { super(layout, filename, true); this.datePattern = datePattern; activateOptions(); System.out.println("UmpDailyRollingFileAppender()"+this); } public void setDatePattern(String pattern) { this.datePattern = pattern; } public String getDatePattern() { return this.datePattern; } public void activateOptions() { super.activateOptions(); if ((this.datePattern != null) && (this.fileName != null)) { this.now.setTime(System.currentTimeMillis()); this.sdf = new SimpleDateFormat(this.datePattern); int type = computeCheckPeriod(); printPeriodicity(type); this.rc.setType(type); File file = new File(this.fileName); this.scheduledFilename = (this.fileName + this.sdf.format(new Date(file.lastModified()))); this.timer = new Timer(); Date next = this.rc.getNextCheckDate(this.now); long perid = this.rc.getNextCheckMillis(next) - next.getTime(); Debug.log("timer.schedule(next,perid): "+next +","+perid+"ms"); _log = org.slf4j.LoggerFactory.getLogger(categoryName); this.timer.schedule(new RolloverFileTask(), next, perid); } else { LogLog.error("Either File or DatePattern options are not set for appender [" + this.name + "]."); } } void printPeriodicity(int type) { switch (type) { case 0: LogLog.debug("Appender [" + this.name + "] to be rolled every minute."); break; case 1: LogLog.debug("Appender [" + this.name + "] to be rolled on top of every hour."); break; case 2: LogLog.debug("Appender [" + this.name + "] to be rolled at midday and midnight."); break; case 3: LogLog.debug("Appender [" + this.name + "] to be rolled at midnight."); break; case 4: LogLog.debug("Appender [" + this.name + "] to be rolled at start of week."); break; case 5: LogLog.debug("Appender [" + this.name + "] to be rolled at start of every month."); break; default: LogLog.warn("Unknown periodicity for appender [" + this.name + "]."); } } int computeCheckPeriod() { RollingCalendar rollingCalendar = new RollingCalendar(gmtTimeZone, Locale.getDefault()); Date epoch = new Date(0L); if (this.datePattern != null) { for (int i = 0; i <= 5; i++) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat( this.datePattern); simpleDateFormat.setTimeZone(gmtTimeZone); String r0 = simpleDateFormat.format(epoch); rollingCalendar.setType(i); Date next = new Date(rollingCalendar.getNextCheckMillis(epoch)); String r1 = simpleDateFormat.format(next); if ((r0 != null) && (r1 != null) && (!r0.equals(r1))) { return i; } } } return -1; } /** * old log LOGARCHIVE * log4j locked http://blog.163.com/qiongling007@126/blog/static/214242962011102344916998/ * log4j time gen log file: http://www.iteye.com/topic/1006379 * @throws IOException */ void rollOver() throws IOException { if (this.datePattern == null) { this.errorHandler.error("Missing DatePattern option in rollOver()."); return; } String datedFilename = this.fileName + this.sdf.format(this.now); //Debug.log("rollOver() datedFilename: "+datedFilename); //Debug.log("rollOver() scheduledFilename: "+scheduledFilename); if (this.scheduledFilename.equals(datedFilename)) { return; } closeFile(); File target = new File(this.scheduledFilename); if (target.exists()) { System.out.println("scheduledFilename- exists- "); target.delete(); } File file = new File(this.fileName); boolean result = file.renameTo(target); if (result) LogLog.debug(this.fileName + " -> " + this.scheduledFilename); else { LogLog.error("Failed to rename [" + this.fileName + "] to [" + this.scheduledFilename + "]."); } try { //setFile(this.fileName, true, this.bufferedIO, this.bufferSize); setFile(this.fileName, false, this.bufferedIO, this.bufferSize); } catch (IOException e) { this.errorHandler.error("setFile(" + this.fileName + ", false) call failed."); } this.scheduledFilename = datedFilename; } protected void subAppend(LoggingEvent event) { long n = System.currentTimeMillis(); if (n >= this.nextCheck) { this.now.setTime(n); this.nextCheck = this.rc.getNextCheckMillis(this.now); try { rollOver(); } catch (IOException ioe) {// if ((ioe instanceof InterruptedIOException)) {// Thread.currentThread().interrupt();// } LogLog.error("rollOver() failed.", ioe); } } super.subAppend(event); } class RolloverFileTask extends TimerTask { RolloverFileTask() { } public void run() { /** * 通过定时打印日志,触发 subAppend(LoggingEvent event) 方法,进行日切日志文件归档。 * mod by oyp 2014-12-04 18:22:30 * @@@Time log cutting@@@ */ try { //Debug.log("-"+categoryName+"@@@-LOGARCHIVE-@@@ timing output log to generate a log file"); /** * log in system.log ,not in mpsp.log, because not the same layout */ _log.info(Debug.LOGARCHIVE+" timing output log to generate a log file"); } catch (Exception e) { e.printStackTrace(); }// System.out.println(System.currentTimeMillis()+"---------------------run---------------------");// long n = System.currentTimeMillis();// if (n >= UmpDailyRollingFileAppender.this.nextCheck) {// UmpDailyRollingFileAppender.this.now.setTime(n);// UmpDailyRollingFileAppender.this.nextCheck = UmpDailyRollingFileAppender.this.rc.getNextCheckMillis(UmpDailyRollingFileAppender.this.now);// try {// UmpDailyRollingFileAppender.this.rollOver();// } catch (IOException ioe) {// if ((ioe instanceof InterruptedIOException)) {// Thread.currentThread().interrupt();// }// LogLog.error("rollOver() failed.", ioe);// System.out.println(ioe);// }// } } }public String getCategoryName() {return categoryName;}public void setCategoryName(String categoryName) {this.categoryName = categoryName;}}
2、重写 PatternLayout。
package com.pouyang.log4j;/** * @author ouyangping * @date Dec 4, 2014 */import org.apache.log4j.Layout;import org.apache.log4j.helpers.PatternConverter;import org.apache.log4j.helpers.PatternParser;import org.apache.log4j.spi.LoggingEvent;public class UmpPatternLayout extends Layout{ public static final String DEFAULT_CONVERSION_PATTERN = "%m%n"; public static final String TTCC_CONVERSION_PATTERN = "%r [%t] %p %c %x - %m%n"; protected final int BUF_SIZE = 256; protected final int MAX_CAPACITY = 1024; private StringBuffer sbuf = new StringBuffer(256); private String pattern; private PatternConverter head; private String timezone; public UmpPatternLayout() { this("%m%n"); } public UmpPatternLayout(String pattern) { this.pattern = pattern; this.head = createPatternParser(pattern == null ? "%m%n" : pattern).parse(); } public void setConversionPattern(String conversionPattern) { this.pattern = conversionPattern; this.head = createPatternParser(conversionPattern).parse(); } public String getConversionPattern() { return this.pattern; } public void activateOptions() { } public boolean ignoresThrowable() { return true; } protected PatternParser createPatternParser(String pattern) { return new PatternParser(pattern); } public String format(LoggingEvent event) { if (this.sbuf.capacity() > 1024) this.sbuf = new StringBuffer(256); else { this.sbuf.setLength(0); } PatternConverter c = this.head; while (c != null) { c.format(this.sbuf, event); c = c.next; } //System.out.println("layout2:"+this.sbuf.toString()); //System.out.println("layout2:"+ MyUtil.bcd(this.sbuf.toString().getBytes())); /** * 过滤掉定时任务执行生成对账文件的日志,只打一个空串且不包含换行操作 * add by oyp 2014-12-04 18:22:44 */// String mesg = this.sbuf.toString();// Debug.log(mesg);// String[] temp = mesg.split("-");// if ( temp.length >= 2 && ( temp[1] == null || "".equals(temp[1].trim())) ) {// return "";// } else {// return mesg;// } String mesg = this.sbuf.toString(); if (mesg.contains(Debug.LOGARCHIVE)) { //Debug.log(mesg); return ""; } else { return mesg; } //return this.sbuf.toString(); }}
0 0
- LOG4J实现日切或者时切
- RCP或者插件 log4j
- Log4j配置学习文档之二 处理日滚文件-实现原理
- Log4j配置学习文档之二 处理日滚文件-模拟实现
- 自动读取log4j.xml或者log4j.properties的问题
- 09月04日学习杂记(LOG4J)
- axjs2 file 实现log4j
- ssh实现log4j
- log4j 实现日志管理
- Log4j源码实现
- Log4j 实现日志统一管理
- log4j实现日志记录
- Log4j 实现运行时的日志级别更改
- Weblogic的War或者EAR应用与log4j的搭配
- spring-junit中使用 log4j或者logback 打印spring日志
- 用js或者CSS实现鼠标指向图片时放大
- common-logging+log4j实现机制
- log4j实现日志集中存储
- socket TCP编程中connect的一些坑
- 线程中断方法interrupt() 与 cancel()以及Runtime.getRuntime().addShutdownHook()
- 函数调用栈的获取原理分析
- storm集群安装过程
- 汇编语言子函数——延时函数
- LOG4J实现日切或者时切
- JSONObject转Java对象的方法
- Servlet中显示提示框
- oracle with as用法
- 棋盘问题 POJ 1321 DFS
- day02-XML约束
- Bitbucket使用
- Kafka安装过程
- Pre-built.2网络库在cocos2dx中的使用