欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

自定義log4j2中的Appender來獲取日志內容的示例代碼

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

springboot版本:2.6.15 log4j版本:2.17.2

Log4j中的Appender 是什么

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

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

需求背景

有兩個系統(tǒng),系統(tǒng) A 和系統(tǒng) B, 系統(tǒng) A 會發(fā)送指令給系統(tǒng) B, 系統(tǒng) B 會響應結果給系統(tǒng) A,這兩個系統(tǒng)之間的通信方式是 MQ, 即 A 通過 MQ 發(fā)送數據給 B(數據中有 UUID 字段值),系統(tǒng) B處理完成后將結果通過 MQ 發(fā)送給 A,請求和響應的對應關系則可以通過 UUID 來進行匹配

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

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

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

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

修改前測試代碼

log4j2 配置文件

下面 log4j2-dev.xml 配置文件很簡單,就是將所有日志打印到控制臺,日志級別為 info

<?xml version="1.0" encoding="UTF-8"?>  
<!--monitorInterval:Log4j能夠自動檢測修改配置 文件和重新配置本身,設置間隔秒數-->  
<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 是將日志信息打印打控制臺-->  
        <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>

兩個測試類代碼

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

@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能夠自動檢測修改配置 文件和重新配置本身,設置間隔秒數-->  
<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 是將日志信息打印打控制臺-->  
        <console name="Console" target="SYSTEM_OUT">  
            <PatternLayout pattern="${LOG_PATTERN_CONSOLE}"/>  
            <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>  
        </console>  
    </appenders>  
  
    <loggers>  
        <!-- 對某個具體類進行單獨的配置, 需要關注 additivity 參數-->  
        <Logger name="com.example.DemoService2" level="info" additivity="true">  
            <AppenderRef ref="CustomAppender"/>  
        </Logger>  
  
        <root level="info">  
            <AppenderRef ref="Console"/>  
        </root>  
    </loggers>  
  
</configuration>

上述配置文件針對原始配置文件主要有兩個修改點

  • <appenders> 標簽下面添加了 <CusAppender name="CustomAppender" /> 標簽, 這里使用 CusAppender 標簽是因為 @Plugin(name = "CusAppender" 中配置的是這個名字
  • <loggers> 標簽下添加了如下內容
<!-- 對某個具體類進行單獨的配置, 需要關注 additivity 參數-->  
<Logger name="com.example.DemoService2" level="info" additivity="true">  
	<AppenderRef ref="CustomAppender"/>  
</Logger>  

通過這種方式,當 DemoService2 類有日志打印并且級別在 info 及以上時就會調用到自定義 Appender 的 append 方法中

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

additivity="true" 配置的作用

先看下 loggers 配置

<loggers>  
	<!-- 對某個具體類進行單獨的配置, 需要關注 additivity 參數-->  
	<Logger name="com.example.DemoService2" level="info" additivity="true">  
		<AppenderRef ref="CustomAppender"/>  
	</Logger>  

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

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

結果

先調用 DemoService2 方法,然后調用 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

說明只有調用了 DemoService2 類中日志方法時才會調用到自定義的 Appender 中

以上就是自定義log4j2中的Appender來獲取日志內容的示例代碼的詳細內容,更多關于自定義Appender獲取日志內容的資料請關注腳本之家其它相關文章!

相關文章

  • Spring Boot應用Docker化的步驟詳解

    Spring Boot應用Docker化的步驟詳解

    這篇文章主要給大家介紹了關于Spring Boot應用Docker化的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2018-04-04
  • protobuf簡介及使用流程

    protobuf簡介及使用流程

    本文介紹了Protocol Buffers(protobuf)的數據結構序列化和反序列化框架,包括其特點、使用流程和快速上手,通過一個簡單的通訊錄示例,展示了如何創(chuàng)建.proto文件、添加注釋、編寫消息定義、編譯.proto文件以及進行序列化和反序列化操作,感興趣的朋友一起看看吧
    2025-02-02
  • Java Object定義三個點實現(xiàn)代碼

    Java Object定義三個點實現(xiàn)代碼

    這篇文章主要介紹了Java Object定義三個點實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-09-09
  • Java多線程下載的實現(xiàn)方法

    Java多線程下載的實現(xiàn)方法

    復習多線程的時候,練習了下,順便記錄一下:
    2013-03-03
  • Lombok不生效,提示java:?找不到符號的解決方案

    Lombok不生效,提示java:?找不到符號的解決方案

    這篇文章主要介紹了Lombok不生效,提示java:?找不到符號的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 記一次集成swagger2(Knife4j)在線文檔提示:Knude4j文檔請求異常的解決辦法

    記一次集成swagger2(Knife4j)在線文檔提示:Knude4j文檔請求異常的解決辦法

    Knife4j是一個集Swagger2 和 OpenAPI3為一體的增強解決方案,下面這篇文章主要給大家介紹了關于一次集成swagger2(Knife4j)在線文檔提示:Knude4j文檔請求異常的解決辦法,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-02-02
  • SpringBoot在idea中的 .idea和 .iml文件的作用

    SpringBoot在idea中的 .idea和 .iml文件的作用

    本文主要介紹了SpringBoot在idea中的 .idea和 .iml文件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-08-08
  • spring boot 自動更新靜態(tài)文件和后臺代碼的實例

    spring boot 自動更新靜態(tài)文件和后臺代碼的實例

    下面小編就為大家分享一篇spring boot 自動更新靜態(tài)文件和后臺代碼的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • Java中的StringTokenizer實現(xiàn)字符串切割詳解

    Java中的StringTokenizer實現(xiàn)字符串切割詳解

    這篇文章主要介紹了Java中的StringTokenizer實現(xiàn)字符串切割詳解,java.util工具包提供了字符串切割的工具類StringTokenizer,Spring等常見框架的字符串工具類(如Spring的StringUtils),需要的朋友可以參考下
    2024-01-01
  • Java將對象保存到文件中/從文件中讀取對象的方法

    Java將對象保存到文件中/從文件中讀取對象的方法

    下面小編就為大家?guī)硪黄狫ava將對象保存到文件中/從文件中讀取對象的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12

最新評論