Log4j 2中記錄日誌的方式有同步日誌和異步日誌兩種方式,其中異步日誌又可分爲使用AsyncAppender和使用AsyncLogger兩種方式。java
同步日誌
所謂同步日誌,即當輸出日誌時,必須等待日誌輸出語句執行完畢後,才能執行後面的業務邏輯語句。spring
下面給出小編在開發中的配置apache
<?xml version="1.0" encoding="UTF-8"?><Configuration>
<Properties><!-- 日誌輸出級別 --><Property name="LOG_INFO_LEVEL" value="info"/><!-- error級別日誌 --><Property name="LOG_ERROR_LEVEL" value="error"/><!-- 在當前目錄下建立名爲log目錄作日誌存放的目錄 --><Property name="LOG_HOME" value="./log"/><!-- 檔案日誌存放目錄 --><Property name="LOG_ARCHIVE" value="./log/archive"/><!-- 模塊名稱, 影響日誌配置名,日誌文件名,根據本身項目進行配置 --><Property name="LOG_MODULE_NAME" value="spring-boot"/><!-- 日誌文件大小,超過這個大小將被壓縮 --><Property name="LOG_MAX_SIZE" value="100 MB"/><!-- 保留多少天之內的日誌 --><Property name="LOG_DAYS" value="15"/><!--輸出日誌的格式:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度, %msg:日誌消息,%n是換行符 --><Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/><!--interval屬性用來指定多久滾動一次--><Property name="TIME_BASED_INTERVAL" value="1"/></Properties>
<Appenders><!-- 控制檯輸出 --><Console name="STDOUT" target="SYSTEM_OUT"><!--輸出日誌的格式--><PatternLayout pattern="${LOG_PATTERN}"/><!--控制檯只輸出level及其以上級別的信息(onMatch),其餘的直接拒絕(onMismatch)--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Console>
<!-- 這個會打印出全部的info級別以上,error級別一下的日誌,每次大小超過size或者知足TimeBasedTriggeringPolicy,則日誌會自動存入按年月日創建的文件夾下面並進行壓縮,做爲存檔--><RollingRandomAccessFile name="RollingRandomAccessFileInfo"fileName="${LOG_HOME}/${LOG_MODULE_NAME}-infoLog.log"filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-infoLog-%d{yyyy-MM-dd}-%i.log.gz"><Filters><!--若是是error級別拒絕,設置 onMismatch="NEUTRAL" 可讓日誌通過後續的過濾器--><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/><!--若是是info\warn輸出--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><!--interval屬性用來指定多久滾動一次,根據當前filePattern設置是1天滾動一次--><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><!-- DefaultRolloverStrategy屬性如不設置,則默認同一文件夾下最多保存7個文件--><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile>
<!--只記錄error級別以上的日誌,與info級別的日誌分不一樣的文件保存--><RollingRandomAccessFile name="RollingRandomAccessFileError"fileName="${LOG_HOME}/${LOG_MODULE_NAME}-errorLog.log"filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-errorLog-%d{yyyy-MM-dd}-%i.log.gz"><Filters><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile>
</Appenders>
<Loggers><!-- 開發環境使用 --><!--<Root level="${LOG_INFO_LEVEL}"> <AppenderRef ref="STDOUT"/> </Root>-->
<!-- 測試,生產環境使用 --><Root level="${LOG_INFO_LEVEL}"><AppenderRef ref="RollingRandomAccessFileInfo"/><AppenderRef ref="RollingRandomAccessFileError"/></Root></Loggers>
</Configuration>
混合同步和異步日誌微信
Log4j-2.9及更高版本在類路徑上須要disruptor-3.3.4.jar或更高版本。在Log4j-2.9以前,須要disruptor-3.0.0.jar或更高版本。無需將系統屬性「Log4jContextSelector」設置爲任何值。dom
能夠在配置中組合同步和異步記錄器。這爲您提供了更大的靈活性,但代價是性能略有降低(與使全部記錄器異步相比)。使用<asyncRoot>或<asyncLogger> 配置元素指定須要異步的記錄器。配置只能包含一個根記錄器(<root> 或<asyncRoot>元素),可是能夠組合異步和非異步記錄器。例如,包含<asyncLogger>元素的配置文件也能夠包含<root>和同步記錄器的元素。異步
默認狀況下,異步記錄器不會將位置傳遞給I / O線程。若是您的某個佈局或自定義過濾器須要位置信息,則須要在全部相關記錄器的配置中設置「includeLocation = true」,包括根記錄器。async
首先引入disruptor依賴spring-boot
<dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.4.2</version></dependency>
混合異步記錄器的配置可能以下所示:佈局
<?xml version="1.0" encoding="UTF-8"?><Configuration>
<Properties><!-- 日誌輸出級別 --><Property name="LOG_INFO_LEVEL" value="info"/><!-- error級別日誌 --><Property name="LOG_ERROR_LEVEL" value="error"/><!-- 在當前目錄下建立名爲log目錄作日誌存放的目錄 --><Property name="LOG_HOME" value="./log"/><!-- 檔案日誌存放目錄 --><Property name="LOG_ARCHIVE" value="./log/archive"/><!-- 模塊名稱, 影響日誌配置名,日誌文件名,根據本身項目進行配置 --><Property name="LOG_MODULE_NAME" value="spring-boot"/><!-- 日誌文件大小,超過這個大小將被壓縮 --><Property name="LOG_MAX_SIZE" value="100 MB"/><!-- 保留多少天之內的日誌 --><Property name="LOG_DAYS" value="15"/><!--輸出日誌的格式:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度, %msg:日誌消息,%n是換行符 --><Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/><!--interval屬性用來指定多久滾動一次--><Property name="TIME_BASED_INTERVAL" value="1"/></Properties>
<Appenders><!-- 控制檯輸出 --><Console name="STDOUT" target="SYSTEM_OUT"><!--輸出日誌的格式--><PatternLayout pattern="${LOG_PATTERN}"/><!--控制檯只輸出level及其以上級別的信息(onMatch),其餘的直接拒絕(onMismatch)--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Console>
<!-- 這個會打印出全部的info級別以上,error級別一下的日誌,每次大小超過size或者知足TimeBasedTriggeringPolicy,則日誌會自動存入按年月日創建的文件夾下面並進行壓縮,做爲存檔--><!--異步日誌會自動批量刷新,因此將immediateFlush屬性設置爲false--><RollingRandomAccessFile name="RollingRandomAccessFileInfo"fileName="${LOG_HOME}/${LOG_MODULE_NAME}-infoLog.log"filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-infoLog-%d{yyyy-MM-dd}-%i.log.gz"immediateFlush="false"><Filters><!--若是是error級別拒絕,設置 onMismatch="NEUTRAL" 可讓日誌通過後續的過濾器--><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/><!--若是是info\warn輸出--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><!--interval屬性用來指定多久滾動一次,根據當前filePattern設置是1天滾動一次--><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><!-- DefaultRolloverStrategy屬性如不設置,則默認同一文件夾下最多保存7個文件--><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile>
<!--只記錄error級別以上的日誌,與info級別的日誌分不一樣的文件保存--><RollingRandomAccessFile name="RollingRandomAccessFileError"fileName="${LOG_HOME}/${LOG_MODULE_NAME}-errorLog.log"filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-errorLog-%d{yyyy-MM-dd}-%i.log.gz"immediateFlush="false"><Filters><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile>
</Appenders>
<Loggers><!-- 開發環境使用 --><!--<Root level="${LOG_INFO_LEVEL}"> <AppenderRef ref="STDOUT"/> </Root>-->
<!-- 測試,生產環境使用 --><!-- 當使用<asyncLogger> or <asyncRoot>時,無需設置系統屬性"Log4jContextSelector" --><AsyncLogger name="com.jourwon" level="${LOG_INFO_LEVEL}" additivity="false"><AppenderRef ref="RollingRandomAccessFileInfo"/><AppenderRef ref="RollingRandomAccessFileError"/></AsyncLogger>
<Root level="${LOG_INFO_LEVEL}"><AppenderRef ref="RollingRandomAccessFileInfo"/><AppenderRef ref="RollingRandomAccessFileError"/></Root></Loggers>
</Configuration>
異步日誌(性能最好,推薦使用)性能
Log4j-2.9及更高版本在類路徑上須要disruptor-3.3.4.jar或更高版本。在Log4j-2.9以前,須要disruptor-3.0.0.jar或更高版本。
這是最簡單的配置,並提供最佳性能。要使全部記錄器異步,請將disruptor jar添加到類路徑,並將系統屬性log4j2.contextSelector設置 爲org.apache.logging.log4j.core.async.AsyncLoggerContextSelector。
默認狀況下,異步記錄器不會將位置傳遞給I / O線程。若是您的某個佈局或自定義過濾器須要位置信息,則須要在全部相關記錄器的配置中設置「includeLocation = true」,包括根記錄器。
首先引入disruptor依賴
<dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.4.2</version></dependency>
而後在src/java/resources目錄添加log4j2.component.properties配置文件
# 設置異步日誌系統屬性log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
配置以下所示:
<?xml version="1.0" encoding="UTF-8"?><Configuration>
<Properties><!-- 日誌輸出級別 --><Property name="LOG_INFO_LEVEL" value="info"/><!-- error級別日誌 --><Property name="LOG_ERROR_LEVEL" value="error"/><!-- 在當前目錄下建立名爲log目錄作日誌存放的目錄 --><Property name="LOG_HOME" value="./log"/><!-- 檔案日誌存放目錄 --><Property name="LOG_ARCHIVE" value="./log/archive"/><!-- 模塊名稱, 影響日誌配置名,日誌文件名,根據本身項目進行配置 --><Property name="LOG_MODULE_NAME" value="spring-boot"/><!-- 日誌文件大小,超過這個大小將被壓縮 --><Property name="LOG_MAX_SIZE" value="100 MB"/><!-- 保留多少天之內的日誌 --><Property name="LOG_DAYS" value="15"/><!--輸出日誌的格式:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度, %msg:日誌消息,%n是換行符 --><Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/><!--interval屬性用來指定多久滾動一次--><Property name="TIME_BASED_INTERVAL" value="1"/></Properties>
<Appenders><!-- 控制檯輸出 --><Console name="STDOUT" target="SYSTEM_OUT"><!--輸出日誌的格式--><PatternLayout pattern="${LOG_PATTERN}"/><!--控制檯只輸出level及其以上級別的信息(onMatch),其餘的直接拒絕(onMismatch)--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Console>
<!-- 這個會打印出全部的info級別以上,error級別一下的日誌,每次大小超過size或者知足TimeBasedTriggeringPolicy,則日誌會自動存入按年月日創建的文件夾下面並進行壓縮,做爲存檔--><!--異步日誌會自動批量刷新,因此將immediateFlush屬性設置爲false--><RollingRandomAccessFile name="RollingRandomAccessFileInfo"fileName="${LOG_HOME}/${LOG_MODULE_NAME}-infoLog.log"filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-infoLog-%d{yyyy-MM-dd}-%i.log.gz"immediateFlush="false"><Filters><!--若是是error級別拒絕,設置 onMismatch="NEUTRAL" 可讓日誌通過後續的過濾器--><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/><!--若是是info\warn輸出--><ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><!--interval屬性用來指定多久滾動一次,根據當前filePattern設置是1天滾動一次--><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><!-- DefaultRolloverStrategy屬性如不設置,則默認同一文件夾下最多保存7個文件--><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile>
<!--只記錄error級別以上的日誌,與info級別的日誌分不一樣的文件保存--><RollingRandomAccessFile name="RollingRandomAccessFileError"fileName="${LOG_HOME}/${LOG_MODULE_NAME}-errorLog.log"filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-errorLog-%d{yyyy-MM-dd}-%i.log.gz"immediateFlush="false"><Filters><ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/></Filters><PatternLayout pattern="${LOG_PATTERN}"/><Policies><TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/><SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/></Policies><DefaultRolloverStrategy max="${LOG_DAYS}"/></RollingRandomAccessFile>
</Appenders>
<Loggers><!-- 開發環境使用 --><!--<Root level="${LOG_INFO_LEVEL}"> <AppenderRef ref="STDOUT"/> </Root>-->
<!-- 測試,生產環境使用 --><Root level="${LOG_INFO_LEVEL}" includeLocation="false"><AppenderRef ref="RollingRandomAccessFileInfo"/><AppenderRef ref="RollingRandomAccessFileError"/></Root></Loggers>
</Configuration>
當配置AsyncLoggerContextSelector做爲異步日誌時,請確保在配置中使用普通的 <root>和<logger>元素。AsyncLoggerContextSelector將確保全部記錄器都是異步的,使用的機制與配置<asyncRoot> 或<asyncLogger>時的機制不一樣。
經過log.info(「是否爲異步日誌:{}」, AsyncLoggerContextSelector.isSelected());能夠查看是否爲異步日誌。
原文連接:
https://blog.csdn.net/ThinkWon/article/details/101625124
本文分享自微信公衆號 - 源代碼社區(ydmsq666)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。