com.common.log.newproxy.BizStaticFileAppender.java Source code

Java tutorial

Introduction

Here is the source code for com.common.log.newproxy.BizStaticFileAppender.java

Source

/*
 * @(#)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);
    }

}