最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

自定義log4j2中的Appender來獲取日志內(nèi)容的示例代碼

 更新時(shí)間:2024年02月06日 09:21:50   作者:咖啡杯里的茶_  
在 Log4j2 中,Appender 是負(fù)責(zé)將日志事件輸出到目標(biāo)地點(diǎn)的組件,本文講述的是通過 log4j 中自定義的 Appender 來獲取需要打印的日志信息,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下

springboot版本:2.6.15 log4j版本:2.17.2

Log4j中的Appender 是什么

本文講述的是通過 log4j 中自定義的 Appender 來獲取需要打印的日志信息,那么 Appender 是什么東西呢?先簡(jiǎn)單了解一下

在 Log4j2 中,Appender 是負(fù)責(zé)將日志事件輸出到目標(biāo)地點(diǎn)的組件。Appender 可以將日志事件輸出到控制臺(tái)、文件、網(wǎng)絡(luò)等不同的目的地。 Log4j2 提供了多種內(nèi)置的 Appender,例如 ConsoleAppender、FileAppender、AsyncAppender 等,同時(shí)支持自定義 Appender。 Appender 的主要職責(zé)是將日志事件按照指定的格式和目的地輸出。每個(gè) Appender 都有自己的名稱和類型,可以根據(jù)需要配置不同的屬性。例如,F(xiàn)ileAppender 用于將日志事件輸出到文件中,其屬性包括文件名、追加模式(是否覆蓋已存在的文件或追加到文件末尾)等。

需求背景

有兩個(gè)系統(tǒng),系統(tǒng) A 和系統(tǒng) B, 系統(tǒng) A 會(huì)發(fā)送指令給系統(tǒng) B, 系統(tǒng) B 會(huì)響應(yīng)結(jié)果給系統(tǒng) A,這兩個(gè)系統(tǒng)之間的通信方式是 MQ, 即 A 通過 MQ 發(fā)送數(shù)據(jù)給 B(數(shù)據(jù)中有 UUID 字段值),系統(tǒng) B處理完成后將結(jié)果通過 MQ 發(fā)送給 A,請(qǐng)求和響應(yīng)的對(duì)應(yīng)關(guān)系則可以通過 UUID 來進(jìn)行匹配

現(xiàn)在有一個(gè)需求是監(jiān)控在某個(gè)時(shí)間段內(nèi)發(fā)送了多少指令,以及多少指令失敗(在給定時(shí)間內(nèi)沒有收到響應(yīng)或者響應(yīng)中給了錯(cuò)誤結(jié)果認(rèn)為失敗)

對(duì)于這種需求一般都是通過 AOP 來解決,但是在部分場(chǎng)景下 AOP 也比較難處理,比如上面場(chǎng)景中其實(shí)這個(gè)監(jiān)控處理是有兩部分的,第一部分是發(fā)送請(qǐng)求,第二部分是獲取請(qǐng)求對(duì)應(yīng)的結(jié)果,而且不是 http 調(diào)用,是通過 MQ 調(diào)用,即業(yè)務(wù)邏輯實(shí)現(xiàn)是分布在兩個(gè)方法中的 (可以抽取一層將發(fā)送請(qǐng)求和響應(yīng)結(jié)果邏輯放在一起,并且返回原始結(jié)果即可)

下面基于已有實(shí)現(xiàn)提供另外一種更簡(jiǎn)單的解決方式,已有實(shí)現(xiàn)的特點(diǎn):

  • 指令發(fā)送和結(jié)果接收都被抽取成獨(dú)立的方法,只要是兩個(gè)系統(tǒng)間的 MQ 通信最終都會(huì)調(diào)用這兩個(gè)方法(一個(gè)發(fā)送,一個(gè)接收結(jié)果)
  • 在這兩個(gè)方法中都將原始的參數(shù)以及最終的響應(yīng)結(jié)果給打印出來了 基于以上兩點(diǎn),如果可以拿到打印的日志信息就可以比較簡(jiǎn)單匯總處理

修改前測(cè)試代碼

log4j2 配置文件

