保留日志文件的 2 个先前版本



我的Java应用程序CB从数据库中获取数据,比如"案例1"。每次 CB 启动时都会创建一个日志文件:

Logger logger = Logger.getLogger("CBLog");  
fh = new FileHandler(CBDataPath + "\CB.log";
logger.addHandler(fh);
SimpleFormatter formatter = new SimpleFormatter();  
fh.setFormatter(formatter);  
logger.info("CB started");  

我想为特定情况保留 2 个以前版本的日志文件。如何才能最容易地做到这一点?

这是我的一个想法。我可以在案例数据库中维护一个表示运行号的整数。每个连续的运行都会命名日志文件CB_CaseA_n.log其中 n 是上一个运行编号加 1。每次在案例A上运行CB时,都会搜索CasaA目录以查找所有CB_CaseA_?。日志文件,仅保留 3 个最新文件。即,在运行时,CB_CaseA_7中的 10 个将被删除。看起来不是很优雅。

有没有更好的方法?

来自 java.util.logging.FileHandler:

count 指定要循环浏览的输出文件数(默认为 1)。

"%g"用于区分轮换日志的世代号

创建具有计数和生成模式的文件处理程序:

new FileHandler("CBDataPath + "\CB%g.log, Integer.MAX_VALUE, 2, false);

这是我的解决方案。解释:

updateLogHistory() maintains historical log files in the MyConcourses directory. It is called in the ConcoursGUI() constructor.
The intuition is a "stack" of log files with the current log, i.e., ConcoursBuilderLog_0.log,  on top. To make room for a new log file
 for the ConcoursBuilder session, any existing log files have to be "pushed down." However, the stack is allowed to hold only a prescribed
number, size, elements so if there are already size files in the stack the bottom one gets deleted, or rather, overwritten. When the function
 finishes the top TWO will be identical, so the top one can be overwritten in the caller.
It's important to note that "stack" is a metaphor here; there isn't a stack in the sense of a programed data structure. There can be only 
size log files in the MyConcourses folder. What actually happens in a so-called push is the CONTENTS of ConcoursBuilderLog_i.log 

复制到 ConcoursBuilderLog_i+1.log 中,ConcoursBuilderLog_i.log保持不变。

// The algorithm below requires an initial ConcoursBuilder_0.log. Consequently, prior to calling updateLogHistory() 
// the directory is first checked and an empty one is created if absent. Typically, this happens only in the first 
// run after INSTALLATION of ConcoursBuilder. However, it must be checked because the user might accidently deleted it.
//
// Work from the bottom up to push all existing log files down, leaving the contents of the current ConcoursBuilderLog_0 in
// both ConcoursBuilderLog_0 and 1. the subsequent log file will overwrite both ConcoursBuilderLog_0.
//

Logger logger = Logger.getLogger("ConcoursBuilderLog"); 
File logFile = null;
try {
    String strFileFullPath = concoursBuilderDataPath + "\ConcoursBuilderLog_" + 0 + ".log";
    logFile = new File(strFileFullPath);
    if(!logFile.exists()){
        try {
            logFile.createNewFile();
        } catch (IOException ex) {
            Logger.getLogger(ConcoursGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {            
            Files.write(Paths.get(logFile.getPath()), "Empty log file".getBytes(), StandardOpenOption.WRITE);
        } catch (IOException ex) {
            Logger.getLogger(ConcoursGUI.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    // Maintain a "stack" of historical ConcoursBuilder log files.
    updateLogHistory(NUM_SAVED_LOGS,  logFile);  
} catch (SecurityException e) {  
    e.printStackTrace();  
} 
fhLogger = null;
try {
    fhLogger = new FileHandler(logFile.toString(), false);
} catch (IOException ex) {
    Logger.getLogger(ConcoursGUI.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
    Logger.getLogger(ConcoursGUI.class.getName()).log(Level.SEVERE, null, ex);
}
logger.addHandler(fhLogger);
logger.setLevel(Level.ALL);
SimpleFormatter formatter = new SimpleFormatter();
fhLogger.setFormatter(formatter);
// the updater
private static  void updateLogHistory(int size, File logFile0){
        String strTemp = logFile0.toString(); 
    String strPrefix = strTemp.substring(0, strTemp.indexOf("_")+1);
    for(int i =  size-1; i >=0; i--){
        String strFileFullPath = strPrefix + i + ".log";
        File logFile_i  = new File(strFileFullPath);
        if(logFile_i.exists() && !logFile_i.isDirectory()){
            Path path= Paths.get(strFileFullPath); // this is the the absolute path to the i file as a Path                
            if( i != size-1){
                // not at the end so there is a valid file name i+1.
                // Note that the file selected by iNext has already been pushed into iNext+1, or is the last. Either way,
                // it can properly be overwritten.
                int iPlus1 = i + 1;
                String strFileFullPathIPlus1 = strPrefix + iPlus1 + ".log";
                Path pathIPlus1 = Paths.get(strFileFullPathIPlus1); //  absolute path to the file as a Path                
                try {
                    Files.copy(path, pathIPlus1,   REPLACE_EXISTING);
                } catch (IOException ex) {
                    okDialog("IOException while updating log history in updateLogHistory()");
                    Logger.getLogger(ConcoursGUI.class.getName()).log(Level.SEVERE, null, ex);
                }
                continue; // (unnecessary) branch back to for() 
            } else{
                // Getting here means stack is full. IOW, the reference file the is last log file to be kept so we no longer need it's contents.
                // No action required since it will simply be overwritten in the next pass.
                //  things in the next pass.;
            }
        } 
    }
}     

最新更新