Create custom log4j appender for Karaf and Pax Logging

Karaf leverages Pax Logging for the logging layer. Pax Logging provides an abstraction service for most popular logging frameworks, like SLF4J, Log4j, commons-logging, etc.

Karaf provides a default logging configuration in etc/org.ops4j.pax.logging.cfg file.

By default, all INFO log messages (rootLogger) are send into a file appender (in data/log/karaf.log). The file appender “maintains” one file of 1MB, and store up to 10 backup files.

Adding a new appender configuration, example with Syslog appender

We can add new appender configuration in the Karaf logging module.

For instance, we can add a syslog appender in etc/org.ops4j.pax.logging.cfg:

log4j.rootLogger = INFO, out, syslog, osgi:*
# Syslog appender
log4j.appender.syslog.layout.ConversionPattern=[%p] %c:%L - %m%n

We create the syslog appender configuration, and we use this appender for the rootLogger.

Pax Logging provides all default Log4j appenders.

Creating a custom appender

It’s also possible to create your own appender.

For instance, you want to create MyJDBCAppender, extending the standard Log4J JDBCAppender. MyJDBCAppender has a better management of the quote in the SQL query for a DB2 backend for instance:


import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.jdbc.JDBCAppender;

* Override apache log4j JDBCAppender for DB2 use (escaping of ' char in data)
* Need proper substitution of the ' char by {@link SQL_APOS} in the writing of the log4j sql property
public class MyJDBCAppender extends JDBCAppender {

private static final String SQL_APOS = "{sql_apos}";
private static final String XML_APOS = "'";

/** {@inheritDoc} */
protected String getLogStatement(LoggingEvent event) {
String sqlLayout = getLayout().format(event);
// escape ' as standard sequence (') in the sql statement after layout
sqlLayout = sqlLayout.replace("'", XML_APOS);
// revert specific sequence as ' to have final executable sql statement
sqlLayout = sqlLayout.replace(SQL_APOS, "'");
return sqlLayout;


We put the MyJDBCAppender java file in a src/main/java/org/apache/karaf/blog/logging folder.

We package this appender as an OSGi bundle. This bundle is a fragment to the Pax Logging service bundle:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="" xmlns:xsi="" xsi:schemaLocation="">






We can use our appender in etc/org.ops4j.pax.logging.cfg file, for instance:

log4j.rootLogger = INFO, out, myappender, osgi:*
log4j.appender.myappender.sql=insert into logs values({{sql_apos}%x{sql_apos}, {sql_apos}%d{sql_apos}, {sql_apos}%C{sql_apos}, {sql_apos}%p{sql_apos}, {sql_apos}%m{sql_apos})

In order to be loading very early in the Karaf bootstrap, our appender bundle should be present in the system folder and defined in etc/

The system folder has a “Maven repo like” structure. So you have to copy with:


In our example, it means:

mkdir -p $KARAF_HOME/system/org/apache/karaf/blog/logging/appender
cp target/ $KARAF_HOME/system/org/apache/karaf/blog/logging/appender/

and in etc/, we define the appender bundle just after the pax-logging-service bundle:


You can now start Karaf, it will use our new custom appender.


Popular posts from this blog

My first days at Huawei

Apache Karaf and log4j2 appenders

What's new in Apache Karaf 4.2.11 ?