目錄[-]
1 系列目錄
- 2種日志接口框架,4種日志實現框架
- Apache Log4j
- Apache Commons Logging
- JDK Logging
- Logback
- Apache Log4j2
2 默認配置
本來以為Log4J2應該有一個默認的配置文件的,不過好像沒有找到(通過DefaultConfiguration,初始化一個最小化配置),下面這個配置文件等同於缺省配置:
<?xml version="1.0" encoding="UTF-8"?> <configuration status="OFF"> <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="error"> <appender-ref ref="Console"/> </root> </loggers> </configuration>
3 第一個配置例子
配置Log4j 2可以有四種方法(其中任何一種都可以):
- 通過一個格式為
XML或JSON的配置文件。 - 以編程方式,通過創建一個
ConfigurationFactory工廠和Configuration實現。 - 以編程方式,通過調用
api暴露在配置界面添加組件的默認配置。 - 以編程方式,通過調用
Logger內部類上的方法。
注意,與Log4j 1.x不一樣的地方,公開的Log4j 2 API沒有提供任何添加、修改或刪除 appender和過濾器或者操作配置文件的方法。
Log4j能夠自動配置本身在初始化期間。當Log4j啟動它將定位所有的ConfigurationFactory插件和安排然后在加權從最高到最低。Log4j包含兩個ConfigurationFactory實現,一個用於JSON和XML。加載配置文件流程如下:
- Log4j將檢查“Log4j的配置文件“系統屬性,如果設置,將
嘗試加載配置使用 ConfigurationFactory 匹配的文件擴展。 - 如果
沒有系統屬性設置JSON ConfigurationFactory log4j2-test將尋找。 json或 log4j2-test。json在類路徑中。 - 如果
沒有這樣的文件發現XML ConfigurationFactory log4j2-test將尋找。 xml在 類路徑。 - 如果
一個測試文件無法找到JSON ConfigurationFactory log4j2將尋找。 log4j2.jsn json或 在類路徑中。 - 如果
一個JSON文件無法找到XML ConfigurationFactory將試圖定位 log4j2。 xml在類路徑中。 - 如果
沒有配置文件可以找到了 DefaultConfiguration 將被使用。 這將導致日志輸出到控制台。
<?xml version="1.0" encoding="UTF-8"?> <configuration status="OFF"> <appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> </appenders> <loggers> <!--我們只讓這個logger輸出trace信息,其他的都是error級別--> <!-- additivity開啟的話,由於這個logger也是滿足root的,所以會被打印兩遍。 不過root logger 的level是error,為什么Bar 里面的trace信息也被打印兩遍呢 --> <logger name="cn.lsw.base.log4j2.Hello" level="trace" additivity="false"> <appender-ref ref="Console"/> </logger> <root level="error"> <appender-ref ref="Console"/> </root> </loggers> </configuration>
我們這里看到了配置文件里面是name很重要,沒錯,這個name可不能隨便起(其實可以隨便起)。這個機制意思很簡單。就是類似於java package一樣,比如我們的一個包:cn.lsw.base.log4j2。而且,可以發現我們前面生成Logger對象的時候,命名都是通過 Hello.class.getName(); 這樣的方法,為什么要這樣呢? 很簡單,因為有所謂的Logger 繼承的問題。比如 如果你給cn.lsw.base定義了一個logger,那么他也適用於cn.lsw.base.lgo4j2這個logger。名稱的繼承是通過點(.)分隔的。然后你可以猜測上面loggers里面有一個子節點不是logger而是root,而且這個root沒有name屬性。這個root相當於根節點。你所有的logger都適用與這個logger,所以,即使你在很多類里面通過類名.class.getName() 得到很多的logger,而且沒有在配置文件的loggers下面做配置,他們也都能夠輸出,因為他們都繼承了root的log配置。
我們上面的這個配置文件里面還定義了一個logger,他的名稱是 cn.lsw.base.log4j2.Hello ,這個名稱其實就是通過前面的Hello.class.getName(); 得到的,我們為了給他單獨做配置,這里就生成對於這個類的logger,上面的配置基本的意思是只有cn.lsw.base.log4j2.Hello 這個logger輸出trace信息,也就是他的日志級別是trace,其他的logger則繼承root的日志配置,日志級別是error,只能打印出ERROR及以上級別的日志。如果這里logger 的name屬性改成cn.lsw.base,則這個包下面的所有logger都會繼承這個log配置(這里的包是log4j的logger name的“包”的含義,不是java的包,你非要給Hello生成一個名稱為“myhello”的logger,他也就沒法繼承cn.lsw.base這個配置了。
那有人就要問了,他不是也應該繼承了root的配置了么,那么會不會輸出兩遍呢?我們在配置文件中給了解釋,如果你設置了additivity="false",就不會輸出兩遍。
4 復雜一點的配置
<?xml version="1.0" encoding="UTF-8"?> <!-- Configuration后面的status,這個用於設置log4j2自身內部的信息輸出,可以不設置,當設置成trace時,你會看到log4j2內部各種詳細輸出。 --> <!-- monitorInterval:Log4j能夠自動檢測修改配置 文件和重新配置本身,設置間隔秒數。 --> <configuration status="error" monitorInterval=”30″> <!--先定義所有的appender--> <appenders> <!--這個輸出控制台的配置--> <Console name="Console" target="SYSTEM_OUT"> <!--控制台只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch)--> <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/> <!--這個都知道是輸出日志的格式--> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </Console> <!--文件會打印出所有信息,這個log每次運行程序會自動清空,由append屬性決定,這個也挺有用的,適合臨時測試用--> <File name="log" fileName="log/test.log" append="false"> <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/> </File> <!-- 這個會打印出所有的信息,每次大小超過size,則這size大小的日志會自動存入按年份-月份建立的文件夾下面並進行壓縮,作為存檔--> <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/> <SizeBasedTriggeringPolicy size="50MB"/> <!-- DefaultRolloverStrategy屬性如不設置,則默認為最多同一文件夾下7個文件,這里設置了20 --> <DefaultRolloverStrategy max="20"/> </RollingFile> </appenders> <!--然后定義logger,只有定義了logger並引入的appender,appender才會生效--> 