如何在log4j2中创build一个自定义Appender?

正如在这个链接中讨论: 如何在log4j中创build一个自己的Appender?

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

同样,我们如何创build一个自定义appender在log4j2因为我们没有AppenderSkelton类来扩展和所有其他appender扩展AppenderBase类。

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

在log4j2中,你会为此创build一个插件。 手册中有一个自定义appender例子的解释: http : //logging.apache.org/log4j/2.x/manual/extending.html#Appenders

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

当你使用@Plugin(name="MyCustomAppender", .... )为自定义的Appender类注解时,插件名变成了configuration元素名,所以你的自定义appender的configuration将如下所示:

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

请注意,configuration中的packages属性是所有包含自定义log4j2插件的包的逗号分隔列表。 Log4j2将在类path中search这些包中用@Plugin注释的类。

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

 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

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

它看起来像插件appender在启动时扫描,不能在运行时添加。 真的吗?

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

  <Configuration monitorInterval="60"> 

AppenderSkeleton类包含在org.apache.log4j.jar中,您必须将此jar作为依赖添加到您的项目中。