且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在 log4j2 中创建自定义 Appender?

更新时间:2023-01-10 16:19:23

这在 log4j2 中与在 log4j-1.2 中的工作方式完全不同.

This works quite differently in log4j2 than in log4j-1.2.

在 log4j2 中,您将为此创建一个插件.该手册对自定义附加程序的示例进行了说明:http://logging.apache.org/log4j/2.x/manual/extending.html#Appenders

In log4j2, you would create a plugin for this. The manual has an explanation with an example for a custom appender here: http://logging.apache.org/log4j/2.x/manual/extending.html#Appenders

扩展 org.apache.logging.log4j.core.appender.AbstractAppender 可能很方便,但这不是必需的.

It may be convenient to extend org.apache.logging.log4j.core.appender.AbstractAppender, but this is not required.

当您使用 @Plugin(name="MyCustomAppender", .... 注释自定义 Appender 类时,插件名称将成为配置元素名称,因此带有自定义 appender 的配置将看起来像这样:

When you annotate your custom Appender class with @Plugin(name="MyCustomAppender", ...., the plugin name becomes the configuration element name, so a configuration with your custom appender would then look like this:

<Configuration packages="com.yourcompany.yourcustomappenderpackage">
  <Appenders>
    <MyCustomAppender name="ABC" otherAttribute="...">
    ...
  </Appenders>
  <Loggers><Root><AppenderRef ref="ABC" /></Root></Loggers>
</Configuration>

请注意,配置中的 packages 属性是以逗号分隔的所有带有自定义 log4j2 插件的包的列表.Log4j2 将在类路径中搜索这些包中使用@Plugin 注释的类.

Note that the packages attribute on the configuration is a comma-separated list of all the packages with custom log4j2 plugins. Log4j2 will search these packages in the classpath for classes annotated with @Plugin.

这是打印到控制台的示例自定义 appender:

Here is a sample custom appender that prints to the console:

package com.yourcompany.yourcustomappenderpackage;

import java.io.Serializable;
import java.util.concurrent.locks.*;
import org.apache.logging.log4j.core.*;
import org.apache.logging.log4j.core.config.plugins.*;
import org.apache.logging.log4j.core.layout.PatternLayout;

// note: class name need not match the @Plugin name.
@Plugin(name="MyCustomAppender", category="Core", elementType="appender", printObject=true)
public final class MyCustomAppenderImpl extends AbstractAppender {

    private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final Lock readLock = rwLock.readLock();

    protected MyCustomAppenderImpl(String name, Filter filter,
            Layout<? extends Serializable> layout, final boolean ignoreExceptions) {
        super(name, filter, layout, ignoreExceptions);
    }

    // The append method is where the appender does the work.
    // Given a log event, you are free to do with it what you want.
    // This example demonstrates:
    // 1. Concurrency: this method may be called by multiple threads concurrently
    // 2. How to use layouts
    // 3. Error handling
    @Override
    public void append(LogEvent event) {
        readLock.lock();
        try {
            final byte[] bytes = getLayout().toByteArray(event);
            System.out.write(bytes);
        } catch (Exception ex) {
            if (!ignoreExceptions()) {
                throw new AppenderLoggingException(ex);
            }
        } finally {
            readLock.unlock();
        }
    }

    // Your custom appender needs to declare a factory method
    // annotated with `@PluginFactory`. Log4j will parse the configuration
    // and call this factory method to construct an appender instance with
    // the configured attributes.
    @PluginFactory
    public static MyCustomAppenderImpl createAppender(
            @PluginAttribute("name") String name,
            @PluginElement("Layout") Layout<? extends Serializable> layout,
            @PluginElement("Filter") final Filter filter,
            @PluginAttribute("otherAttribute") String otherAttribute) {
        if (name == null) {
            LOGGER.error("No name provided for MyCustomAppenderImpl");
            return null;
        }
        if (layout == null) {
            layout = PatternLayout.createDefaultLayout();
        }
        return new MyCustomAppenderImpl(name, filter, layout, true);
    }
}

有关插件的更多详细信息:http://logging.apache.org/log4j/2.x/manual/plugins.html

For more details on plugins: http://logging.apache.org/log4j/2.x/manual/plugins.html

如果手册不够,查看 log4j-core 中内置 appender 的源代码可能会有用.

If the manual is not enough, it may be useful to look at the source code for the built-in appenders in log4j-core.