ã¯ããã«
ãApache Logging Services Projectãæä¾ããLog4jã¯ããã¡ã¤ã«ãµã¤ãºã«ãã£ã¦ãã°ãã¡ã¤ã«ã®ãã¼ãã¼ã·ã§ã³ãè¡ãRollingFileAppender
ãæ¥ä»ã§ãã¼ãã¼ã·ã§ã³ãè¡ãDailyRollingFileAppender
ãæä¾ãã¦ãã¾ãã
ããããããã¡ã¤ã«ãµã¤ãºã¨æ¥ä»ã®ä¸¡æ¹ã§ãã¼ãã¼ãããAppenderã¯æä¾ããã¦ããªãããã両æ¹ã®æ©è½ãåæã«å©ç¨ãããã¨ã¯ã§ãã¾ãããã¾ããDailyRollingFileAppender
ãå©ç¨ããå ´åã¯ãããã¯ã¢ãããã°ãã¡ã¤ã«æ°ãè¨å®ã§ããªããããDisk Fullã¸ã®å¯¾çãæ¤è¨ããå¿
è¦ãããã¾ãã
ãæ¬ç¨¿ã§ã¯RollingFileAppender
ã¨DailyRollingFileAppender
ã®æ©è½ãçµã¿åãããAppenderãä½æããæ¹æ³ãç´¹ä»ãããã®å©ç¨æ¹æ³ã«ã¤ãã¦ç¤ºãã¾ãã
対象èªè
ãJavaããã°ã©ãã³ã°ã®çµé¨ããããLog4jã使ã£ããã¨ãããæ¹ã対象ã¨ãã¾ããLog4jã®åºæ¬ã«ã¤ãã¦ã¯ããLog4Jã³ãã¯ã·ã§ã³ãã¼ãªã³ã°å¯¾å¿JDBCAppenderã§ããã©ã¼ãã³ã¹ãåä¸ãããããçè ã管çããLog4j Q&Aãåç §ãã ããã
å¿ è¦ãªç°å¢
ããªããçè ã¯ä»¥ä¸ã®ç°å¢ã§åä½ç¢ºèªããã¦ãã¾ãã
- JDK 5.0 Update 4
- Log4j 1.2.13
RollingFileAppenderã¨DailyRollingFileAppender
ãLog4jã¯ãã¾ãã¾ãªAppenderãç¨æãã¦ãã¾ãããæä½ãã°ãã¨ã©ã¼ãã°ã®è¨é²ã®ããã«ã以ä¸ã®Appenderãåºã使ããã¦ããã¨æãã¾ãã
RollingFileAppender
DailyRollingFileAppender
RollingFileAppender
ããã¡ã¤ã«ãµã¤ãºã§ãã°ãã¡ã¤ã«ã®ãã¼ãã¼ã·ã§ã³ãè¡ãAppenderã§ãããã°ãã¡ã¤ã«ã®ãµã¤ãºãæ大ãã¡ã¤ã«ãµã¤ãºãè¶ ããã¨ãã«ããã°ãã¡ã¤ã«ã®ãã¼ãã¼ã·ã§ã³ãçºçãã¾ããããã¯ã¢ãããã°ãã¡ã¤ã«æ°ãæ大ããã¯ã¢ãããã°ãã¡ã¤ã«æ°ãè¶ ãããæãå¤ããã°ãã¡ã¤ã«ãåé¤ããã¾ãã
ããããã£
ãorg.apache.log4j.RollingFileAppender
ã§ã¯ä»¥ä¸ã®ããããã£ãç¨æããã¦ãã¾ãã
ããããã£å | è¨å®ä¾ | 説æ |
MaxFileSize | 10MB | æ大ãã¡ã¤ã«ãµã¤ãºããã®ãã¡ã¤ã«ãµã¤ãºãè¶ ããã¨ãã°ãã¡ã¤ã«ã®ãã¼ãã¼ã·ã§ã³ãçºçãã |
MaxBackupIndex | 10 | æ大ããã¯ã¢ãããã°ãã¡ã¤ã«æ°ãããã¯ã¢ãããã°ãã¡ã¤ã«æ°ããã®å¤ãè¶ ããã¨ãæãå¤ããã°ãã¡ã¤ã«ãåé¤ããã |
DailyRollingFileAppender
ãæ¥ä»ã§ãã°ãã¡ã¤ã«ã®ãã¼ãã¼ã·ã§ã³ãè¡ãAppenderã§ããDatePattern
ã§ç¤ºãããæ¥ä»ãå¤ãã£ãã¨ãã«ããã°ãã¡ã¤ã«ã®ãã¼ãã¼ã·ã§ã³ãçºçãã¾ãã
ããããã£
ãorg.apache.log4j.DailyRollingFileAppender
ã§ã¯ã以ä¸ã®ããããã£ãç¨æããã¦ãã¾ãã
ããããã£å | è¨å®ä¾ | 説æ |
DatePattern | '.'yyyy-MM-dd | ãã°ãã¡ã¤ã«ã®ãã¼ãªã³ã°ã®ã¹ã±ã¸ã¥ã¼ã«ãæå®ãã¾ããæãé±ãæ¥ãæãåãªã©ã§ãã¼ãªã³ã°ããããã¨ãå¯è½ã§ãã詳細ãªè¨å®æ¹æ³ã¯Log4j API Specificationã®DailyRollingFileAppender ã®é
ãåç
§ãã ããã |
両Appenderã®é¢ä¿ã¨æ°è¦Appenderã®ä½ç½®ä»ã
ãã¯ã©ã¹åããã¯RollingFileAppender
ã¨DailyRollingFileAppender
ã«è¦ªåé¢ä¿ãããããã«æãã¾ãããå®éã¯ããã§ã¯ããã¾ããããã®ãããDailyRollingFileAppender
ã§RollingFileAppender
ã®ããããã£ã使ããã¨ã¯ã§ãã¾ãããLog4jã§ã¯ããµã¤ãºã¨æ¥ä»ã§ãã¼ãã¼ãããAppenderãã¯æä¾ããã¦ããªãã®ã§ãã
ãããã§ã両è
ã®æ©è½ãä½µãæã¤CompositeRollingFileAppender
ã¯ã©ã¹ãæ°è¦ã«ä½æãã¾ããæ¢åã®Appenderã¨åæ§ã«CompositeRollingFileAppender
ãFileAppender
ãç¶æ¿ãã¾ãã以ä¸ã«UMLå³ã示ãã¾ãã
CompositeRollingFileAppenderã®å®è£
ããã±ã¼ã¸
ãorg.apache.log4j
ã¸ã®ããã±ã¼ã¸ã¢ã¯ã»ã¹ãå¿
è¦ã«ãªããããæ¬ã¯ã©ã¹ã®ããã±ã¼ã¸ãorg.apache.log4j
ã¨ãã¾ãã
ãã¼ãã¼ã·ã§ã³çºçã®æ¤åº
ãLog4jã§ã¯ãã°ã¤ãã³ããçºçããã¨ãorg.apache.log4j.WriterAppender#subAppend(LoggingEvent)
ã¡ã½ãããå¼ã³åºããããã°åºåãè¡ããã¾ããRollingFileAppender
ãDailyRollingFileAppender
ã§ã¯ããã®ã¡ã½ããå
ã§ãã¼ãã¼ã·ã§ã³ã®æç¡ãæ¤åºãã¦ãã¾ããããã§ãCompositeRollingFileAppender
ã®subAppend
ã¡ã½ããã¯ã両è
ã®ãã¼ãã¼ã·ã§ã³ã®æ¤åºãçµã¿åãããå½¢ã§å®è£
ãã¾ãã
protected void subAppend(LoggingEvent event) { // æ¥ä»ãã¼ã¹ã®ãã¼ãã¼ã·ã§ã³ãçºçãããã©ãããã§ãã¯ãã // çºçããå ´åã¯ãã¼ãã¼ã·ã§ã³ãè¡ãã long n = System.currentTimeMillis(); if (n >= nextCheck) { now.setTime(n); nextCheck = rc.getNextCheckMillis(now); try { rollOverTime(); } catch (IOException ioe) { LogLog.error("rollOver() failed.", ioe); } } // ãµã¤ãºãã¼ã¹ã®ãã¼ãã¼ã·ã§ã³ãçºçãããã©ãããã§ãã¯ãã // çºçããå ´åã¯ãã¼ãã¼ã·ã§ã³ãè¡ã if ((fileName != null) && ((CountingQuietWriter) qw).getCount() >= maxFileSize) { rollOverSize(); } super.subAppend(event); }
ãµã¤ãºãã¼ã¹ã®ãã¼ãã¼ã·ã§ã³
ããµã¤ãºãã¼ã¹ã®ãã¼ãã¼ã·ã§ã³ã§ã¯ãã¾ãããã¯ã¢ãããã°ãã¡ã¤ã«æ°ãMaxBackupIndex
以ä¸ã§ããããã§ãã¯ããããã§ããã°æãå¤ããã°ãã¡ã¤ã«ãåé¤ãã¾ãã
ãRollingFileAppender
ã§ã¯ãã¡ã¤ã«ãµã¤ãºã«ãããã¼ãã¼ã·ã§ã³ã®ã¿è¡ãããããããã°ãã¡ã¤ã«ã®ããã¯ã¢ããã¤ã³ããã¯ã¹ããæãå¤ããã°ãã¡ã¤ã«ãç¹å®ã§ãã¾ãããCompositeRollingFileAppender
ã§ã¯ãã¼ãã¼ã·ã§ã³ã®æ¹æ³ã2種é¡ï¼ãµã¤ãºãã¼ã¹ã¨æ¥ä»ãã¼ã¹ï¼ãããããå¥ã®å¤å®æ¹æ³ãå¿
è¦ã«ãªãã¾ããæ¬ç¨¿ã®å®è£
ã§ã¯ãã°ãã¡ã¤ã«ã®ã¿ã¤ã ã¹ã¿ã³ãããæãå¤ããã°ãã¡ã¤ã«ãå¤æãã¦ãã¾ãã
ã次ã«ãããã¯ã¢ãããã°ãã¡ã¤ã«ã®å称ãå¤æ´ãã¾ããå ·ä½çã«ã¯ãã¡ã¤ã«åã«ä»ããããã¤ã³ããã¯ã¹ãå¢ããããã«ãã¾ãããã®æãæ¢ã«æ¥ä»ã§ãã¼ãã¼ãããããã°ãã¡ã¤ã«ã¯ãã¼ãã¼ã·ã§ã³ã®å¯¾è±¡ã«ãã¾ããã
ã以ä¸ã®ã½ã¼ã¹ã³ã¼ãã¯ããµã¤ãºãã¼ã¹ã®ãã¼ãã¼ã·ã§ã³ãè¡ãå¦çã®æç²ã§ãã詳細ã¯ãµã³ãã«ãã¡ã¤ã«ã«å«ã¾ããã½ã¼ã¹ã³ã¼ããåç §ä¸ããã
public void rollOverSize() { if (maxBackupIndex > 0) { rotateLogFilesBy(BY_SIZE); } try { this.setFile(fileName, false, bufferedIO, bufferSize); } catch (IOException e) { LogLog.error("setFile(" + fileName + ", false) call failed.", e); } } private void rotateLogFilesBy(int mode) { // æ¥ä»ãä»ãããã¦ããªããã°ãã¡ã¤ã«ãæ¤ç´¢ãã List notDailyLogs = new ArrayList(); File[] allLogs = getAllLogFiles(); for (int i = 0; i < allLogs.length; i++) { if (!isDailyLotatedLog(allLogs[i])) { notDailyLogs.add(allLogs[i]); } } int notDailyLogNum = notDailyLogs.size(); // ã¢ã¼ãã«å¾ã£ã¦ãã¼ãã¼ã·ã§ã³ãè¡ã if (mode == BY_SIZE) { File file = null; File target = null; // æãå¤ããã°ãã¡ã¤ã«ãåé¤ãã if (getBackupLogFileNum() >= maxBackupIndex) { deleteOldestFile(); } // Map {(maxBackupIndex - 1), ..., 2, 1} to // {maxBackupIndex, ..., 3, 2} for (int i = notDailyLogNum - 1; i >= 1; i--) { file = new File(fileName + "." + i); if (file.exists()) { target = new File(fileName + '.' + (i + 1)); LogLog.debug("Renaming file " + file + " to " + target); file.renameTo(target); } } // Rename fileName to fileName.1 target = new File(fileName + "." + 1); this.closeFile(); // keep windows happy. file = new File(fileName); LogLog.debug("Renaming file " + file + " to " + target); file.renameTo(target); } else if (mode == BY_DATE) { ã»ã»ã» } }
æ¥ä»ãã¼ã¹ã®ãã¼ãã¼ã·ã§ã³
ãæ¥ä»ãã¼ã¹ã®ãã¼ãã¼ã·ã§ã³ã§ããã¾ãããã¯ã¢ãããã°ãã¡ã¤ã«æ°ãMaxBackupIndex
以ä¸ã§ããããã§ãã¯ããããã§ããã°æãå¤ããã°ãã¡ã¤ã«ãåé¤ãã¾ãã
ã次ã«ãããã¯ã¢ãããã°ãã¡ã¤ã«åã«æ¥ä»ãä»ä¸ãã¾ããæ¥ä»ãä»ããããããã¯ã¢ãããã°ãã¡ã¤ã«ã¯ä»¥å¾ãªãã¼ã ããããã¨ã¯ããã¾ããã以ä¸ã®ã½ã¼ã¹ã³ã¼ãã¯ãæ¥ä»ãã¼ã¹ã®ãã¼ãã¼ã·ã§ã³ãè¡ãå¦çã®æç²ã§ãã
public void rollOverTime() throws IOException { /* Compute filename, but only if datePattern is specified */ if (datePattern == null) { errorHandler.error("Missing DatePattern option in rollOver()."); return; } String datedFilename = fileName + sdf.format(now); // 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)) { return; } rotateLogFilesBy(BY_DATE); 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; } private void rotateLogFilesBy(int mode) { // æ¥ä»ãä»ãããã¦ããªããã°ãã¡ã¤ã«ãæ¤ç´¢ãã List notDailyLogs = new ArrayList(); File[] allLogs = getAllLogFiles(); for (int i = 0; i < allLogs.length; i++) { if (!isDailyLotatedLog(allLogs[i])) { notDailyLogs.add(allLogs[i]); } } int notDailyLogNum = notDailyLogs.size(); // ã¢ã¼ãã«å¾ã£ã¦ãã¼ãã¼ã·ã§ã³ãè¡ã if (mode == BY_SIZE) { ã»ã»ã» } else if (mode == BY_DATE) { // close current file, and rename it to datedFilename this.closeFile(); // æãå¤ããã°ãã¡ã¤ã«ãåé¤ãã if (getBackupLogFileNum() >= maxBackupIndex) { deleteOldestFile(); } // ãã°ãã¡ã¤ã«åã«æ¥ä»ãä»ä¸ãã for (int i = 1; i <= notDailyLogNum - 1; i++) { String from = fileName + '.' + i; String to = scheduledFilename + '.' + i; renameFile(from, to); } renameFile(fileName, scheduledFilename); } }
RollingFileAppender
ã¨DailyRollingFileAppender
ãçµã¿åãããã¨ããæ§è³ªä¸ãããããã®ã¯ã©ã¹ã®ã½ã¼ã¹ã³ã¼ãããã¼ã¹ã«ãã¦ãã¾ããä¸è¨ã®ã½ã¼ã¹ã³ã¼ãã«ããè±èªã®ã³ã¡ã³ãã¯å
ã®ã½ã¼ã¹ã³ã¼ãã«ä»ãããã¦ãããã®ã§ãããã¾ãLog4jã®ãã¼ã¸ã§ã³ã«ãã£ã¦
RollingFileAppender
ã¨DailyRollingFileAppender
ã®ã½ã¼ã¹ã³ã¼ããç°ãªããããããããçµã¿åãããä¸è¨å®è£
ããã¼ã¹ã¨ãªãLog4jã®ãã¼ã¸ã§ã³ã«ãã£ã¦ç°ãªãã¾ããæ¬ç¨¿ã§ç´¹ä»ããã³ã¼ãã¯Log4j 1.2.13ããã¼ã¹ã«ãã¦ãã¾ããããããã£
ãorg.apache.log4j.CompositeRollingFileAppender
ã§ç¨æããããããã£ã¯æ¬¡ã®ã¨ããã§ãã
ããããã£å | è¨å®ä¾ | ããã©ã«ãå¤ | 説æ |
MaxFileSize | 10MB | java.lang.Long#MAX_VALUE | æ大ãã¡ã¤ã«ãµã¤ãºãæ¥ä»ã§ã®ã¿ãã¼ãã¼ã·ã§ã³ããããå ´åã¯ããã®ãªãã·ã§ã³ãçç¥ãã¦ãã ãã |
MaxBackupIndex | 10 | 1 | æ大ããã¯ã¢ãããã°ãã¡ã¤ã«æ° |
DatePattern | '.'yyyy-MM-dd-HH | '.'yyyy-MM-dd | ãã°ãã¡ã¤ã«ã®ãã¼ãã¼ã·ã§ã³ã®ã¹ã±ã¸ã¥ã¼ã« |
ãããããã®ããããã£ã®è©³ç´°ã¯ãRollingFileAppender
ãDailyRollingFileAppender
ã¨åãã§ãã
è¨å®ãã¡ã¤ã«ä¾
ã以ä¸ã®ãµã³ãã«ã¯ãæ大ãã¡ã¤ã«ãµã¤ãº10MBãæ大ããã¯ã¢ãããã°ãã¡ã¤ã«æ°10ã§ãæ¥ãã¨ã«ãã¼ãã¼ã·ã§ã³ãè¡ããlog4j.xmlãã®è¨å®ä¾ã§ãã
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="FILE" class="org.apache.log4j.CompositeRollingFileAppender"> <param name="File" value="log/sample.log" /> <param name="MaxFileSize" value="10MB" /> <param name="MaxBackupIndex" value="10" /> <param name="datePattern" value="'.'yyyy-MM-dd" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d %t %-5p %c{2} - %m%n"/> </layout> </appender> <logger name="jp.co.okisoft.esc.log4j"> <level value="debug" /> <appender-ref ref="FILE" /> </logger> </log4j:configuration>
ããã¡ã¤ã«ãµã¤ãºã¯ç¡è¦ãã¦ãã¨ã«ããæ¥ä»ã ãã§ãã¼ãã¼ã·ã§ã³ããããå ´åã¯ãä¸è¨ã®è¨å®ã«ããã¦MaxFileSize
ããããã£ãçç¥ãã¾ããDailyRollingFileAppender
ã§ã¯æ大ããã¯ã¢ãããã°ãã¡ã¤ã«æ°ãæå®ãããã¨ãã§ãã¾ããããCompositeRollingFileAppender
ãå©ç¨ãããã¨ã§ãããã¯ã¢ããæ°å¶éä»ãã®æ¥ä»ãã¼ã¹ãã¼ãã¼ã·ã§ã³ãå®ç¾ã§ãã¾ãã
ãµã³ãã«ã¢ããªã±ã¼ã·ã§ã³
ãä»åä½æããCompositeRollingFileAppender
ã®åä½ç¢ºèªã®ããã«ç¨ãããµã³ãã«ã¢ããªã±ã¼ã·ã§ã³ã以ä¸ã«ç¤ºãã¾ããwhile
ã«ã¼ãå
ã§INFO
ã¬ãã«ã®ãã°ãåºåãç¶ããã ãã®ã·ã³ãã«ãªã³ã¼ãã§ãã
package jp.co.okisoft.esc.log4j; import org.apache.log4j.Logger; public class RollingSample { private static Logger logger = Logger.getLogger(RollingSample.class); public static void main(String[] args) throws Exception { while (true) { Thread.sleep(100); logger.info("test"); } } }
-Dlog4j.debug=true