您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關(guān)log4j2的異步使用及添加自定義參數(shù)方式是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
關(guān)于log4j2的性能和原理就不贅述了,這篇主要講使用,配置文件解讀,和添加自定義參數(shù),偏應(yīng)用的一篇文章。
相比與其他的日志系統(tǒng),log4j2丟數(shù)據(jù)這種情況少;disruptor技術(shù),在多線程環(huán)境下,性能高于logback等10倍以上;利用jdk1.5并發(fā)的特性,減少了死鎖的發(fā)生;
目前看來(lái),log4j2的性能最突出。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions><!-- 去掉springboot默認(rèn)配置 --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <!-- 引入log4j2依賴 --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
然后再各個(gè)項(xiàng)目中添加文件log4j2.xml,在要使用的類上添加@slf4j 注解(lombok的),即可使用log對(duì)象。
log4j 2.0與以往的1.x有一個(gè)明顯的不同,其配置文件只能采用.xml, .json或者 .jsn。在默認(rèn)情況下,系統(tǒng)選擇configuration文件的優(yōu)先級(jí)如下:(classpath為src文件夾)
classpath下名為 log4j-test.json 或者log4j-test.jsn文件
classpath下名為 log4j2-test.xml
classpath下名為 log4j.json 或者log4j.jsn文件
classpath下名為 log4j2.xml
level:日志輸出級(jí)別,共有8個(gè)級(jí)別,按照從低到高為:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
<?xml version="1.0" encoding="UTF-8"?> <!-- Configuration后面的status,這個(gè)用于設(shè)置log4j2自身內(nèi)部的信息輸出,可以不設(shè)置,當(dāng)設(shè)置成trace時(shí),你會(huì)看到log4j2內(nèi)部各種詳細(xì)輸出--> <!-- monitorInterval:Log4j能夠自動(dòng)檢測(cè)修改配置 文件和重新配置本身,設(shè)置間隔秒數(shù)--> <configuration status="WARN"> <Properties> <!--常用變量配置 供下文中使用--> <property name="APP_NAME">項(xiàng)目名稱</property> <property name="LOGGER_LEVEL">INFO</property> <!--日志路徑 對(duì)應(yīng)服務(wù)器路徑--> <property name="LOGGER_PATH">/data/logs</property> <Property name="LOG_HOME">${LOGGER_PATH}/${APP_NAME}</Property> <!--文件大小--> <Property name="FILE_SIZE">10M</Property> <!--日志格式--> <Property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n</Property> <!--日志文件命名格式--> <Property name="rolling_file_name">-%d{yyyy-MM-dd}.%i.zip</Property> <!--日志留存最大文件數(shù)--> <Property name="rollover_strategy_max">30</Property> <Property name="LOG_HOME_PROJECT">${LOG_HOME}/${APP_NAME}-project</Property> <Property name="LOG_HOME_PROJECT_ERROR">${LOG_HOME}/${APP_NAME}-project-error</Property> <Property name="LOG_HOME_SQL">${LOG_HOME}/${APP_NAME}-sql</Property> </Properties> <appenders> <!--控制臺(tái)打印 及格式--> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="${log_pattern}" /> </Console> <!--定義rolling() 供下文使用--> <RollingRandomAccessFile name="projectRolling" fileName="${LOG_HOME_PROJECT}.log" filePattern="${LOG_HOME_PROJECT}${rolling_file_name}" immediateFlush="false" append="true"> <PatternLayout> <Pattern>${log_pattern}</Pattern> <Charset>UTF-8</Charset> </PatternLayout> <Policies> <!--滾動(dòng)規(guī)則 時(shí)間或者文件大小 滾動(dòng)后將按照f(shuō)ilePattern命名--> <!--interval屬性用來(lái)指定多久滾動(dòng)一次,默認(rèn)是1 hour--> <TimeBasedTriggeringPolicy interval="24"/> <SizeBasedTriggeringPolicy size="${FILE_SIZE}"/> </Policies> <DefaultRolloverStrategy max="${rollover_strategy_max}" /> </RollingRandomAccessFile> <RollingRandomAccessFile name="projectErrorRolling" fileName="${LOG_HOME_PROJECT_ERROR}.log" filePattern="${LOG_HOME_PROJECT_ERROR}${rolling_file_name}" immediateFlush="false" append="true"> <Filters> <!-- 只輸出level及以上級(jí)別的信息(onMatch),其他的直接拒絕(onMismatch)可以使用多個(gè)ThresholdFilter 達(dá)到精準(zhǔn)過(guò)濾某個(gè)級(jí)別的日志--> <ThresholdFilter level="${LOGGER_LEVEL}" onMatch="ACCEPT" onMismatch="DENY" /> </Filters> <PatternLayout> <Pattern>${log_pattern}</Pattern> <Charset>UTF-8</Charset> </PatternLayout> <Policies> <SizeBasedTriggeringPolicy size="${FILE_SIZE}"/> </Policies> <DefaultRolloverStrategy max="${rollover_strategy_max}" /> </RollingRandomAccessFile> </RollingRandomAccessFile> <RollingRandomAccessFile name="sqlRolling" fileName="${LOG_HOME_SQL}.log" filePattern="${LOG_HOME_SQL}${rolling_file_name}" immediateFlush="false" append="true"> <PatternLayout> <Pattern>${log_pattern}</Pattern> <Charset>UTF-8</Charset> </PatternLayout> <Policies> <SizeBasedTriggeringPolicy size="${FILE_SIZE}"/> </Policies> <DefaultRolloverStrategy max="${rollover_strategy_max}" /> </RollingRandomAccessFile> </appenders> <!--Logger節(jié)點(diǎn)用來(lái)單獨(dú)指定日志的形式,比如要為指定包下的class指定不同的日志級(jí)別等。--> <loggers> <!--異步日志 區(qū)別于普通使用的logger root 搭配--> <!--name 為包名 對(duì)應(yīng)配置日志輸出等級(jí)level --> <!--若是additivity設(shè)為false,則 子Logger 只會(huì)在自己的appender里輸出,而不會(huì)在 父Logger 的appender里輸出。--> <!--將org.springframework包下的日志打印到Console控制臺(tái),projectRolling文件,projectErrorRolling(error級(jí)別單獨(dú)一個(gè)文件)--> <AsyncLogger name="org.springframework" level="${LOGGER_LEVEL}" additivity="false"> <appender-ref ref="Console"/> <appender-ref ref="projectRolling"/> <appender-ref ref="projectErrorRolling"/> </AsyncLogger> <AsyncLogger name="com.alibaba.dubbo" level="${LOGGER_LEVEL}" additivity="false"> <appender-ref ref="Console"/> <appender-ref ref="projectRolling"/> <appender-ref ref="projectErrorRolling"/> </AsyncLogger> <AsyncLogger name="druid.sql" level="${LOGGER_LEVEL}" additivity="false"> <appender-ref ref="Console"/> <appender-ref ref="sqlRolling"/> </AsyncLogger> <AsyncLogger name="org.mybatis" level="${LOGGER_LEVEL}" additivity="false"> <appender-ref ref="Console"/> <appender-ref ref="sqlRolling"/> </AsyncLogger> <AsyncLogger name="com.項(xiàng)目包名" level="${LOGGER_LEVEL}" additivity="false"> <appender-ref ref="Console"/> <appender-ref ref="projectRolling"/> <appender-ref ref="projectErrorRolling"/> </AsyncLogger> <AsyncRoot level="${LOGGER_LEVEL}"> <appender-ref ref="Console"/> <appender-ref ref="projectRolling" /> <appender-ref ref="projectErrorRolling" /> </AsyncRoot> </loggers> </configuration>
如上配置會(huì)產(chǎn)生3個(gè)日志文件
項(xiàng)目名稱-project.log
項(xiàng)目名稱-project-error.log
項(xiàng)目名稱-sql.log
onMatch和onMismatch都有三個(gè)屬性值,分別為Accept、DENY和NEUTRAL
分別介紹這兩個(gè)配置項(xiàng)的三個(gè)屬性值:
onMatch=“ACCEPT”
表示匹配該級(jí)別及以上
onMatch=“DENY”
表示不匹配該級(jí)別及以上
onMatch=“NEUTRAL”
表示該級(jí)別及以上的,由下一個(gè)filter處理,如果當(dāng)前是最后一個(gè),則表示匹配該級(jí)別及以上
onMismatch=“ACCEPT”
表示匹配該級(jí)別以下
onMismatch=“NEUTRAL”
表示該級(jí)別及以下的,由下一個(gè)filter處理,如果當(dāng)前是最后一個(gè),則不匹配該級(jí)別以下的
onMismatch=“DENY”
表示不匹配該級(jí)別以下的
%d{HH:mm:ss.SSS}
表示輸出到毫秒的時(shí)間
%logger{36}
簡(jiǎn)單理解為類名
%thread
輸出當(dāng)前線程名稱
%-5level
輸出日志級(jí)別,-5表示左對(duì)齊并且固定輸出5個(gè)字符,如果不足在右邊補(bǔ)0
%logger
輸出logger名稱,因?yàn)镽oot Logger沒(méi)有名稱,所以沒(méi)有輸出
%msg
日志文本
%n
換行
%X{xxx} xxx
為自定義參數(shù)
定義攔截器(web服務(wù)攔controller,dubbo服務(wù)攔api),每次請(qǐng)求過(guò)來(lái),攔住,然后將自定義參數(shù)傳入。至于自定義參數(shù)怎么存,就是另一個(gè)問(wèn)題了。
eg: traceId 跟蹤號(hào) 對(duì)應(yīng)log4j2.xml中的 %X{traceId}
下面是關(guān)鍵代碼:
public class ContextFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { String traceId = UUID.randomUUID().toString().replaceAll("-", ""); // org.slf4j.MDC MDC.put(CommonConsts.TRACE_ID_LOG, traceId);// 用來(lái)給日志文件使用 // org.apache.logging.log4j.ThreadContext ThreadContext.put(CommonConsts.TRACE_ID_LOG, traceId); //經(jīng)測(cè)試,這兩行都可行。 filterChain.doFilter(servletRequest, servletResponse); }
最后的日志打印效果如下:
2019-05-29 12:04:30.122 [http-nio-8080-exec-2] [2333333] INFO com.core.web.filter.ContextFilter - 接口調(diào)用時(shí)間:245毫秒
使用log4j、log4j2輸入日志時(shí),有時(shí)想追加打印自定義參數(shù)(比如客戶端環(huán)境:手機(jī)型號(hào)、瀏覽器數(shù)據(jù),request數(shù)據(jù)、用戶數(shù)據(jù)等),以便于快速定位問(wèn)題所在。
亦或在多線程環(huán)境中,快速定位哪些日志是由同一用戶輸出,便于其他工具進(jìn)行日志分析。
log4j提供了ThreadContext 線程上下文類,用于存儲(chǔ)自定義數(shù)據(jù),以便在輸入日志時(shí),包含指定數(shù)據(jù)。
package com.howtodoinjava.log4j2.examples; import java.util.UUID; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.ThreadContext; public class Log4j2HelloWorldExample { private static final Logger LOGGER = LogManager.getLogger(Log4j2HelloWorldExample.class.getName()); public static void main(String[] args) { //Add context information ThreadContext.put("id", UUID.randomUUID().toString()); ThreadContext.put("ipAddress", "192.168.21.9"); LOGGER.debug("Debug Message Logged !!"); LOGGER.info("Info Message Logged !!"); LOGGER.debug("Another Debug Message !!"); //Clear the map ThreadContext.clearMap(); LOGGER.debug("Thread Context Cleaned up !!"); LOGGER.debug("Log message with no context information !!"); } }
而后在 log4j.xml 中指定上述參數(shù),
單獨(dú)使用%X以包含地圖的全部?jī)?nèi)容。
使用%X{key}包括指定的鍵。
使用%x包括堆棧的全部?jī)?nèi)容。
在實(shí)際應(yīng)用時(shí),一般是在過(guò)濾器、攔截器進(jìn)行上述操作,方法之前,將數(shù)據(jù)綁定到線程中,方法完成后,清理線程數(shù)據(jù)。
看完上述內(nèi)容,你們對(duì)log4j2的異步使用及添加自定義參數(shù)方式是什么有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝大家的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。