slf4j+log4j2模式的日誌搭建
前言:今天打算為大家介紹一下我們我們在項目中必須得有的一個部分——日誌!是的,就是那些讓我們看著頭疼的東西~~~好的日誌可以幫助團隊成員快速發現並解決問題,用好了可以大幅度提高代碼缺陷修復效率!言歸正傳,今天先來講講如何為一個項目建立日誌!解決方案:(slf4j+log4j2)
項目地址:https://github.com/ksuth/wsyq.git
原理介紹:
現在行業內有很多關於日誌記錄的jar包,我選用的slf4j可以通俗的理解為一個日誌調用的接口,其本身裏面是沒有關於日誌的具體實現,所以我選用了log4j作為它的具體實現。(這也是目前用得比較多吧~~)當然如果你覺得不好,也可以選用其他具體日誌作為其實現。
環境搭建:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.9.1</version>
</dependency>
2.新增log4j2.xml的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Properties>
<Property name="baseDir">/logtest</Property>
</Properties>
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="%d %p [%c] [%M] [Line:%L] - <%m>%n"/>
</Console>
<RollingFile name="RollingFile" fileName="${baseDir}/logs/app.log"
filePattern="${baseDir}/logs/app-%d{MM-dd-yyyy}.log.gz">
<RegexFilter regex=".*password.*" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<TimeBasedTriggeringPolicy />
</RollingFile>
</Appenders>
<Loggers>
<AsyncLogger name="test.log.shuyuq" level="debug" additivity="false" includeLocation="true">
<AppenderRef ref="RollingFile"/>
</AsyncLogger>
<AsyncRoot level="info">
<AppenderRef ref="console"/>
</AsyncRoot>
</Loggers>
</Configuration>
3.包裝原生日誌:(這個並不是必須的,主要應用於公司對日誌有特別的規範,或者業務處理中需要一些特別的記錄)項目日誌類:
@Data
public class CASLogger {
/** LOGINDEVICE */
private static final String LOGINDEVICE="loginDevice";
/** slf4j */
private Logger log;
/**
* 調用類名
* @param name String
*/
public CASLogger(String name) {
log = org.slf4j.LoggerFactory.getLogger(name);
}
/**
* 此處用於重寫需要用的的log方法
*/
}
為項目日誌類提供靜態的調用方式:
package util;
import java.util.HashMap;
import java.util.Map;
/**
* 功能描述: 日誌添加
* @author shuyuq
* @date 2018-8-17
**************************************************/
public class LoggerFactory {
private static Object initLock = new Object();
private static Map<String, CASLogger> loggerMap = new HashMap<String, CASLogger>();
/**
* 功能描述: 獲取Logger
* @param name String
* @return CASLogger CASLogger
* Date: 2018-8-17
*/
public static CASLogger getLogger(String name) {
CASLogger casLogger = null;
synchronized(initLock) {
casLogger = loggerMap.get(name);
if (casLogger == null) {
casLogger = new CASLogger(name);
loggerMap.put(name, casLogger);
}
}
return casLogger;
}
/**
* 功能描述: 獲取Logger
* @param clazz String
* @return CASLogger CASLogger
* Date: 2018-8-17
*/
public static CASLogger getLogger(Class<?> clazz) {
String name=clazz.getName();
CASLogger casLogger = null;
synchronized(initLock) {
casLogger = loggerMap.get(name);
if (casLogger == null) {
casLogger = new CASLogger(name);
loggerMap.put(name, casLogger);
}
}
return casLogger;
}
}
做到這兒整個項目的簡單日誌文件就已經搭建好啦~下面著重為大家介紹一下log4j2的配置文件!這也是實現其日誌個性化的核心!
配置說明:
1.配置文件加載的優先級:
classpath下名為 log4j-test.json 或者log4j-test.jsn文件
classpath下名為 log4j2-test.xml
classpath下名為 log4j.json 或者log4j.jsn文件
classpath下名為 log4j2.xml文件
2.簡單參數介紹:
先為大家貼上log4j的官方文檔地址:https://logging.apache.org/log4j/2.x/
如果需要實現一些特別的個性化功能可參考官方文檔
我在這兒為大家介紹一些比較常用的參數:
Properties:這個參數主要用於為配置文件定義一些常用量,可參考上面的配置中我為其定義了一個文件寫的路徑
Appenders:用於包裹Appender標簽,每一個Appender為一個OutputStream
Loggers:用於包裹Logger標簽,Logger標簽用於篩選路徑(類比於spring的掃描路徑)和指定需要使用的Appender
3.RollingFileAppender
RollingFileAppender是一個OutputStreamAppender,它寫入fileName參數中指定的File,並根據TriggeringPolicy和RolloverPolicy滾動文件。RollingFileAppender使用RollingFileManager(擴展OutputStreamManager)來實際執行文件I / O並執行翻轉。雖然無法共享來自不同配置的RolloverFileAppenders,但如果可以訪問Manager,則可以使用RollingFileManagers。例如,如果Log4j位於兩個共用的ClassLoader中,則servlet容器中的兩個Web應用程序可以擁有自己的配置並安全地寫入同一文件。
RollingFileAppender需要TriggeringPolicy和 RolloverStrategy。觸發策略確定是否應在RolloverStrategy定義如何進行翻轉時執行翻轉。如果未配置RolloverStrategy,則RollingFileAppender將使用DefaultRolloverStrategy。從log4j-2.5開始,可以在DefaultRolloverStrategy中配置自定義刪除操作以在翻轉時運行。從2.8開始,如果沒有配置文件名, 則將使用DirectWriteRolloverStrategy而不是DefaultRolloverStrategy。從log4j-2.9開始,自定義POSIX文件屬性查看動作 可以在DefaultRolloverStrategy中配置以在rollover中運行,如果未定義,將應用RollingFileAppender繼承的POSIX文件屬性視圖。
RollingFileAppender不支持文件鎖定。
關於參數的問題~~~(在官網中找到Appenders搜索RollingFileAppender可以找到對應內容 更多參數請訪問:http://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender)
參數名稱 | 類型 | 說明 |
append | boolean | 默認為true,記錄追加到文件的最後,否則就先清除以前的記錄再寫入 |
bufferedIO | boolean | 如果為true - 默認情況下,記錄將寫入緩沖區,當緩沖區已滿時,數據將寫入磁盤;如果設置了immediateFlush,則寫入記錄時。文件鎖定不能與bufferedIO一起使用。性能測試表明,即使啟用了immediateFlush,使用緩沖I / O也可以顯著提高性能。 |
bufferSize | int | 當bufferedIO為true時,這是緩沖區大小,默認為8192字節。 |
createOnDemand | boolean | appender按需創建文件。appender僅在日誌事件通過所有過濾器並將其路由到此appender時創建該文件。默認為false. |
filter | Filter | 過濾器,用於確定此Appender是否應該處理該事件。使用CompositeFilter可以使用多個Filter |
fileName | String | 要寫入的文件的名稱。如果文件或其任何父目錄不存在,則將創建它們。 |
filePattern | String | 歸檔日誌文件的文件名模式。模式的格式取決於使用的RolloverPolicy。DefaultRolloverPolicy將同時接受與SimpleDateFormat兼容的日期/時間模式 和/或表示整數計數器的%i。該模式還支持在運行時進行插值,因此任何查找(例如DateLookup)都可以包含在模式中 |
immediateFlush | boolean | 設置為true時 - 默認值,每次寫入後都會進行刷新。這將保證數據寫入磁盤,但可能會影響性能。
每次寫入後刷新僅在將此appender與同步記錄器一起使用時才有用。即使immediateFlush設置為false,異步記錄器和追加器也會在一批事件結束時自動刷新。這也保證了數據被寫入磁盤但效率更高 |
layout | Layout | 用於格式化LogEvent的布局。如果未提供布局,則將使用“%m%n”的默認圖案布局。 |
name | String | Appender的名字 |
policy | TriggeringPolicy | 用於確定是否應發生翻轉的策略 |
strategy | RolloverStrategy | 用於確定存檔文件的名稱和位置的策略 |
參數名稱 | 類型 | 說明 | |||
ignoreExceptions | boolean | 默認值為true,導致在將事件附加到內部記錄然後被忽略時遇到異常。設置為false時,異常將傳播給調用者。將此Appender包裝在FailoverAppender中時, 必須將此參數設置為false。 | |||
filePermissions | String | POSIX格式的文件屬性權限,以便在創建文件時應用 | |||
fileOwner | String | 文件所有者在每次創建文件時定義,出於安全原因,可能會限制更改文件的所有者,並且不允許操作IOException。如果_POSIX_CHOWN_RESTRICTED對路徑有效,則只有具有等效於文件用戶ID或具有適當權限的有效用戶ID的進程才能更改文件的所有權。 | |||
fileGroup | String |
文件組,用於定義創建文件的時間 |
slf4j+log4j2模式的日誌搭建