log4j2使用總結1
在項目運行過程中,常常需要進行功能調試以及用戶行為的跟蹤和記錄,部分人習慣使用System.out,但這並不建議,它僅僅是使用方便但不便於維護也無擴展性。相比log4j的話,log4j可以控制日誌信息的輸送目的地、輸出格式以及級別等等,使我們能夠更加細致地控制日誌的生成過程。
Log4j2是對Log4j1的升級,在性能和功能上有顯著的改進,包括多線程中吞吐量的增強、占位符的支持、配置文件自動重新加載等
一、入門介紹
1、下載jar包
pox.xml
<dependencies> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.10.0</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.10.0</version> </dependency> </dependencies>
2、配置文件
Log4j包含四個配置工廠實現:JSON、YAML、properties、XML,本文介紹常用的properties和XML兩種。
Log4j具有在初始化期間自動配置自身的能力。當Log4j啟動時,它將定位類路徑下所有符合名稱的文件,優先級順序:log4j2-test.properties > log4j2-test.xml > log4j2.properties > log4j2.xml
3、一個簡單的實例
xml配置:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> </Root> </Loggers> </Configuration>
java代碼:
private static final Logger logger = LogManager.getLogger(MyApp.class); @Test public void testLog4j(){ logger.info("hello world!"); } }
控制臺信息
22:17:47.146 [main] INFO MyApp - hello world!
二、模塊介紹
<Configuration>
屬性 | 描述 |
monitorInterval | 如果文件被修改了,指定時間後會重新加載配置。單位秒,最小值是5 |
packages | 以逗號隔開的包名列表,用於搜索插件,比如自定義filter、appender等。插件僅會加載一次,所以要想修改後生效必須重啟項目 |
status | 內部日誌級別,設置值為debug可以在控制臺上清晰地看到整個日誌事件流程,所使用的Logger是org.apache.logging.log4j.core.LOGGER |
strict | 允許使用嚴格的XML格式。不支持JSON配置 |
verbose | 在加載插件時啟用診斷信息 |
<Appenders>
Log4j允許將日誌請求打印到多個目的地。在log4j語言中,輸出目的地稱為Appender。目前,appender存在於控制臺、文件、遠程套接字服務器、Apache Flume、JMS、遠程UNIX Syslog守護進程和各種數據庫api中。以下介紹幾種比較常用的appender,如需了解更多可以到官網上進行查閱。
1、ConsoleAppender
輸出到控制臺,<Console>
參數名稱 |
類型 |
描述 |
filter |
Filter |
過濾器 |
layout |
Layout |
日誌輸出格式 |
follow |
boolean |
|
direct |
boolean |
|
name |
String |
Appender的名稱 |
ignoreExceptions |
boolean |
默認true,忽略寫入異常 |
target |
String |
SYSTEM_OUT或SYSTEM_ERR,默認是SYSTEM_OUT |
2、FileAppender
輸出到文件,<File>
參數 |
類型 |
描述 |
---|---|---|
append |
boolean |
默認是true,新記錄將追加到文件尾部 |
bufferedIO |
boolean |
默認是true,使用緩沖區可以顯著地提高性能 |
bufferSize |
int |
當bufferedIO是true時,這個屬性緩沖區大小,默認是8192字節。 |
createOnDemand |
boolean |
appender按需創建文件。只有當一個日誌事件通過所有過濾器並被路由到這個appender時,appender才會創建這個文件。默認值為假 |
filter |
Filter |
一個過濾器來確定事件是否應該由這個Appender處理。使用復合過濾器可以使用多個篩選器 |
fileName |
String |
要寫入的文件的名稱。如果文件或它的任何父目錄不存在,它們將被創建 |
immediateFlush |
boolean |
默認true,每次寫入後都將有一個刷新。這將保證緩沖區的數據被寫入磁盤,但可能會影響性能。 |
layout |
Layout |
日誌格式 |
locking |
boolean |
文件鎖,默認false |
name |
String |
Appender的名稱 |
ignoreExceptions |
boolean |
默認true,忽略寫入異常 |
filePermissions |
String |
定義文件權限 例: rw------- or rw-rw-rw- etc... |
fileOwner |
String |
定義文件所有者 |
fileGroup |
String |
定義文件組 |
3、JDBCAppender
JDBCAppender使用標準JDBC將日誌事件寫入到關系數據庫表中。它可以配置為使用JNDI數據源或自定義工廠方法獲得JDBC連接。無論采用哪種方法,都必須由連接池來支持。否則,日誌記錄性能將受到極大的影響。如果已配置的JDBC驅動程序支持批處理語句,並且將緩沖區大小配置為一個正數,那麽日誌事件將被批處理。
(1)<JDBC>
參數 |
類型 |
描述 |
---|---|---|
name |
String |
必須,appender的名稱 |
ignoreExceptions |
boolean |
默認true,忽略日誌事件異常 |
filter |
Filter |
過濾器 |
bufferSize |
int |
如果一個大於0的整數,這將導致appender緩沖日誌事件,並在緩沖區達到該大小時刷新寫入數據 |
connectionSource |
ConnectionSource |
必須,可被檢索到的數據庫連接 |
tableName |
String |
必須,插入日誌事件的數據表名 |
columnConfigs |
ColumnConfig[] |
必須,需要插入到數據庫的字段,由多個<Column>元素組成 |
columnMappings |
ColumnMapping[] |
必須,字段映射配置 |
(2)使用<DataSource>來獲得JDBC的連接:
參數 | 類型 | 描述 |
---|---|---|
jndiName | String | 必需的,如已配置的jndi為jdbc/LoggingDatabase,那此處的值為java:comp/env/jdbc/LoggingDatabase。數據源必須由連接池來支持;否則,日誌記錄將非常緩慢。 |
(3)使用<Column>來指定要寫入表中的哪些列,以及如何對它們進行寫入。它沒有SQL註入漏洞。
參數 | 類型 | 描述 |
---|---|---|
name | String |
必須,表字段名稱 |
pattern | String |
使用PatternLayout模式插入值,註:同一個Column元素中,patter、literal、isEventTimestamp3個屬性只能存在一個 |
literal | String |
該值將直接包含在SQL語句中執行,比如:rand()函數將生成隨機數,類似myibats中的${} |
isEventTimestamp | boolean |
是否時間格式java.sql.Types.TIMESTAMP |
isUnicode | boolean |
除非指定pattern,否則該屬性將被忽略。如果是true,該值將插入Unicode。否則,該值將被插入非Unicode。 |
isClob | boolean |
除非指定pattern,否則該屬性將被忽略。如果是true,該值將插入CLOB,否則將插入varchar、nvarchar |
實例:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="error"> <Appenders> <JDBC name="databaseAppender" tableName="dbo.application_log"> <DataSource jndiName="java:/comp/env/jdbc/LoggingDataSource" /> <Column name="eventDate" isEventTimestamp="true" /> <Column name="level" pattern="%level" /> <Column name="logger" pattern="%logger" /> <Column name="message" pattern="%message" /> <Column name="exception" pattern="%ex{full}" /> </JDBC> </Appenders> <Loggers> <Root level="warn"> <AppenderRef ref="databaseAppender"/> </Root> </Loggers> </Configuration>
補充:
在實際應用中,有時需要對用戶的訪問信息進行記錄,比如請求參數、用戶id等等。在log4j1中我們會使用MDC和NDC來存儲應用程序的上下文信息,而log4j2使用ThreadContext來實現MDC和NDC兩者的功能。
(1)NDC采用類似棧的機制來存儲上下文信息,線程獨立。
在PatternLayout中使用 %x 來輸出,註意x是小寫。
實例:
Test.java
ThreadContext.push("hello world!");
log4j2.xml
<Column name="tip" pattern="%x" />
(2)MDC采用類似map的機制來存儲信息,線程獨立。
在PatternLayout中使用 %X{userId} 來輸出,註意X是大寫。
實例:
Test.java
ThreadContext.put("userId","1");
log4j2.xml
<Column name="userId" pattern="%X{userId}" />
註意使用完後調用clearAll()清除上下文映射和堆棧。
<PatternLayout>
pattern
(1)日期,%d / %date
Pattern |
示例 |
---|---|
%d{DEFAULT} |
2012-11-02 14:34:02,781 |
%d{ISO8601} |
2012-11-02T14:34:02,781 |
%d{ISO8601_BASIC} |
20121102T143402,781 |
%d{ABSOLUTE} |
14:34:02,781 |
%d{DATE} |
02 Nov 2012 14:34:02,781 |
%d{COMPACT} |
20121102143402781 |
%d{HH:mm:ss,SSS} |
14:34:02,781 |
%d{dd MMM yyyy HH:mm:ss,SSS} |
02 Nov 2012 14:34:02,781 |
%d{HH:mm:ss}{GMT+0} |
18:34:02 |
%d{UNIX} |
1351866842 |
%d{UNIX_MILLIS} |
1351866842781 |
當然你也可以自定義格式,比如 %d{yyyy-dd-MMM HH:mm:ss}
(2)記錄器,%c / %logger
Conversion Pattern |
Logger Name |
結果 |
---|---|---|
%c{1} |
org.apache.commons.Foo |
Foo |
%c{2} |
org.apache.commons.Foo |
commons.Foo |
%c{10} |
org.apache.commons.Foo |
org.apache.commons.Foo |
%c{-1} |
org.apache.commons.Foo |
apache.commons.Foo |
%c{-2} |
org.apache.commons.Foo |
commons.Foo |
%c{-10} |
org.apache.commons.Foo |
org.apache.commons.Foo |
%c{1.} |
org.apache.commons.Foo |
o.a.c.Foo |
%c{1.1.~.~} |
org.apache.commons.test.Foo |
o.a.~.~.Foo |
%c{.} |
org.apache.commons.test.Foo |
....Foo |
{?} - ?是正整數時表示從右邊開始取n個部分,負整數表示從左邊開始移除n個部分,那為什麽%c{-10}是完整的名稱我也不清楚,歡迎留言
(3)日誌信息,%m / %msg / %message
(4)日誌等級,%level
api:http://logging.apache.org/log4j/2.x/javadoc.html
官網地址:https://logging.apache.org/log4j/2.x/index.html
轉載請註明出處:http://www.cnblogs.com/cjh-notes/p/8017855.html
log4j2使用總結1