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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在log4j2中创建自定义Appender?相关的知识,希望对你有一定的参考价值。

正如在这个链接中讨论的:qazxsw poi

为了在log4j 1.x中创建自定义appender,我们必须扩展AppenderSkeleton类并实现其append方法。

类似地,我们如何在log4j2中创建自定义appender,因为我们没有扩展AppenderSkelton类,所有其他appender扩展AppenderBase类。

答案

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

在log4j2中,您将为此创建一个插件。手册中有一个自定义appender示例的解释:How to create a own Appender in log4j?

扩展http://logging.apache.org/log4j/2.x/manual/extending.html#Appenders可能很方便,但这不是必需的。

当您使用org.apache.logging.log4j.core.appender.AbstractAppender注释自定义Appender类时,插件名称将成为配置元素名称,因此使用自定义appender的配置将如下所示:

@Plugin(name="MyCustomAppender", ....

请注意,配置中的<Configuration packages="com.yourcompany.yourcustomappenderpackage"> <Appenders> <MyCustomAppender name="ABC" otherAttribute="..."> ... </Appenders> <Loggers><Root><AppenderRef ref="ABC" /></Root></Loggers> </Configuration> 属性是包含自定义log4j2插件的所有包的逗号分隔列表。 Log4j2将在类路径中搜索这些包,注释用@Plugin注释的类。

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

packages

有关插件的更多详细信息: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); } }

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

另一答案

看起来插件appender在启动时被扫描,并且在运行时无法添加。真的吗?

在运行时添加新的appender可以使用monitorInterval属性来更新日志配置,即每60秒:

http://logging.apache.org/log4j/2.x/manual/plugins.html
另一答案

对于需要输出到TextArea的人来说,这是一个有效的调整

使TextArea静态

<Configuration monitorInterval="60">

在Frame中添加静态方法

NetBeans Swing TextArea is not static, causes trouble

打电话给Appender的追加

public class MyFrame extends javax.swing.JFrame {
    ...
    public static void outputToTextArea(String message) {
        jTextArea.append(message);
    }
另一答案

正如您所指出的,AppenderSkeleton不再可用,因此@Override public void append(LogEvent event) { final byte[] bytes = getLayout().toByteArray(event); MyFrame.outputToTextArea(new String(bytes)); } 中的解决方案将无效。

如果您期望多个日志消息,则使用Mockito或类似的库来创建带有ArgumentCaptor的Appender将无法工作,因为MutableLogEvent会在多个日志消息上重用。

我在log4j2中找到的最通用的解决方案是提供一个记录所有消息的模拟实现。它不需要任何其他库,如Mockito或JMockit。

How to create my own Appender in log4j?

以上是关于如何在log4j2中创建自定义Appender?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 laravel 中创建自定义关系?

如何在 QML 中创建自定义对象?

2019-07-03 log4j2 自定义ElasticSearch Appender

如何在 Facebook SDK 中创建自定义分享按钮

如何在 WordPress 中创建自定义表单?

如何在 React Native 中创建自定义日历?