下面 log4j2-dev.xml 配置文件很簡(jiǎn)單,就是將所有日志打印到控制臺(tái),日志級(jí)別為 info

<?xml version="1.0" encoding="UTF-8"?>  
<!--monitorInterval:Log4j能夠自動(dòng)檢測(cè)修改配置 文件和重新配置本身,設(shè)置間隔秒數(shù)-->  
<configuration monitorInterval="60">  
    <Properties>  
        <property name="LOG_PATTERN_CONSOLE"  
                  value="%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n%xwEx"/>  
    </Properties>  
  
    <appenders>  
        <!-- Console 是將日志信息打印打控制臺(tái)-->  
        <console name="Console" target="SYSTEM_OUT">  
            <PatternLayout pattern="${LOG_PATTERN_CONSOLE}"/>  
            <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>  
        </console>  
    </appenders>  
  
    <loggers>    
        <root level="info">  
            <AppenderRef ref="Console"/>  
        </root>  
    </loggers>  
  
</configuration>

兩個(gè)測(cè)試類代碼

給出兩個(gè)測(cè)試類是為了對(duì)比,后續(xù)自定義的 Appender 只會(huì)作用在一個(gè)測(cè)試類中,對(duì)于其他類的日志打印不會(huì)獲取到對(duì)應(yīng)的日志信息

@Component  
public class DemoService {  
    private static final Logger logger = LoggerFactory.getLogger(DemoService.class);  
    public void doSomething(String param) {  
        logger.info("test demo");  
    }  
}

@Component  
public class DemoService2 {  
    private static final Logger logger = LoggerFactory.getLogger(DemoService2.class);  
    public void doSomething(String param) {  
        logger.info("test demo 2");  
    }  
}

自定義Appender

自定義的 Appender 不需要被 Spring 管理,所以不需要 @Component 等注解

package com.example;  
  
import org.apache.logging.log4j.core.Appender;  
import org.apache.logging.log4j.core.Filter;  
import org.apache.logging.log4j.core.Layout;  
import org.apache.logging.log4j.core.LogEvent;  
import org.apache.logging.log4j.core.appender.AbstractAppender;  
import org.apache.logging.log4j.core.config.plugins.Plugin;  
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;  
import org.apache.logging.log4j.core.config.plugins.PluginElement;  
import org.apache.logging.log4j.core.config.plugins.PluginFactory;  
import org.apache.logging.log4j.core.layout.PatternLayout;  
  
import java.io.Serializable;  
  
@Plugin(name = "CusAppender", category = "Core", elementType = Appender.ELEMENT_TYPE)  
public class CustomAppender extends AbstractAppender {  
  
    protected CustomAppender(String name, Filter filter, Layout<? extends Serializable> layout) {  
        super(name, filter, layout);  
    }  
  
    @Override  
    public void append(LogEvent event) {  
        // 在這里獲取日志信息  
        String message = event.getMessage().getFormattedMessage();  
        // 打印日志信息  
        System.out.println("攔截到的消息" + message);  
    }  
  
    @PluginFactory  
    public static CustomAppender createAppender(@PluginAttribute("name") String name,  
                                                @PluginElement("Layout") Layout<? extends Serializable> layout) {  
        if (name == null) {  
            throw new IllegalArgumentException("No name provided for CustomAppender");  
        }  
        if (layout == null) {  
            layout = PatternLayout.createDefaultLayout();  
        }  
        return new CustomAppender(name, null, layout);  
    }  
}

將自定義 Appender 配置到 Log4j 配置文件中

