新需求要在log4j上做些自定義的東西,所以補了log4j2這一塊的東西
配置
先看下log4j2的傳統配置
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<properties>
<property name="log_path">C:/</property>
<property name="file_name">file.log</property>
<property name="root_level">error</property>
</properties>
<Appenders>
<!--console :控制檯輸出的配置-->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<!--File :同步輸出日誌到本地文件 append:是否追加寫-->
<File name="log" fileName="${logFilePath}/${logFileName}" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!--RollingFile:日誌滾動策略-->
<RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"
filePattern="${sys:user.home}/logs/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
<!--ThresholdFilter :日誌輸出過濾-->
<!--level="info" :日誌級別,onMatch="ACCEPT" :級別在info之上則接受,onMismatch="DENY" :級別在info之下則拒絕-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!-- Policies :日誌滾動策略-->
<Policies>
<!-- TimeBasedTriggeringPolicy :時間滾動策略,默認0點小時產生新的文件,interval="6" : 自定義文件滾動時間間隔,每隔6小時產生新文件, modulate="true" : 產生文件是否以0點偏移時間,即6點,12點,18點,0點-->
<TimeBasedTriggeringPolicy interval="6" modulate="true"/>
<!-- SizeBasedTriggeringPolicy :文件大小滾動策略-->
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<!-- DefaultRolloverStrategy屬性如不設置,則默認爲最多同一文件夾下7個文件,這裏設置了20 -->
<DefaultRolloverStrategy max="20"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="${root_level}">
<AppenderRef ref="Console"/>
</Root>
<!--配置Mybatis Sql語句打印-->
<logger name="com.demo.mapper" level="debug" additivity="false">
<AppenderRef ref="Console"/>
</logger>
</Loggers>
</Configuration>
配置主要包括以下幾個節點
- Configuration
- properties
- property
- Appenders
- Console
- File
- RollingFile
- Loggers
- Logger
- Root
- properties
Configuration標籤
日誌的根標籤,主要屬性介紹
屬性名 | 描述 |
---|---|
monitorInterval | 定時掃描日誌配置,動態改變日誌配置。參數爲秒,最低值爲5 |
name | 日誌配置名稱 |
status | 設置日誌內部打印級別 |
strict | 日誌模式 |
schema | 指定文檔約束 |
Properties
日誌文件中需要用到的屬性值,通過子標籤<property>
設置
property
用於設置日誌可能會用到的屬性值,比如配置文件中的
<property name="log_path">C:/</property>
在配置其他屬性時可以通過${log_path}
獲取。
Appenders
包含多個<Appender>
子標籤,用於指定日誌的輸出位置及格式級別等,比如<Console>
,將日誌打印到控制檯。
Console
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
屬性名 | 描述 |
---|---|
name | 配置名稱 |
target | “SYSTEM_OUT"或者"SYSTEM_ERR”,默認是"SYSTEM_OUT" |
子節點
- PatternLayout:日誌輸出樣式設置
File
定義輸出到指定位置的文件,
<File name="log" fileName="${logFilePath}/${logFileName}" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
屬性名 | 描述 |
---|---|
name | 配置名稱 |
fileName | 日誌輸出日誌文件名稱 |
append | 是否追加輸出到文件 |
RollingFile
輸出日誌文件策略,可進行歷史日誌壓縮存儲等操作
屬性名 | 描述 |
---|---|
name | 配置名稱 |
fileName | 日誌文件名稱 |
filePattern | 指定新建日誌文件的名稱格式 |
子節點
- ThresholdFilter:過濾日誌級別過濾器
- PatternLayout:日誌輸出樣式
- Policies:指定滾動日誌的策略,何時進行新建日誌文件輸出日誌
- TimeBasedTriggeringPolicy:指定日誌滾動時間間隔,interval 屬性指定間隔時間,默認爲 1 小時。modulate屬性,是否以0點爲標準時間
- SizeBasedTriggeringPolicy:指定日誌文件大小的滾動策略,size 屬性用來定義每個日誌文件的大小
- DefaultRolloverStrategy:指定日誌文件覆蓋策略,默認爲最多同一個文件夾下7個文件開始覆蓋刪除舊日誌文件,max屬性定義最大數
Loggers
包含一個默認的日誌輸出和多個其他可選的日誌輸出,通常包括Root
和Logger
節點
Root
Root 節點用來指定項目的根日誌,如果沒有單獨指定 Logger,那麼就會默認使用該 Root日誌輸出,必須存在的標籤
<Root level="${root_level}">
<AppenderRef ref="Console"/>
</Root>
屬性名 | 描述 |
---|---|
level | 日誌輸出級別,All<Trace<Debug<Info<Warn<Error<Fatal < OFF |
子節點
- AppenderRef:指定日誌輸出Appender
Logger
Loggers的子節點,用來單獨指定日誌的形式
<!--配置Mybatis Sql語句打印-->
<logger name="com.demo.mapper" level="debug" additivity="false">
<AppenderRef ref="Console"/>
</logger>
屬性名 | 描述 |
---|---|
name | 必須,指定具體的要打印的日誌,通常爲包路徑 |
level | 日誌輸出級別,可選,默認爲ERROR級別 |
additivity | 是否繼承其他日誌輸出,可能會在Root中打印日誌,可選,默認爲false |
子節點
- AppenderRef:指定日誌輸出Appender,如未指定則繼承Root
自定義Appender
大多數情況下Log4j2提供的Appender能夠滿足業務需求,當然想要自定義日誌的輸出位置和方式可以通過自定義Appender方式實現。下面代碼展示如何實現自定義Appender,通過繼承AbstractAppender
類
@Plugin(name="DefineAppender",category = "Core",elementType = "appender",printObject = true)
public class DefineAppender extends AbstractAppender {
//自定義配置項
private String fileName;
protected DefineAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions,String fileName) {
super(name, filter, layout, ignoreExceptions);
//自定義配置項
this.fileName = fileName;
}
@Override
public void append(LogEvent logEvent) {
//這裏實現自定義日誌的業務邏輯
}
@PluginFactory
public static DefineAppender createAppender(@PluginAttribute("name") String name,
@PluginElement("Filter") final Filter filter,
@PluginElement("Layout") Layout<? extends Serializable> layout,
@PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
@PluginAttribute("filename") String fileName) {
if (name == null) {
LOGGER.error("No name defiend in conf");
return null;
}
if (layout == null) {
layout = PatternLayout.createDefaultLayout();
}
return new DefineAppender(name, filter, layout, ignoreExceptions,fileName);
}
}
過濾器
日誌過濾器,通過配置過濾器可以過濾自己希望輸出的日誌,符合條件的日誌可以被當前過濾器通過,進入到後續的處理。log4j2提供了多種日誌。
比如ThresholdFilter過濾器,過濾不同級別的日誌
<ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
參數 | 描述 |
---|---|
level | 設置過濾日誌級別 |
onMatch | 滿足level,根據參數值確定是否打印日誌 |
onMismatch | 不滿足level,根據參數值是否過濾日誌 |
onMatch與onMisMatch使用三個參數值,分別是ACCEPT
,DENY
,NEUTRY
。
- onMatch=“ACCEPT” 表示匹配該級別及以上
- onMatch=“DENY” 表示不匹配該級別及以上
- onMatch=“NEUTRAL” 表示該級別及以上的,由下一個filter處理,如果當前是最後一個,則表示匹配該級別及以上
- onMismatch=“ACCEPT” 表示匹配該級別以下
- onMismatch=“NEUTRAL” 表示該級別及以下的,由下一個filter處理,如果當前是最後一個,則不匹配該級別以下的
- onMismatch=“DENY” 表示不匹配該級別以下的
其他過濾器可以參考Log4j2過濾器;
自定義過濾器
自定義了一個日誌概率輸出過濾器。
當需要自定義過濾器時可以繼承AbstractFilter
@Plugin(name = "LogRateFilter", category = Node.CATEGORY, elementType = Filter.ELEMENT_TYPE, printObject = true)
public class LogRateFilter extends AbstractFilter {
//自定義配置項
private final Double rate;
private LogRateFilter(final Double rate,final Result onMatch,final Result onMismatch){
super(onMatch,onMismatch);
// 自定義配置項
this.rate = rate;
}
@PluginFactory
public static LogRateFilter createFilter(
@PluginAttribute("rate") Double rate,
@PluginAttribute("onMatch") final Result match,
@PluginAttribute("onMismatch") final Result mismatch){
final Double actuaRate = rate == 0.0 ? 1.0:rate;
final Result onMatch = match == null ? Result.NEUTRAL : match;
final Result onMismatch = mismatch == null ? Result.DENY : mismatch;
return new LogRateFilter(rate,onMatch,onMismatch);
}
public Result filter(Level level){
// 根據日誌級別實現業務
Random random = new Random();
double seed = random.nextDouble();
System.out.println(seed);
return seed <= rate ? onMatch:onMismatch;
}
@Override
public Result filter(final LogEvent event) {
return filter(event.getLevel());
}
@Override
public Result filter(final Logger logger, final Level level, final Marker marker, final Message msg,
final Throwable t) {
return filter(level);
}
@Override
public Result filter(final Logger logger, final Level level, final Marker marker, final Object msg,
final Throwable t) {
return filter(level);
}
@Override
public Result filter(final Logger logger, final Level level, final Marker marker, final String msg,
final Object... params) {
return filter(level);
}
}
使用
項目中自定義過濾器需要讓Log4j加載到,在configuration 配置packages 目錄,多個目錄以,
分割
<configuration monitorInterval="5" packages="com.demo.log4j2.config">
<console name="Console" target="SYSTEM_OUT">
<!--輸出日誌的格式-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<!-- rate:日誌輸出概率50% -->
<LogRateFilter rate="0.5" />
</console>
</configuration>