log4j自定義級別並分類輸出到檔案
阿新 • • 發佈:2019-02-17
背景介紹:為service中的每個方法進行日誌記錄,記錄方法執行時間以及方法名、方法用途、返回結果等。記錄工具採用了log4j,並自定義級別,然後分類輸出到檔案中。
首先,自定義log4j級別:
public class ServiceLog { private static Logger logger = Logger.getLogger(ServiceLog.class); // 定義級別 private static class ServiceLogLevel extends Level { private static final long serialVersionUID = 1L; private ServiceLogLevel(int level, String name, int sysLogLevel) { super(level, name, sysLogLevel); } } // 20050級別數,"SERVICELOG":級別名稱 private static final Level SERVICE_LOG_LEVEL = new ServiceLogLevel(20050, "SERVICELOG", SyslogAppender.LOG_LOCAL0); // 使用時呼叫方法 public static void serviceLogger(Object pm_objLogInfo) { logger.log(SERVICE_LOG_LEVEL, pm_objLogInfo); } }
定義過濾器:
配置檔案log4j.xmlpublic class ServiceLogFilter extends Filter { boolean acceptOnMatch = false; private String levelMin; private String levelMax; public String getLevelMin() { return levelMin; } public void setLevelMin(String levelMin) { this.levelMin = levelMin; } public String getLevelMax() { return levelMax; } public void setLevelMax(String levelMax) { this.levelMax = levelMax; } public boolean isAcceptOnMatch() { return acceptOnMatch; } public void setAcceptOnMatch(boolean acceptOnMatch) { this.acceptOnMatch = acceptOnMatch; } @Override public int decide(LoggingEvent lgEvent) { int inputLevel = lgEvent.getLevel().toInt(); if (inputLevel >= getLevel(levelMin) && inputLevel <= getLevel(levelMax)) { return 0; } return -1; } private int getLevel(String level) { level = level.toUpperCase(); if (level.equals("SERVICELOG")) { return LevelType.SERVICELOG.getType(); } if (level.equals("OFF")) { return LevelType.OFF.getType(); } if (level.equals("FATAL")) { return LevelType.FATAL.getType(); } if (level.equals("ERROR")) { return LevelType.ERROR.getType(); } if (level.equals("INFO")) { return LevelType.INFO.getType(); } if (level.equals("WARN")) { return LevelType.WARN.getType(); } if (level.equals("DEBUG")) { return LevelType.DEBUG.getType(); } if (level.equals("ALL")) { return LevelType.ALL.getType(); } return LevelType.OFF.getType(); } private static enum LevelType { OFF(2147483647), FATAL(50000), ERROR(40000), WARN(30000), INFO(20000), DEBUG(10000), ALL(-2147483648), SERVICELOG(20050); int type; public int getType() { return type; } private LevelType(int type) { this.type = type; } } }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <!-- 輸出日誌到控制檯 ConsoleAppender --> <appender name="stdout" class="org.apache.log4j.ConsoleAppender"> <param name="Threshold" value="DEBUG"></param> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%p][%d{yyyy-MM-dd HH:mm:ss} -%t] %c:%L%n%m%n"></param> </layout> </appender> <!-- 記錄info資訊 每天一個檔案 --> <appender name="info" class="org.apache.log4j.DailyRollingFileAppender"> <param name="DatePattern" value="'_'yyyy-MM-dd'.log'"></param> <param name="File" value="D:/Servers/logs/log_info"></param> <param name="Encoding" value="UTF-8"></param> <param name="Append" value="true"></param> <param name="Threshold" value="INFO"></param> <filter class="com.cisdi.tool.serviceLog.ServiceLogFilter"> <param name="LevelMin" value="INFO" /> <param name="LevelMax" value="INFO" /> </filter> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%p][%d{yyyy-MM-dd HH:mm:ss} -%t] %c:%L%n%m%n"></param> </layout> </appender> <!-- 記錄錯誤資訊 檔案大小到達指定尺寸的時候產生一個新的檔案 --> <appender name="error" class="org.apache.log4j.DailyRollingFileAppender"> <param name="File" value="D:/Servers/logs/log_error"></param> <param name="DatePattern" value="'_'yyyy-MM-dd'.log'"/> <param name="Append" value="true"></param> <param name="Threshold" value="ERROR"></param> <param name="MaxFileSize" value="2000KB"></param> <param name="Encoding" value="UTF-8"></param> <filter class="com.cisdi.tool.serviceLog.ServiceLogFilter"> <param name="LevelMin" value="Error" /> <param name="LevelMax" value="Error" /> </filter> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%p][%d{yyyy-MM-dd HH:mm:ss} -%t] %c:%L%n%m%n"></param> </layout> </appender> <!-- 自定義日誌,用來記錄service操作記錄 --> <appender name="serviceLog" class="org.apache.log4j.DailyRollingFileAppender"> <param name="File" value="D:/Servers/logs/serviceLog"></param> <param name="DatePattern" value="'_'yyyy-MM-dd"></param> <param name="Encoding" value="UTF-8"></param> <param name="Append" value="true"></param> <param name="Threshold" value="SERVICELOG"></param> <filter class="com.cisdi.tool.serviceLog.ServiceLogFilter"> <param name="LevelMin" value="SERVICELOG" /> <param name="LevelMax" value="SERVICELOG" /> </filter> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss}] %m%n%n"></param> </layout> </appender> <!-- 定義全域性的日誌輸出級別,但是在輸出目的地的配置中配置的具體輸出級別優先順序高於全域性定義的優先順序。 如果在railyFile中定義<param name="Threshold" value="info"></param>,那麼將會把info以上級別的資訊輸出 --> <root> <priority value="info" /> <appender-ref ref="stdout" /> <appender-ref ref="info" /> <appender-ref ref="error" /> <appender-ref ref="serviceLog" /> </root> </log4j:configuration>
配置檔案的使用,需要在web.xml中配置使用(由於筆者使用時,採用的java web專案)
<!-- log4j 系統日誌-->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:config/log4j.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
關於自定義的日誌級別具體使用請參見另一篇文章《AOP實現方法的日誌記錄》