How to Create a Custom Appender in log4j2?
This works quite differently in log4j2 than in log4j-1.2.
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
It may be convenient to extend org.apache.logging.log4j.core.appender.AbstractAppender
, but this is not required.
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>
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.
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);
}
}
For more details on plugins:
http://logging.apache.org/log4j/2.x/manual/plugins.html
If the manual is not enough, it may be useful to look at the source code for the built-in appenders in log4j-core.
create a custom log4j2 rolling file appender
The RollingFileAppender
in Log4j 2.x is final
, so you can not extend it. However you can obtain the functionality of your custom Log4j 1.x appender using:
- A
RoutingAppender
, which can create appenders on demand, - Multiple
RollingFileAppender
that will write and rotate your files, - The
EventLookup
to retrieve the current thread name.
For a simple logfile-per-thread appender you can use:
<Routing name="Routing">
<Routes pattern="$${event:ThreadName}">
<Route>
<RollingFile name="Rolling-${event:ThreadName}"
fileName="logs/thread-${event:ThreadName}.log"
filePattern="logs/thread-${event:ThreadName}.log.%d{yyyy-MM-dd}">
<PatternLayout pattern="%d [%-5p] [%t] [%c{1}] [%M] - %m%n" />
<TimeBasedTriggeringPolicy />
</RollingFile>
</Route>
</Routes>
</Routing>
For a more complex configuration both the <Routing>
appender and the <Routes>
can contain a <Script>
(cf. documentation):
- the script in the
<Routing>
appender can initialize thestaticVariables
map and return a default route, - the script in the
<Routes>
component chooses the appropriate route based onstaticVariables
and the logging event.
How to setup a log4j2 custom appender with Spring Boot?
You have to add the package of your appender class in log4j.properties e.g.
packages = org.home.appenders
What is the preferred method for creating a custom appender in log4j2?
You need to put the package name (or names in a comma-separated list if multiple) in the packages
attribute of the Configuration
element of your log4j2.xml.
E.g.
<Configuration status="trace" packages="com.mycomp.myproject.appenders">
...
See the Log4j2 Configuration Documentation for more information.
Related Topics
Kafka - Unable to Send a Message to a Remote Server Using Java
What Does Statement.Setfetchsize(Nsize) Method Really Do in SQL Server Jdbc Driver
Generate All Combinations from Multiple Lists
Why Does the Jvm Consume Less Memory Than -Xms Specified
Java - Process.Destroy() Source Code for Linux
Java Program That Runs Commands with Linux Terminal
How to Install Intellij Idea on Ubuntu
How to Downsample Images Within PDF File
Start a Jar File Like Service in Linux
Error: Unable to Load Installed Packages Just Now
How to Make Rjava Use the Newer Version of Java on Osx
Lambdas: Local Variables Need Final, Instance Variables Don'T
Java: (String[])List.Toarray() Gives Classcastexception
Convert Rgb Values to Color Name