Java tutorial
/* * @(#)BizStaticFileAppender.java 1.6 05/03/10 * * Copyright (c) 2003-2005 ASPire Technologies, Inc. * 6/F,IER BUILDING, SOUTH AREA,SHENZHEN HI-TECH INDUSTRIAL PARK Mail Box:11# 12#. * All rights reserved. * * This software is the confidential and proprietary information of * ASPire Technologies, Inc. ("Confidential Information"). You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Aspire. */ package com.common.log.newproxy; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.time.DateFormatUtils; import org.apache.log4j.Layout; import org.apache.log4j.helpers.CountingQuietWriter; import org.apache.log4j.helpers.LogLog; import org.apache.log4j.spi.ErrorCode; import org.apache.log4j.spi.LoggingEvent; /** * <p>Title: BizStaticFileAppender</p> * <p>Description: it record the biz log and output the statistics of files of biz log * </p> * <p>Copyright: Copyright (c) 2003</p> * <p>Company: Aspire Technologies</p> * @author YanFeng * @version 1.6.5 * history * created at 2005/03/10 * @CheckItem@ BUG-Yanfeng-20060810 ? * @CheckItem@ REQ-huangbigui-20070522 ??? */ public class BizStaticFileAppender extends TimeSizeRollingFileAppender implements ErrorCode { /** * record the biz log stastics */ //private static File lastStatFile; //private boolean newStartup=false; //private static FileWriter fw; private long nextCheck = System.currentTimeMillis() - 1; /** * the current date for biz log stastics */ //private static Date currStatDate=new Date(); private static final String NEXT_LINE = System.getProperty("line.separator"); private final static String FILE_SEP = System.getProperty("file.separator"); private final static String PUBLISHED_CHECKFILE = ".pub"; private final static String CHECKFILE_PATH = "stat"; /** * 0 */ //private int ts_start; /** * ??? * ? */ private int ts_offset; /** * * ?true,??? * ?? */ private boolean first_on_day = true; /** * ? */ private File statFile; /** * ? */ private File extFile; /** * ? * ? */ // private long last_ts_trap; /** * ? * ??.n.bak,Pullbiz.log2005-09-14-23 */ private String lastLogFilePrefix; /** * ? * ??0; */ private int lastLogFileSize; /** * , */ private long currDate = getCurrDate(); /** * ????? */ private long lastDayTime = getCurrDate(); /** * ???:?'.'yyyy-MM-dd'.999999' */ private String stat_datepattern = "'.'yyyy-MM-dd'.999999'"; /** * ?? */ private String instantCreatChkfile = "false"; /** The default constructor does nothing. */ public BizStaticFileAppender() { super(); //newStartup=true; LogLog.debug("New BizStaticFileAppender instance"); } public BizStaticFileAppender(Layout layout, String filename, String datePattern) throws IOException { super(layout, filename, datePattern); //newStartup=true; LogLog.debug("New BizStaticFileAppender instance"); } public void activateOptions() { super.activateOptions(); // LogLog.debug("this.instantCreatChkfile:" + this.instantCreatChkfile); if ("true".equals(this.instantCreatChkfile)) { ChkfileCreatorObserver.addToListen(this); } } /** * */ private void publishOldCheckFile() { String statPath = LogHelper.getLogRootPath() + FILE_SEP + "log" + FILE_SEP + CHECKFILE_PATH + FILE_SEP; File path = new File(statPath); File[] checkFiles = path.listFiles(); if (checkFiles == null) {//tat return; } HashMap extLogMap = new HashMap(); HashMap chkLogMap = new HashMap(); ArrayList keyDate = new ArrayList(); for (int i = 0; i < checkFiles.length; i++) { File oldChkFile = checkFiles[i]; String tmpfileName = oldChkFile.getName(); String currfilename = currFile.getName(); if (!tmpfileName.startsWith(currFile.getName())) {//? continue; } if (tmpfileName.endsWith(".bak")) {//?? //int index=tmpfileName.indexOf(".log"); //String fileDate=tmpfileName.substring(index+4,index+4+10); //String bizName=tmpfileName.substring(0,index+4); int index = fileName.lastIndexOf(FILE_SEP); // String bizName = fileName.substring(index + 1); String fileDate = getUnidateFromFileName(tmpfileName, bizName, datePattern); extLogMap.put(bizName + fileDate, oldChkFile); } else if (tmpfileName.endsWith(".999999")) {//? int index = fileName.lastIndexOf(FILE_SEP); // String bizName = fileName.substring(index + 1); String fileDate = getUnidateFromFileName(tmpfileName, bizName, stat_datepattern); keyDate.add(bizName + fileDate); //? //String strCurrDate = StringUtils.toString(new Date(),"yyyyMMdd"); String yesterday = getLastDate(); if (yesterday.equals(fileDate)) { //??, chkLogMap.put(bizName + fileDate, oldChkFile); } } } for (int i = 0; i < keyDate.size(); i++) {//? String logDay = (String) keyDate.get(i); if (chkLogMap.containsKey(logDay)) {// File checkFile = (File) chkLogMap.get(logDay); try { File targetFile = new File(currFile.getParentFile(), checkFile.getName()); FileWriter fw = new FileWriter(checkFile, true); if (extLogMap.containsKey(logDay)) { // File extFile = (File) extLogMap.get(logDay); //? fw.write(extFile.getName() + NEXT_LINE); // File targetExtFile = new File(currFile.getParentFile(), extFile.getName()); fileCopy(extFile, targetFile); //? File publishedExtFile = new File(extFile.getParentFile(), extFile.getName() + PUBLISHED_CHECKFILE); extFile.renameTo(publishedExtFile); } fw.write("999999" + NEXT_LINE); fw.flush(); fw.close(); fileCopy(checkFile, targetFile); //? File publishedCheckFile = new File(checkFile.getParentFile(), checkFile.getName() + PUBLISHED_CHECKFILE); checkFile.renameTo(publishedCheckFile); } catch (IOException ex) { ex.printStackTrace(); } } } extLogMap.clear(); extLogMap = null; chkLogMap.clear(); chkLogMap = null; keyDate.clear(); keyDate = null; } /** * ???? * @return boolean */ private boolean inCheckTrap() { long n = System.currentTimeMillis(); long check = currDate + ts_offset * 1000; long ts_trap = n - check; if (ts_trap < 0) {//??? return true; } if (first_on_day) { // //? publishOldCheckFile(); first_on_day = false; } /* if (lastDayTime<currDate) {//?? if (first_on_day) {// first_on_day = false; //? // publishCheckFile(); // //statFile.delete(); } }*/ // last_ts_trap=ts_trap; return false; } /** * ?? * @param msg Object * @return boolean */ private boolean isLog2Extra(Object msg) { /* ????? if(ts_start > 0) {//?? String strMsg = (String)msg.toString(); String bizTsDate = strMsg.substring(ts_start,ts_start + 8); String currDate = StringUtils.toString(new Date(),"yyyyMMdd"); if(currDate.compareTo(bizTsDate) > 0) { //??,? //lastDay.append(bizTsDate); return true; } } else */if (msg instanceof BizLogContent) { //?? long bizTsDate = ((BizLogContent) msg).getTimestamp(); if (bizTsDate > 0) { //??? if (currDate > bizTsDate) { //?? //lastDay.append(bizTsDate); return true; } } } return false; } /** * * @return String */ private String getExtraLogFileName() { int index = lastLogFilePrefix.lastIndexOf(FILE_SEP); // String realName = lastLogFilePrefix.substring(index + 1); String extraFileName = realName + "." + (lastLogFileSize + 1) + LogConstants.LOG_BACKUP_SUFFIX; return extraFileName; } /** * ??? * @param event LoggingEvent * @return boolean ? */ private boolean log2extraFile(LoggingEvent event) { //? boolean hasLog = false; //StringBuffer lastDay=new StringBuffer(); if (inCheckTrap() && event != null) { Object msg = event.getMessage(); boolean needAppendExtra = isLog2Extra(msg); if (needAppendExtra) {//?? String statPath = LogHelper.getLogRootPath() + FILE_SEP + "log" + FILE_SEP + CHECKFILE_PATH + FILE_SEP; File path = new File(statPath); if (!path.exists()) { path.mkdir(); } String extraFileName = getExtraLogFileName(); extFile = new File(path, extraFileName); OutputStreamWriter exSw; FileOutputStream exFw; try { if (extFile.exists()) {// exFw = new FileOutputStream(extFile, true); } else {// exFw = new FileOutputStream(extFile); } exSw = new OutputStreamWriter(exFw, encoding); if (msg instanceof String) { exSw.write((String) msg + NEXT_LINE); hasLog = true; } else if (msg instanceof BizLogContent) { String content = ((BizLogContent) msg).toString(); exSw.write(content + NEXT_LINE); hasLog = true; } exSw.flush(); exFw.flush(); exSw.close(); exFw.close(); } catch (IOException ex) { ex.printStackTrace(); } } } return hasLog; } private long getCurrDate() { //? Calendar cal2 = Calendar.getInstance(); cal2.set(Calendar.HOUR_OF_DAY, 0); cal2.set(Calendar.MINUTE, 0); cal2.set(Calendar.SECOND, 0); cal2.set(Calendar.MILLISECOND, 0); Date currStatDate = cal2.getTime(); //currDate currDate = currStatDate.getTime(); if (currDate > lastDayTime) {//??? first_on_day = true; } return currDate; } /** * ?yyyyMMdd * @return long */ private String getLastDate() { Calendar cal2 = Calendar.getInstance(); cal2.set(Calendar.HOUR_OF_DAY, 0); cal2.set(Calendar.MINUTE, 0); cal2.set(Calendar.SECOND, 0); cal2.set(Calendar.MILLISECOND, 0); cal2.add(Calendar.DAY_OF_MONTH, -1); String yesterday = DateFormatUtils.format(new Date(cal2.getTimeInMillis()), "yyyyMMdd"); return yesterday; } private long getDateOfFile(long fileTime) { // Calendar cal2 = Calendar.getInstance(); cal2.setTimeInMillis(fileTime); cal2.set(Calendar.HOUR_OF_DAY, 0); cal2.set(Calendar.MINUTE, 0); cal2.set(Calendar.SECOND, 0); cal2.set(Calendar.MILLISECOND, 0); return cal2.getTimeInMillis(); } /** * ?? * @param event LoggingEvent */ public void subAppend(LoggingEvent event) { long n = System.currentTimeMillis(); //boolean log2last=append2LastHour(event.getMessage()); //if ((n >= nextCheck)&&!log2last) LogLog.debug("n:" + n + "nextCheck:" + nextCheck); if (n >= nextCheck) {//?,? LogLog.debug("Now rollOverForTime"); now.setTime(n); //??? lastDayTime = currDate; //currDate0 getCurrDate(); nextCheck = rc.getNextCheckMillis(now); try { rollOverForTime(); } catch (IOException ioe) { LogLog.error("rollOver() failed.", ioe); } } //time roll first if ((fileName != null) && ((CountingQuietWriter) qw).getCount() >= maxFileSize) { rollOverForSize(); } if (!log2extraFile(event)) {//? if (event != null) { super.directSubAppend(event); } } } /** * ? * @param pFileName String * @param typeName String * @param pattern String??? * @return String yyyyMMdd?? */ private String getUnidateFromFileName(String pFileName, String typeName, String pattern) { //ullbiz.log.yyyy-MM-dd.bak StringBuffer strBuf = new StringBuffer(); for (int i = 0; i < pattern.length(); i++) { char ch = pattern.charAt(i); if (ch != '\'') {//'?? strBuf.append(ch); } } String templateFileName = typeName + strBuf.toString(); //int indYear=templateFileName.indexOf("yyyy"); int indYear = templateFileName.lastIndexOf("yyyy"); String year = pFileName.substring(indYear, indYear + 4); // int indMonth=templateFileName.indexOf("MM"); int indMonth = templateFileName.lastIndexOf("MM"); String month = pFileName.substring(indMonth, indMonth + 2); // int indDay=templateFileName.indexOf("dd"); int indDay = templateFileName.lastIndexOf("dd"); String day = pFileName.substring(indDay, indDay + 2); return year + month + day; } /** * ??? * @param fileDate * @return boolean */ private boolean isCheckReportPublished(long fileDate) { String statPath = LogHelper.getLogRootPath() + FILE_SEP + "log" + FILE_SEP + CHECKFILE_PATH + FILE_SEP; int index = fileName.lastIndexOf(FILE_SEP); // String realName = fileName.substring(index + 1); SimpleDateFormat simpleDateFormat = new SimpleDateFormat(stat_datepattern); //006-06-14.999999 String statDate = simpleDateFormat.format(new Date(getDateOfFile(fileDate))); String statFileName = realName + statDate; //? File statBakFile = new File(statPath, statFileName + PUBLISHED_CHECKFILE); if (statBakFile.exists()) { // return true; } return false; } /** * * @param logFileName String the roll file name * like biz.log.2005-03-08-14.1.bak * @param seq String the roll file 's sequence No */ private void logStastics(String logFileName, String seq) { //get the start index of .bak int rIndex = logFileName.lastIndexOf(LogConstants.LOG_BACKUP_SUFFIX); if (seq != null) {//the seq is the sequence number when log roll over size rIndex = rIndex - seq.length() - 1; } //get the end index of raw file int lIndex = fileName.length(); String datePart = logFileName.substring(lIndex, rIndex); try { //the date of the biz log file output Date rawDate = sdf.parse(datePart); Calendar cal = Calendar.getInstance(); cal.setTime(rawDate); cal.set(Calendar.HOUR_OF_DAY, 0); cal.set(Calendar.MINUTE, 0); //, Date logDate = cal.getTime(); //String statPattern="'.'yyyy-MM-dd'.999999'"; SimpleDateFormat simpleDateFormat = new SimpleDateFormat(stat_datepattern); //get the string of stat log date String statDate = simpleDateFormat.format(logDate); int index = fileName.lastIndexOf(FILE_SEP); // String realName = fileName.substring(index + 1); //statlog String statPath = LogHelper.getLogRootPath() + FILE_SEP + "log" + FILE_SEP + CHECKFILE_PATH + FILE_SEP; File path = new File(statPath); if (!path.exists()) { path.mkdir(); } String statFileName = realName + statDate; statFile = new File(path, statFileName); /*if (isCheckReportPublished()) {//logCheck.sh,? return; }*/ FileWriter fw = null; if (statFile.exists()) { fw = new FileWriter(statFile, true); } else { fw = new FileWriter(statFile); } //add timestamp---will removed at production /*SimpleDateFormat sdfTemp=new SimpleDateFormat("yyyyMMdd HH:mm:ss-SSS"); Date now=new Date(); fw.write(sdfTemp.format(now)); */ //add timestamp---will removed at production int lastFSIndex = logFileName.lastIndexOf(FILE_SEP); fw.write(logFileName.substring(lastFSIndex + 1) + NEXT_LINE); fw.flush(); fw.close(); } catch (Exception ex) { ex.printStackTrace(); } } /** * reload this method to generate the stastics * @throws IOException */ public void rollOverForTime() throws IOException { //? lastLogFilePrefix = null; /* Compute filename, but only if datePattern is specified */ LogLog.debug("Let's rock and roll"); if (datePattern == null) { LogLog.debug("datePattern==null"); errorHandler.error("Missing DatePattern option in rollOver()."); return; } String datedFilename = fileName + sdf.format(now); LogLog.debug("datedFilename:" + datedFilename); // It is too early to roll over because we are still within the // bounds of the current interval. Rollover will occur once the // next interval is reached. if (scheduledFilename.equals(datedFilename)) { LogLog.debug("scheduledFilename.equals(datedFilename)"); return; } // close current file, and rename it to datedFilename this.closeFile(); long currFileDate = currFile.lastModified(); LogLog.debug("isCheckReportPublished(currFileDate):" + isCheckReportPublished(currFileDate)); if (isCheckReportPublished(currFileDate)) {// currFile.delete(); for (int i = 1; i <= maxBackupIndex; i++) {//currFile?xx.log.1,xxxlog.2 String before = fileName + "." + i; File files = new File(before); if (files.exists()) { files.delete(); } } setFile(fileName, false, this.bufferedIO, this.bufferSize); return; } File target = new File(scheduledFilename + LogConstants.LOG_BACKUP_SUFFIX); if (target.exists()) { target.delete(); } File file = new File(fileName); for (int i = 1; i <= maxBackupIndex; i++) { //roll for all size-backup files String before = fileName + "." + i; File files = new File(before); String after = scheduledFilename + "." + i + LogConstants.LOG_BACKUP_SUFFIX; if (files.exists()) { //only backup existed one File targets = new File(after); if (targets.exists()) { targets.delete(); } boolean result = files.renameTo(targets); if (result) { //?i? lastLogFileSize = i; logStastics(after, String.valueOf(i)); LogLog.debug(before + " -> " + after); } else { LogLog.error("Failed to rename [" + before + "] to [" + after + "]."); } } else { break; } } boolean result = file.renameTo(target); LogLog.debug("file.renameTo(target) result:" + result); if (result) { // logStastics(target.getAbsolutePath(), null); lastLogFilePrefix = scheduledFilename; LogLog.debug(fileName + " -> " + scheduledFilename); } else { LogLog.error("Failed to rename [" + fileName + "] to [" + scheduledFilename + "]."); } 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; LogLog.debug("scheduledFilename after roll:" + scheduledFilename); } public void setTs_offset(int ts_offset) { this.ts_offset = ts_offset; } public void setStat_datepattern(String stat_datepattern) { this.stat_datepattern = stat_datepattern; } /** * @return Returns the instantCreatChkfile. */ public String getInstantCreatChkfile() { return instantCreatChkfile; } /** * @param instantCreatChkfile The instantCreatChkfile to set. */ public void setInstantCreatChkfile(String instantCreatChkfile) { this.instantCreatChkfile = instantCreatChkfile; } // ??pps_commonlog?ileCopy public void fileCopy(final File source, final File target) throws IOException { FileInputStream extInputSteam = new FileInputStream(source); FileOutputStream targetOutputSteam = new FileOutputStream(target); IOUtils.copy(extInputSteam, targetOutputSteam); } }