log4j2中的自定义Appender详解

该博客介绍了如何在Log4j2中创建自定义Appender,以将日志信息发送到Dubbo服务。通过继承AbstractAppender并重写append方法,实现了接收日志并调用Dubbo接口进行处理的功能。同时,详细展示了代码实现和log4j2.xml配置文件的修改,包括设置应用名称、连接注册中心、创建Dubbo引用等步骤。此外,还给出了必要的Maven依赖和配置文件示例。
摘要由CSDN通过智能技术生成

log4j官网提供了很多Appender组件,但是当那些组键不满足日志收集的时候,我们需要自己定义Appender

定点Appender需要处理好两个地方的问题
1.需要在代码中写一个自定义Appender
2.修改log4j.xml文件中的Appenders下面引用的Appender为自定义appender

首先是代码实现主要是继承AbstractAppender这个抽象类,重写append()方法
append方法是我们进行接收日志的方法

  @Override
    public void append(LogEvent logEvent) {
        final byte[] bytes = getLayout().toByteArray(logEvent);
        String  log= new String(bytes);
        doLog(log,genericService);
    }
1
2
3
4
5
6
createAppender
这个方法可以用来接收log4j.xml的传参数,可以自行添加接收,和log4j.xml 中传参数对应上就行

 @PluginFactory
    public static LogAreaAppender createAppender(
            @PluginAttribute("name") String name, @PluginElement("Filter") final Filter filter,
            @PluginElement("Layout") Layout<? extends Serializable> layout, @PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
            @PluginAttribute("registryAddress") String registryAddress,
            @PluginAttribute("registryProtocol") String registryProtocol,
            @PluginAttribute("namespace") String namespace,
            @PluginAttribute("protocolName") String protocolName,
            @PluginAttribute("consumerGroup") String consumerGroup
    ) {
        if (name == null) {
            LOGGER.error("No name provided for MyCustomAppenderImpl");
            return null;
        }
        if (layout == null) {
            layout = PatternLayout.createDefaultLayout();
        }
        return new LogAreaAppender(name, filter, layout, ignoreExceptions,registryAddress,registryProtocol,namespace,protocolName,consumerGroup);
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
LogAreaAppender 构造方法可以用来初始化我们要进行用的保存日志的方式

 public LogAreaAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions,
                           String registryAddress, String registryProtocol, String namespace, String protocolName, String consumerGroup) {
        super(name, filter, layout, ignoreExceptions);
        createDubbo(registryAddress,registryProtocol,namespace,protocolName,consumerGroup);
    }
1
2
3
4
5
上代码实现dubbo的日志接口

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.rpc.service.GenericService;
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;
import java.util.HashMap;

@Slf4j
@Plugin(name = "LogAreaAppender", category = "Core", elementType = "appender", printObject = true)
public class LogAreaAppender extends AbstractAppender {


    GenericService genericService =null;
    //dubbo日志方法
    private String logMethodName = "saveLog";

    public LogAreaAppender(String name, Filter filter, Layout<? extends Serializable> layout, boolean ignoreExceptions,
                           String registryAddress, String registryProtocol, String namespace, String protocolName, String consumerGroup) {
        super(name, filter, layout, ignoreExceptions);
        createDubbo(registryAddress,registryProtocol,namespace,protocolName,consumerGroup);
    }

    @Override
    public void append(LogEvent logEvent) {
        final byte[] bytes = getLayout().toByteArray(logEvent);
        String  log= new String(bytes);
        doLog(log,genericService);
    }

    // 下面这个方法可以接收配置文件中的参数信息
    @PluginFactory
    public static LogAreaAppender createAppender(
            @PluginAttribute("name") String name, @PluginElement("Filter") final Filter filter,
            @PluginElement("Layout") Layout<? extends Serializable> layout, @PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
            @PluginAttribute("registryAddress") String registryAddress,
            @PluginAttribute("registryProtocol") String registryProtocol,
            @PluginAttribute("namespace") String namespace,
            @PluginAttribute("protocolName") String protocolName,
            @PluginAttribute("consumerGroup") String consumerGroup
    ) {
        if (name == null) {
            LOGGER.error("No name provided for MyCustomAppenderImpl");
            return null;
        }
        if (layout == null) {
            layout = PatternLayout.createDefaultLayout();
        }
        return new LogAreaAppender(name, filter, layout, ignoreExceptions,registryAddress,registryProtocol,namespace,protocolName,consumerGroup);
    }

    private void createDubbo(String registryAddress ,String registryProtocolame,String namespace,String protocolName,String consumerGroup) {
        try {

            //设置应用名称
            ApplicationConfig applicationConfig = new ApplicationConfig();
            applicationConfig.setName("douc-rpc-dubbo");

            //连接注册中心
            RegistryConfig registryConfig = new RegistryConfig();
            registryConfig.setAddress(registryAddress);  //本地nacos
            registryConfig.setProtocol(registryProtocolame);  //本地nacos

            HashMap<String, String> registryNacosMap = new HashMap<>();
            registryNacosMap.put("namespace",namespace);
            registryConfig.setParameters(registryNacosMap);

            // reference remote service
            ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
            reference.setApplication(applicationConfig);
            reference.setRegistry(registryConfig);
            reference.setProtocol(protocolName);
            reference.setGroup(consumerGroup);
            reference.setVersion("1.0.0");
            reference.setTimeout(3000);
            reference.setInterface("com.cloudwise.douc.facade.LogDubboFacade");
            reference.setGeneric(true);
            genericService = reference.get();
            LOGGER.info("create client success");
        } catch (Exception e) {
            LOGGER.error("create file exception", e);
        }
    }

    /**
     * 执行dubbo接口
     * @param logInfo
     */
    public void doLog(String logInfo, GenericService genericService){
        log.info("dubbo----====-日志log---=====--入参:"+logInfo);
        genericService.$invoke(logMethodName, new String[]
                {"java.lang.String"}, new Object[]{logInfo});
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
log4j2.xml配置介绍

registryAddress nacos地址和 namespace 命名空间ID

<Configuration status="info" packages="com.zero.scribe.log4j2plugin">  
修改一 Appenders里面的
<Appenders>
 
<!-- 这个就是自定义的Appender -->
<LogAreaAppender name="LogAreaAppender" registryProtocol="nacos" registryAddress="10.0.2.102:8848"
 namespace = "douc-102" protocolName = "" consumerGroup = "DOUC_RPC_DUBBO" >
 <JsonLayout properties="true"/>
</LogAreaAppender>
  
  
修改2 将这个地方的 http的删掉 添加  LogAreaAppender 引用
<AsyncLogger name="operatorLogger"  level="INFO">
<!--            <appender-ref ref="httpAppender" level="INFO" />-->
            <appender-ref ref="LogAreaAppender"  level="INFO"/>
        </AsyncLogger>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
注: log4j2配置里面的的<LogAreaAppender name=“LogAreaAppender” 与java中的类对应上

需要的mavn依赖

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
————————————————
版权声明:本文为CSDN博主「langzilige」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/li646495946/article/details/112792605

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值