<?xml version="1.0" encoding="UTF-8"?>  
<!--monitorInterval:Log4j能夠自動(dòng)檢測(cè)修改配置 文件和重新配置本身,設(shè)置間隔秒數(shù)-->  
<configuration monitorInterval="60">  
    <Properties>  
        <property name="LOG_PATTERN_CONSOLE"  
                  value="%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n%xwEx"/>  
    </Properties>  
  
    <appenders>  
	    <!-- 添加自定義的 Appender -->  
        <CusAppender name="CustomAppender" />  
        <!-- Console 是將日志信息打印打控制臺(tái)-->  
        <console name="Console" target="SYSTEM_OUT">  
            <PatternLayout pattern="${LOG_PATTERN_CONSOLE}"/>  
            <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>  
        </console>  
    </appenders>  
  
    <loggers>  
        <!-- 對(duì)某個(gè)具體類進(jìn)行單獨(dú)的配置, 需要關(guān)注 additivity 參數(shù)-->  
        <Logger name="com.example.DemoService2" level="info" additivity="true">  
            <AppenderRef ref="CustomAppender"/>  
        </Logger>  
  
        <root level="info">  
            <AppenderRef ref="Console"/>  
        </root>  
    </loggers>  
  
</configuration>

上述配置文件針對(duì)原始配置文件主要有兩個(gè)修改點(diǎn)

  • <appenders> 標(biāo)簽下面添加了 <CusAppender name="CustomAppender" /> 標(biāo)簽, 這里使用 CusAppender 標(biāo)簽是因?yàn)?@Plugin(name = "CusAppender" 中配置的是這個(gè)名字
  • <loggers> 標(biāo)簽下添加了如下內(nèi)容
<!-- 對(duì)某個(gè)具體類進(jìn)行單獨(dú)的配置, 需要關(guān)注 additivity 參數(shù)-->  
<Logger name="com.example.DemoService2" level="info" additivity="true">  
	<AppenderRef ref="CustomAppender"/>  
</Logger>  

通過這種方式,當(dāng) DemoService2 類有日志打印并且級(jí)別在 info 及以上時(shí)就會(huì)調(diào)用到自定義 Appender 的 append 方法中

public void append(LogEvent event) {  
        // 在這里獲取日志信息  
	String message = event.getMessage().getFormattedMessage();  
	// 打印日志信息  
	System.out.println("攔截到的消息" + message);  
}  

additivity="true" 配置的作用

先看下 loggers 配置

<loggers>  
	<!-- 對(duì)某個(gè)具體類進(jìn)行單獨(dú)的配置, 需要關(guān)注 additivity 參數(shù)-->  
	<Logger name="com.example.DemoService2" level="info" additivity="true">  
		<AppenderRef ref="CustomAppender"/>  
	</Logger>  

	<root level="info">  
		<AppenderRef ref="Console"/>  
	</root>  
</loggers>  

這里的 root 就是頂層的配置,對(duì)于 DemoService2 類來說,因?yàn)閱为?dú)配置了 Logger, 所以會(huì)先走單獨(dú)配置的 Logger 中的 Appender, 也就是 CustomAppender,但是 CustomAppender 中只是獲取日志信息,并沒有往控制臺(tái)或者文件寫日志,這樣日志就會(huì)丟失了,additivity 參數(shù)就是用來控制是否繼續(xù)使用父級(jí)的 Appender, additivity=true 時(shí),日志會(huì)先經(jīng)過 CustomAppender 處理,然后會(huì)讓父級(jí)( root ) 的 Console 處理。

結(jié)果

先調(diào)用 DemoService2 方法,然后調(diào)用 DemoService 的方法,日志打印如下

攔截到的消息test demo 2
2024-02-05 16:48:21.641  INFO 2760 --- [command-execute] c.e.DemoService2                         : test demo 2
2024-02-05 16:48:34.424  INFO 2760 --- [command-execute] c.e.DemoService                          : test demo

說明只有調(diào)用了 DemoService2 類中日志方法時(shí)才會(huì)調(diào)用到自定義的 Appender 中

