Log4j組件構成
Log4j由三個重要的組件構成:
1.日誌資訊的優先權(Logger)
2.日誌資訊的輸出目的地(Appender)
3.日誌資訊的輸出格式(Layout)。
概要:
日誌資訊的優先權從高到低有ERROR、WARN、INFO、DEBUG,分別用來指定這條日誌資訊的重要程度;
日誌資訊的輸出目的地指定了日誌將列印到控制台還是檔案中;
而輸出格式則控制了日誌資訊的顯示內容。
Log4j介紹
Log4j是Apache的一個開放原始碼項目,透過使用Log4j,我們可以控制日誌資訊傳送的目的地是控制台、檔案、GUI元件、甚至是套介面伺服器、NT的事件記錄器、UNIX Syslog守護程式等;我們也可以控制每一條日誌的輸出格式,透過定義每一個日誌資訊的級別,我們能夠更加細緻地控制日誌的生成過程。 log4j-- log for java (java的日誌) .
Log4j下載網址: http://logging.apache.org/log4j/2.x/download.html
Log4j設定檔的格式
Log4j支援兩種設定檔格式:
1. XML格式的文件
2. properties格式的文件
也可以完全不使用設定檔,而是在程式碼中配置Log4j環境。但是,使用設定檔將使您的應用程式更加靈活。
Log4j定義設定檔
1.配置根Logger
其語法為:
參數說明:
level是日誌記錄的優先權,分為OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或您定義的等級。
Off:最高等級,用於關閉所有日誌記錄
Fatal:指出每個嚴重的錯誤事件將會導致應用程式的退出。
Error:指出雖然發生錯誤事件,但仍不影響系統的繼續運作。
Warn:表明會出現潛在的錯誤情形
Info:一般用在粗粒度等級上,強調應用程式的運行全程
Debug:一般和在粗粒度等級上,強調應用程式的運行全程。
All:最低等級,用於開啟所有日誌記錄。
Log4j建議只使用四個級別,優先權從高到低分別是ERROR、WARN、INFO、DEBUG。透過在這裡定義的級別,您可以控製到應用程式中相應級別的日誌資訊的開關。
appenderName就是指日誌資訊輸出到哪個地方,可以同時指定多個輸出目的地。
2.配置日誌資訊輸出目的地Appender
其語法為:
log4j.appender.appenderName.option1 = value1
…
log4j.appender.appenderName.option = valueN
org.apache.log4j.ConsoleAppender(控制台)
org.apache.log4j.FileAppender(檔案)
org.apache.log4j.DailyRollingFileAppender(每天產生一個日誌檔案)
org.apache.log4j.RollingFileAppender(檔案大小到達指定尺寸的時候產生新檔案)
org.apache.log4j.WriterAppender(將日誌資訊以串流格式傳送到任意指定的地方)
3.配置日誌資訊的格式
語法為:
log4j.appender.appenderName.layout.option1 = value1 …
log4j.appender.appenderName.layout.option = valueN
org.apache.log4j.HTMLLayout(以HTML表格形式佈局),
org.apache.log4j.PatternLayout(可以靈活地指定佈局模式),
org.apache.log4j.SimpleLayout(包含日誌資訊的層級和資訊字串),
org.apache.log4j.TTCCLayout(包含日誌產生的時間、執行緒、類別等等資訊)
Log4J採用類似C語言中的printf函數的列印格式格式化日誌訊息,列印參數如下:
%m輸出代碼中指定的訊息
%p輸出優先權,即DEBUG,INFO,WARN,ERROR,FATAL
%r輸出自應用程式啟動到輸出該log資訊耗費的毫秒數
%c輸出所屬的類別目,通常就是所在類別的全名
%t輸出產生該日誌事件的執行緒名
%n輸出一個回車換行符,Windows平台為“rn”,Unix平台為“n”
%d輸出日誌時間點的日期或時間,預設格式為ISO8601,也可以在其後指定格式,例如:%d{yyyMMMddHH:mm:ss,SSS},輸出類似:2002年10月18日22:10 :28,921
%l輸出日誌事件的發生位置,包括類別目名、發生的線程,以及在程式碼中的行數。範例:Testlog4.main(TestLog4.java:10)
%x:輸出和目前執行緒相關聯的NDC(嵌套診斷環境),尤其用到像javaservlets這樣的多客戶多執行緒的應用中。
%%:輸出一個”%”字元%F:輸出日誌訊息產生時所在的檔案名稱
%L:輸出程式碼中的行號
%m:輸出代碼中指定的訊息,產生的日誌具體訊息
%n:輸出一個回車換行符,Windows平台為”/r/n”,Unix平台為”/n”輸出日誌訊息換行可以在%與模式字元之間加上修飾符來控制其最小寬度、最大寬度、和文字的對齊方式。
如:
1)%20c:指定輸出category的名稱,最小的寬度是20,如果category的名稱小於20的話,預設的情況下右對齊。
2)%-20c:指定輸出category的名稱,最小的寬度是20,如果category的名稱小於20的話,」-」號指定左對齊。
3)%.30c:指定輸出category的名稱,最大的寬度是30,如果category的名稱大於30的話,就會將左邊多出的字元截掉,但小於30的話也不會有空格。
4)%20.30c:如果category的名稱小於20就補空格,並且右對齊,如果其名稱長於30字符,就從左邊交遠銷出的字符截掉。
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="appender1"
>
<param name="File" value="logfile08.html" />
<param name="MaxFileSize" value="1MB" />
<param name="MaxBackupIndex" value="5" />
<layout>
</layout>
</appender>
<root>
<level value="debug" />
<appender-ref ref="appender1" />
</root>
</log4j:configuration>
在程式中使用Log4j之前,首先要將commons-logging.jar和logging-log4j-1.2.9.jar匯入到classpath中,並將log4j.properties放於src根目錄中。 在類別中使用log4j,先宣告一個靜態變數Loggerlogger=Logger.getLog("classname").現在就可以使用了。
用法如下:logger.debug("debugmessage")或logger.info("infomessage").
1.得到記錄器
使用Log4j,第一步就是取得日誌記錄器,這個記錄器將負責控制日誌資訊。
其語法為:
publicstaticLoggergetLogger(Stringname)
透過指定的名字來獲得記錄器,如果必要的話,則為這個名字建立一個新的記錄器。 Name一般取本類的名字,例如:
staticLoggerlogger=Logger.getLogger(ServerWithLog4j.class.getName())
2.讀取設定檔
當獲得了日誌記錄器之後,第二步將配置Log4j環境,其語法為:
BasicConfigurator.configure():自動快速地使用預設Log4j環境。
PropertyConfigurator.configure(StringconfigFilename):讀取使用Java的特性檔編寫的設定檔。
DOMConfigurator.configure(Stringfilename):讀取XML形式的設定檔。
3.插入記錄資訊(格式化日誌資訊)
當上兩個必要步驟執行完畢,您就可以輕鬆地使用不同優先級的日誌記錄語句插入到您想記錄日誌的任何地方,語法如下:
Logger.debug(Objectmessage);
Logger.info(Objectmessage);
Logger.warn(Objectmessage);
Logger.error(Objectmessage);
程式演示
1.使用程式進行日誌資訊輸出
import java.io.IOException;
import org.apache.commons.logging.impl.Log4JLogger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
/**
*
* @version : 1.1
*
* @author : 蘇若年<a href="mailto:[email protected]">寄郵件</a>
*
* @since : 1.0 建立時間: 2013-1-1 下午03:19:42
*
* @function: 透過程式碼將日誌輸出
*
*/
public class Log4jPrintByCode {
private static Logger logger = Logger.getLogger(Log4jPrintByCode.class);
private Layout layout = new SimpleLayout();
private FileAppender fileAppender;
//使用建構依賴,建立物件時初始化
public Log4jPrintByCode(Layout layout, Level level,String distDir){
BasicConfigurator.configure(); //使用預設的設定資訊,不需要寫log4j.properties
try {
init(layout,level, distDir);
} catch (Exception e) {
e.printStackTrace();
}
}
public void init(Layout layout, Level level,String distDir) throws Exception{
logger.setLevel(level); //設定日誌輸出級別
fileAppender = new FileAppender(layout,distDir,false);
logger.addAppender(fileAppender); //新增輸出端
}
public static void main(String[] args) {
SimpleLayout layout = new SimpleLayout();
String logDir = "log4jcode.Log";
Log4jPrintByCode log4jCode = new Log4jPrintByCode(layout,Level.INFO,logDir);
//下面資訊將會被輸出
log4jCode.logger.info("log info print by log4j");
log4jCode.logger.warn("log warn print by log4j");
log4jCode.logger.error("log error print by log4j");
}
public Layout getLayout() {
return layout;
}
public void setLayout(Layout layout) {
this.layout = layout;
}
public FileAppender getFileAppender() {
return fileAppender;
}
public void setFileAppender(FileAppender fileAppender) {
this.fileAppender = fileAppender;
}
}
// 記錄info級別的信息
if (logger.isInfoEnabled()) {
logger.info("This is info message from Dao.");
}
2.Log4J將同一個日誌資訊輸出到多個目的地
/* 切換資料庫*/
use db_log4j;
/* 日誌資訊表*/
create table tb_log(
logId int not null auto_increment comment '流水號' ,
createDate varchar(45) default null comment '日誌產生時間' ,
thread varchar(45) default null comment '當前線程',
level varchar(45) default null comment '目前日誌等級' ,
class varchar(45) default null comment '產生日誌的類別',
message varchar(245) default null comment '日誌具體資訊',
primary key(logId)
);
應用實例將日誌資訊同時輸出到控制台,檔案和資料庫中.
建立資料庫與表
/* 切換資料庫*/
use db_log4j;
/* 日誌資訊表*/
create table tb_log(
logId int not null auto_increment comment '流水號' ,
createDate varchar(45) default null comment '日誌產生時間' ,
thread varchar(45) default null comment '當前線程',
level varchar(45) default null comment '目前日誌等級' ,
class varchar(45) default null comment '產生日誌的類別',
message varchar(245) default null comment '日誌具體資訊',
primary key(logId)
);
#定義A1輸出到控制器
log4j.appender.A1=org.apache.log4j.ConsoleAppender
#定義A1的佈局模式為PaternLayout
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
# 定義A1的輸出格式
log4j.appender.A1.layout.ConversionPattern=%4p [%t] (%F:%L) - %m%n
#定義A2輸出到文件
log4j.appender.A2=org.apache.log4j.RollingFileAppender
#定義A2輸出到哪個文件
log4j.appender.A2.File=./log/sysLog.log
#定義A2輸出檔的最大長度
log4j.appender.A2.MaxFileSize = 1KB
#定義A2的備份檔數
log4j.appender.A2.MaxBackupIndex = 3
#定義A2的佈局模式為PatternLayout
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
#定義A2的輸出模式
log4j.appender.A2.layout.ConversionPattern=%d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n
#定義A3輸出到資料庫
log4j.appender.A3=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.A3.URL=jdbc:mysql://localhost:3306/db_log4j
log4j.appender.A3.driver=com.mysql.jdbc.Driver
log4j.appender.A3.user=root
log4j.appender.A3.password=root
#定義A3的佈局和執行的SQL語句
log4j.appender.A3.layout=org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern=INSERT INTO tb_log(createDate,thread,level,class,message) values('%d','%t','%-5p','%c','%m ')
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
/**
*
* @version : 1.1
*
* @author : 蘇若年<a href="mailto:[email protected]">寄郵件</a>
*
* @since : 1.0 建立時間: 2013-1-1 下午04:13:59
*
* @function: 透過設定檔控制日誌資訊輸出到多個目的端
*
*/
public class Log4jPrintByConfigure {
private static Logger logger = Logger.getLogger(Log4jPrintByConfigure.class);
public static void main(String[] args) throws Exception {
//載入log設定檔log4j.properties
PropertyConfigurator.configure("configure/log4j.properties");//檔案存放在src同目錄的configure資料夾下
//如果放在src下的話,參數要為"bin/log4j.properties"或"src/log4j.properties", 建議以bin為準
//以下資訊將會被列印輸出
logger.debug("logger print DEBUG messgae");
logger.info("logger print INFO message");
logger.warn("logger print WARN message");
logger.error("logger print ERROR message");
logger.fatal("Here is FATAL message");
}
}