在進行代碼開發的過程中,日志是非常重要的。如果沒有日志是難以進行代碼調試和排錯的。
在開發過程中,我們可以選擇適合自己(團隊)的日志類來實現日志輸出,也可以自己編寫日志類來實現(也是有一定工作量的,不推薦),當然也可以選擇第三方的日志類來輔助,比如Log4j等。如果開發環境是JDK1.4以上的話,可以利用JDK自帶的日志類java.util.logging,也可以使用第三方的日志類;如果開發環境是JDK1.3,那就只能使用第三方的日志類,或者自行編寫日志類。
本文主要介紹如何在Log4j的基礎上,實現符合自己需要的日志類。
Log4j功能相當完善,一般都通過腳本配置將日志按照一定的規則輸出到文件或者console上,這種做法還是比較靈活的。
但現在需求比較特殊:
1、不想把日志輸出到一個確定的文件中,而希望是哪個類的日志就輸出到以這個類命名的文件中(通過腳本較難實現,如何您能實現的話,請一定要告訴我,呵呵);
2、每天的日志放在以日期命名的文件夾中,比如今天是2006-12-15,那么日志所在的文件夾是061215;
3、對于每天的日志采用循環日志,日志文件最大大小為2M,超過2M就清空重寫(這個功能Log4j本身是可以實現的);
4、日志輸出應包含時間(這個功能Log4j本身也是可以實現的)。
下面是自行編寫的LogBase類,文件名為:LogBase.java
------------------------------------------------------------------------------------------------
import?java.io.File;
import?java.text.SimpleDateFormat;
import?java.util.Date;
import?java.util.ResourceBundle;
import?org.apache.log4j.Level;
import?org.apache.log4j.Logger;
import?org.apache.log4j.PatternLayout;
import?org.apache.log4j.RollingFileAppender;
public?class?LogBase?{
????private?static?String?PROPERTIES_FILE?=?"logconf";
????private?static?String?LOG_PATH;
????private?static?String?DATE_LOG_FOLDER;
????private?static?String?LOG_LEVEL;
????private?static?String?PATTERN_LAYOUT;
????private?static?long?MAX_FILE_SIZE;
????private?LogBase()?{
????}
????public?static?Logger?getLogInstance(String?name)?{
????????Logger?logger?=?Logger.getLogger(name);
????????try?{
????????????String?pattern?=?getPatternLayout();
????????????RollingFileAppender?appender?=?new?RollingFileAppender(
????????????????????new?PatternLayout(pattern),?createClassLogFile(name)
????????????????????????????.getAbsolutePath());
????????????long?maxfilesize?=?getMaxFileSize();
????????????appender.setMaximumFileSize(maxfilesize);
????????????logger.addAppender(appender);
????????????String?level?=?getLogLevel();
????????????logger.setLevel((Level)?Level.toLevel(level));
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();
????????}
????????return?logger;
????}
????/*
?????*?在LOG_PATH下創建以當天日期為名字的文件夾
?????*/
????private?static?File?createDateLogFolder()?{
????????LOG_PATH?=?getLogPath();
????????if?(LOG_PATH?==?null)?{
????????????readLogConfigParams();
????????}
????????String?currentdate?=?getCurrentDate();
????????DATE_LOG_FOLDER?=?LOG_PATH?+?System.getProperty("file.separator")
????????????????+?currentdate;
????????File?logFolder?=?new?File(DATE_LOG_FOLDER);
????????try?{
????????????if?(!logFolder.exists())?{
????????????????logFolder.mkdirs();
????????????}
????????}?catch?(Exception?ex)?{
????????????ex.printStackTrace();
????????}
????????return?logFolder;
????}
????private?static?File?createClassLogFile(String?classname)?{
????????if?(DATE_LOG_FOLDER?==?null)?{
????????????createDateLogFolder();
????????}
????????String?classnameString?=?DATE_LOG_FOLDER
????????????????+?System.getProperty("file.separator")?+?classname?+?".txt";
????????File?logFile?=?new?File(classnameString);
????????try?{
????????????if?(!logFile.exists())?{
????????????????logFile.createNewFile();
????????????}
????????}?catch?(Exception?ex)?{
????????????ex.printStackTrace();
????????}
????????return?logFile;
????}
????private?static?void?readLogConfigParams()?{
????????ResourceBundle?rb?=?ResourceBundle.getBundle(PROPERTIES_FILE);
????????LOG_PATH?=?rb.getString("LOG_PATH");
????????LOG_LEVEL?=?rb.getString("LOG_LEVEL");
????????PATTERN_LAYOUT?=?rb.getString("PATTERN_LAYOUT");
????????MAX_FILE_SIZE?=?Long.parseLong(rb.getString("MAX_FILE_SIZE"));
????}
????private?static?String?getLogPath()?{
????????return?LOG_PATH;
????}
????private?static?String?getCurrentDate()?{
????????SimpleDateFormat?df?=?new?SimpleDateFormat("yyyyMMdd");
????????return?df.format(new?Date());
????}
????private?static?String?getLogLevel()?{
????????if?(LOG_LEVEL?==?null)?{
????????????readLogConfigParams();
????????}
????????return?LOG_LEVEL;
????}
????private?static?String?getPatternLayout()?{
????????if?(PATTERN_LAYOUT?==?null)?{
????????????readLogConfigParams();
????????}
????????return?PATTERN_LAYOUT;
????}
????private?static?long?getMaxFileSize()?{
????????if?(!(MAX_FILE_SIZE?>?0))?{
????????????readLogConfigParams();
????????}
????????return?MAX_FILE_SIZE;
????}
????public?static?void?main(String[]?args)?{
????????Logger?logger?=?LogBase.getLogInstance("LogBase");
????????logger.info("info");
????????logger.error("error");
????}
}
------------------------------------------------------------------------------------------------
LogBase類從配置文件logconf.properties文件中讀入日志存放路徑,logconf.properties文件內容很簡單,如下:
------------------------------------------------------------------------------------------------
LOG_PATH?=?D:\\logs
LOG_LEVEL?=?Level.DEBUG
PATTERN_LAYOUT?=?%-5p?%d{yyyy-MM-dd?HH:mm:ss}?%m%n
#MaxFileSize?is?set?to?about?10M
MAX_FILE_SIZE?=?10485760
------------------------------------------------------------------------------------------------
注意,LogBase類對外只提供一個public類型的方法getLogInstance(String?name),其余類都是private類型的。getLogInstance方法返回的類型是Logger,在getLogInstance方法中通過addAppender指向一個RollingFileAppender類型的文件,并設置日志文件的最大大小,然后通過setLevel方法設置日志級別。LOG_LEVEL,PATTERN_LAYOUT和MAX_FILE_SIZE都從配置文件中取得。
寫好這個類后,當需要使用LogBase類的時候,只要在你的源程序中加入:private?static?Logger?logger?=?LogBase.getLogInstance("XXXXXX");
XXXXXX代表你的類名,然后通過logger.info()之類的進行寫日志就可以了。
例如下面的測試
------------------------------------------------------------------------------------------------
import?org.apache.log4j.Logger;
public?class?LogBaseTest?{
????private?static?Logger?logger?=?LogBase.getLogInstance("LogBaseTest");
????public?static?void?main(String[]?args)?{
????????logger.info("LogBaseTest");
????}
}
------------------------------------------------------------------------------------------------
運行結束后,請到日志路徑下查找,是否出現以今天日期為名字的文件夾,并檢查該文件夾里面是否有一個LogBaseTest.txt文件,看看文件里的內容是什么樣子的,日志格式應該如下:
INFO??2006-12-15?13:33:36?LogBaseTest
以上的源程序和配置文件,請下載附件。
如果讀者對以上的內容有任何疑問,可以和我聯系,
jw_ws@163.com?版權所有,嚴禁轉載