中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

log4j2的異步使用及添加自定義參數方式是什么

發布時間:2021-12-22 20:20:41 來源:億速云 閱讀:314 作者:柒染 欄目:開發技術

今天就跟大家聊聊有關log4j2的異步使用及添加自定義參數方式是什么,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

    log4j2異步使用及添加自定義參數

    關于log4j2的性能和原理就不贅述了,這篇主要講使用,配置文件解讀,和添加自定義參數,偏應用的一篇文章。

    相比與其他的日志系統,log4j2丟數據這種情況少;disruptor技術,在多線程環境下,性能高于logback等10倍以上;利用jdk1.5并發的特性,減少了死鎖的發生;

    目前看來,log4j2的性能最突出。

    添加依賴(這里省略了版本號)

    <dependency> 
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions><!-- 去掉springboot默認配置 -->
    <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>

    然后再各個項目中添加文件log4j2.xml,在要使用的類上添加@slf4j 注解(lombok的),即可使用log對象。

    log4j 2.0與以往的1.x有一個明顯的不同,其配置文件只能采用.xml, .json或者 .jsn。在默認情況下,系統選擇configuration文件的優先級如下:(classpath為src文件夾)

    • classpath下名為 log4j-test.json 或者log4j-test.jsn文件

    • classpath下名為 log4j2-test.xml

    • classpath下名為 log4j.json 或者log4j.jsn文件

    • classpath下名為 log4j2.xml

    level:日志輸出級別,共有8個級別,按照從低到高為:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.

    下面寫一個生產可用的log4j2.xml的模板

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Configuration后面的status,這個用于設置log4j2自身內部的信息輸出,可以不設置,當設置成trace時,你會看到log4j2內部各種詳細輸出-->
    <!-- monitorInterval:Log4j能夠自動檢測修改配置 文件和重新配置本身,設置間隔秒數-->
    <configuration status="WARN">
    <Properties>
    <!--常用變量配置 供下文中使用-->
    <property name="APP_NAME">項目名稱</property>
    <property name="LOGGER_LEVEL">INFO</property>
    <!--日志路徑 對應服務器路徑-->
    <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>
    <!--日志留存最大文件數-->
    <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>
    <!--控制臺打印 及格式-->
    <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>
    <!--滾動規則 時間或者文件大小 滾動后將按照filePattern命名-->
    <!--interval屬性用來指定多久滾動一次,默認是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及以上級別的信息(onMatch),其他的直接拒絕(onMismatch)可以使用多個ThresholdFilter 達到精準過濾某個級別的日志-->
    <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節點用來單獨指定日志的形式,比如要為指定包下的class指定不同的日志級別等。-->
    <loggers>
    <!--異步日志 區別于普通使用的logger root 搭配-->
    <!--name 為包名 對應配置日志輸出等級level -->
    <!--若是additivity設為false,則 子Logger 只會在自己的appender里輸出,而不會在 父Logger 的appender里輸出。-->
    <!--將org.springframework包下的日志打印到Console控制臺,projectRolling文件,projectErrorRolling(error級別單獨一個文件)-->
    <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.項目包名" 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>

    如上配置會產生3個日志文件

    • 項目名稱-project.log

    • 項目名稱-project-error.log

    • 項目名稱-sql.log

    補充知識

    onMatch和onMismatch都有三個屬性值,分別為Accept、DENY和NEUTRAL

    分別介紹這兩個配置項的三個屬性值:

    • onMatch=“ACCEPT” 表示匹配該級別及以上

    • onMatch=“DENY” 表示不匹配該級別及以上

    • onMatch=“NEUTRAL” 表示該級別及以上的,由下一個filter處理,如果當前是最后一個,則表示匹配該級別及以上

    • onMismatch=“ACCEPT” 表示匹配該級別以下

    • onMismatch=“NEUTRAL” 表示該級別及以下的,由下一個filter處理,如果當前是最后一個,則不匹配該級別以下的

    • onMismatch=“DENY” 表示不匹配該級別以下的

    自定義日志格式
    • %d{HH:mm:ss.SSS} 表示輸出到毫秒的時間

    • %logger{36} 簡單理解為類名

    • %thread 輸出當前線程名稱

    • %-5level 輸出日志級別,-5表示左對齊并且固定輸出5個字符,如果不足在右邊補0

    • %logger 輸出logger名稱,因為Root Logger沒有名稱,所以沒有輸出

    • %msg 日志文本

    • %n 換行

    • %X{xxx} xxx為自定義參數

    如何在日志中添加自己想傳的參數?

    定義攔截器(web服務攔controller,dubbo服務攔api),每次請求過來,攔住,然后將自定義參數傳入。至于自定義參數怎么存,就是另一個問題了。

    eg: traceId 跟蹤號 對應log4j2.xml中的 %X{traceId}

    下面是關鍵代碼:

    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);// 用來給日志文件使用
    // org.apache.logging.log4j.ThreadContext
        ThreadContext.put(CommonConsts.TRACE_ID_LOG, traceId); //經測試,這兩行都可行。
        filterChain.doFilter(servletRequest, servletResponse);
    }

    最后的日志打印效果如下:

    2019-05-29 12:04:30.122 [http-nio-8080-exec-2] [2333333] INFO com.core.web.filter.ContextFilter - 接口調用時間:245毫秒

    log4j 輸入自定義參數

    使用log4j、log4j2輸入日志時,有時想追加打印自定義參數(比如客戶端環境:手機型號、瀏覽器數據,request數據、用戶數據等),以便于快速定位問題所在。

    亦或在多線程環境中,快速定位哪些日志是由同一用戶輸出,便于其他工具進行日志分析。

    log4j提供了ThreadContext 線程上下文類,用于存儲自定義數據,以便在輸入日志時,包含指定數據。

    測試代碼如下

    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 中指定上述參數,

    log4j2的異步使用及添加自定義參數方式是什么

    單獨使用%X以包含地圖的全部內容。

    使用%X{key}包括指定的鍵。

    使用%x包括堆棧的全部內容。

    在實際應用時,一般是在過濾器、攔截器進行上述操作,方法之前,將數據綁定到線程中,方法完成后,清理線程數據。

    看完上述內容,你們對log4j2的異步使用及添加自定義參數方式是什么有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    建宁县| 界首市| 若尔盖县| 湖口县| 西和县| 长葛市| 容城县| 南城县| 盘山县| 北流市| 阜康市| 靖江市| 郴州市| 绵阳市| 花垣县| 澄迈县| 攀枝花市| 朔州市| 汉中市| 昆明市| 华宁县| 应城市| 京山县| 淮南市| 勃利县| 宁夏| 邹平县| 镇江市| 德令哈市| 葫芦岛市| 资讯| 沙湾县| 寻乌县| 石屏县| 酉阳| 德化县| 泸定县| 汾西县| 绥阳县| 班戈县| 疏附县|