以上就是自定義log4j2中的Appender來獲取日志內(nèi)容的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于自定義Appender獲取日志內(nèi)容的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring boot中PropertySource注解的使用方法詳解

    Spring boot中PropertySource注解的使用方法詳解

    這篇文章主要給大家介紹了關(guān)于Spring boot中PropertySource注解的使用方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • Spring MVC下 bootStrap服務(wù)器分頁代碼

    Spring MVC下 bootStrap服務(wù)器分頁代碼

    因?yàn)镾pring 對(duì)于ajax直接返回對(duì)象,到了WEB頁面就轉(zhuǎn)換成json 所以不需要使用JSON轉(zhuǎn)換封裝可以直接使用。接下來通過本文給大家分享Spring MVC下 bootStrap服務(wù)器分頁代碼,需要的的朋友參考下
    2017-03-03
  • Maven之導(dǎo)入thymeleaf依賴飄紅問題及解決

    Maven之導(dǎo)入thymeleaf依賴飄紅問題及解決

    這篇文章主要介紹了Maven之導(dǎo)入thymeleaf依賴飄紅問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • spring boot參數(shù)驗(yàn)證注解@NotNull、@NotBlank和@NotEmpty區(qū)別解析

    spring boot參數(shù)驗(yàn)證注解@NotNull、@NotBlank和@NotEmpty區(qū)別解析

    使用spring boot參數(shù)驗(yàn)證是常常會(huì)使用@NotNull、@NotBlank和@NotEmpty三個(gè)判斷是否不為空的注解,中文都有不能為空的意思,大部分使用者都傻傻分清它們之間到底有什么區(qū)別,今天就讓咱們來一起探索它們之間的不同吧,感興趣的朋友一起看看吧
    2024-05-05
  • Spring中如何自定義監(jiān)聽器

    Spring中如何自定義監(jiān)聽器

    這篇文章將通過一個(gè)簡(jiǎn)單的自定義的監(jiān)聽器,從源碼的角度分析一下Spring中監(jiān)聽的整個(gè)過程,分析監(jiān)聽的作用,感興趣的小伙伴可以了解一下
    2024-11-11
  • Spring事務(wù)@Transactional失效的8大場(chǎng)景與解決方法

    Spring事務(wù)@Transactional失效的8大場(chǎng)景與解決方法

    在我們開發(fā)Spring Boot應(yīng)用中,很多小伙伴以為只要在方法上加一個(gè) @Transactional,但實(shí)際開發(fā)中,事務(wù)經(jīng)常出現(xiàn)失效的情況,下面我們就來看看如何解決吧
    2025-08-08
  • Java基礎(chǔ)知識(shí)精選 你答對(duì)了幾道?

    Java基礎(chǔ)知識(shí)精選 你答對(duì)了幾道?

    精選Java基礎(chǔ)知識(shí)講解,看看你能答對(duì)多少?
    2017-09-09
  • MyBatis-Plus Generator配置詳解

    MyBatis-Plus Generator配置詳解

    這篇文章主要介紹了MyBatis-Plus Generator配置詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Java實(shí)現(xiàn)將Word文檔轉(zhuǎn)換為圖像(JPEG,PNG或SVG)

    Java實(shí)現(xiàn)將Word文檔轉(zhuǎn)換為圖像(JPEG,PNG或SVG)

    在現(xiàn)代企業(yè)應(yīng)用開發(fā)中,文檔轉(zhuǎn)換是一個(gè)頻繁且必不可少的任務(wù),在本文中,我們將探討如何使用Java編程將Word文檔轉(zhuǎn)換為多種圖像格式,感興趣的小伙伴可以了解下
    2026-05-05
  • Java volatile的幾種使用場(chǎng)景分析

    Java volatile的幾種使用場(chǎng)景分析

    volatile 是一種輕量級(jí)的同步機(jī)制,它能保證共享變量的可見性,同時(shí)禁止重排序保證了操作的有序性,但是它無法保證原子性,本文給大家總結(jié)了Java olatile的使用場(chǎng)景有哪些,并通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2024-03-03

最新評(píng)論

福泉市| 邵阳市| 衡南县| 昭通市| 肇庆市| 桦甸市| 甘谷县| 浦江县| 沁源县| 大冶市| 建瓯市| 馆陶县| 临沭县| 江北区| 鄂州市| 东宁县| 望谟县| 绍兴市| 昌邑市| 大关县| 灵宝市| 商都县| 永城市| 屏东县| 芦溪县| 米泉市| 徐闻县| 札达县| 休宁县| 郴州市| 永康市| 合肥市| 阳山县| 唐河县| 沈丘县| 龙山县| 汉源县| 金塔县| 调兵山市| 遂溪县| 铜梁县|