Source Code for Apache Log4j NoSQL Appenders

Apache Log4j NoSQL Appenders allows applications to send events to NoSQL repositories. To use it, you need both the log4j-nosql as well as the appropriate driver for your NoSQL database type.

Bytecode (Java 8) for Apache Log4j NoSQL Appenders is provided in a separate JAR file like log4j-nosql-2.3.jar.

Source Code files for Apache Log4j NoSQL Appenders are provided in both binary packge like and source package like You can download them at Apache Log4j Website.

You can also browse Source Code files for Apache Log4j NoSQL Appenders 2.3 below.



 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache license, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * See the license for the specific language governing permissions and
 * limitations under the license.
package org.apache.logging.log4j.nosql.appender;

import java.util.Map;

import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AppenderLoggingException;
import org.apache.logging.log4j.core.appender.ManagerFactory;
import org.apache.logging.log4j.core.appender.db.AbstractDatabaseManager;
import org.apache.logging.log4j.core.util.Closer;

 * An {@link AbstractDatabaseManager} implementation for all NoSQL databases.
 * @param <W> A type parameter for reassuring the compiler that all operations are using the same {@link NoSqlObject}.
public final class NoSqlDatabaseManager<W> extends AbstractDatabaseManager {
    private static final NoSQLDatabaseManagerFactory FACTORY = new NoSQLDatabaseManagerFactory();

    private final NoSqlProvider<NoSqlConnection<W, ? extends NoSqlObject<W>>> provider;

    private NoSqlConnection<W, ? extends NoSqlObject<W>> connection;

    private NoSqlDatabaseManager(final String name, final int bufferSize,
            final NoSqlProvider<NoSqlConnection<W, ? extends NoSqlObject<W>>> provider) {
        super(name, bufferSize);
        this.provider = provider;

    protected void startupInternal() {
        // nothing to see here

    protected void shutdownInternal() {
        // NoSQL doesn't use transactions, so all we need to do here is simply close the client

    protected void connectAndStart() {
        try {
            this.connection = this.provider.getConnection();
        } catch (final Exception e) {
            throw new AppenderLoggingException("Failed to get connection from NoSQL connection provider.", e);

    protected void writeInternal(final LogEvent event) {
        if (!this.isRunning() || this.connection == null || this.connection.isClosed()) {
            throw new AppenderLoggingException(
                    "Cannot write logging event; NoSQL manager not connected to the database.");

        final NoSqlObject<W> entity = this.connection.createObject();
        entity.set("level", event.getLevel());
        entity.set("loggerName", event.getLoggerName());
        entity.set("message", event.getMessage() == null ? null : event.getMessage().getFormattedMessage());

        final StackTraceElement source = event.getSource();
        if (source == null) {
            entity.set("source", (Object) null);
        } else {
            entity.set("source", this.convertStackTraceElement(source));

        final Marker marker = event.getMarker();
        if (marker == null) {
            entity.set("marker", (Object) null);
        } else {
            entity.set("marker", buildMarkerEntity(marker));

        entity.set("threadName", event.getThreadName());
        entity.set("millis", event.getTimeMillis());
        entity.set("date", new java.util.Date(event.getTimeMillis()));

        Throwable thrown = event.getThrown();
        if (thrown == null) {
            entity.set("thrown", (Object) null);
        } else {
            final NoSqlObject<W> originalExceptionEntity = this.connection.createObject();
            NoSqlObject<W> exceptionEntity = originalExceptionEntity;
            exceptionEntity.set("type", thrown.getClass().getName());
            exceptionEntity.set("message", thrown.getMessage());
            exceptionEntity.set("stackTrace", this.convertStackTrace(thrown.getStackTrace()));
            while (thrown.getCause() != null) {
                thrown = thrown.getCause();
                final NoSqlObject<W> causingExceptionEntity = this.connection.createObject();
                causingExceptionEntity.set("type", thrown.getClass().getName());
                causingExceptionEntity.set("message", thrown.getMessage());
                causingExceptionEntity.set("stackTrace", this.convertStackTrace(thrown.getStackTrace()));
                exceptionEntity.set("cause", causingExceptionEntity);
                exceptionEntity = causingExceptionEntity;

            entity.set("thrown", originalExceptionEntity);

        final Map<String, String> contextMap = event.getContextMap();
        if (contextMap == null) {
            entity.set("contextMap", (Object) null);
        } else {
            final NoSqlObject<W> contextMapEntity = this.connection.createObject();
            for (final Map.Entry<String, String> entry : contextMap.entrySet()) {
                contextMapEntity.set(entry.getKey(), entry.getValue());
            entity.set("contextMap", contextMapEntity);

        final ThreadContext.ContextStack contextStack = event.getContextStack();
        if (contextStack == null) {
            entity.set("contextStack", (Object) null);
        } else {
            entity.set("contextStack", contextStack.asList().toArray());


    private NoSqlObject<W> buildMarkerEntity(final Marker marker) {
        final NoSqlObject<W> entity = this.connection.createObject();
        entity.set("name", marker.getName());

        final Marker[] parents = marker.getParents();
        if (parents != null) {
            final NoSqlObject<W>[] parentEntities = new NoSqlObject[parents.length];
            for (int i = 0; i < parents.length; i++) {
                parentEntities[i] = buildMarkerEntity(parents[i]);
            entity.set("parents", parentEntities);
        return entity;

    protected void commitAndClose() {
        // all NoSQL drivers auto-commit (since NoSQL doesn't generally use the concept of transactions).
        // also, all our NoSQL drivers use internal connection pooling and provide clients, not connections.
        // thus, we should not be closing the client until shutdown as NoSQL is very different from SQL.
        // see LOG4J2-591 and LOG4J2-676

    private NoSqlObject<W>[] convertStackTrace(final StackTraceElement[] stackTrace) {
        final NoSqlObject<W>[] stackTraceEntities = this.connection.createList(stackTrace.length);
        for (int i = 0; i < stackTrace.length; i++) {
            stackTraceEntities[i] = this.convertStackTraceElement(stackTrace[i]);
        return stackTraceEntities;

    private NoSqlObject<W> convertStackTraceElement(final StackTraceElement element) {
        final NoSqlObject<W> elementEntity = this.connection.createObject();
        elementEntity.set("className", element.getClassName());
        elementEntity.set("methodName", element.getMethodName());
        elementEntity.set("fileName", element.getFileName());
        elementEntity.set("lineNumber", element.getLineNumber());
        return elementEntity;

     * Creates a NoSQL manager for use within the {@link NoSqlAppender}, or returns a suitable one if it already exists.
     * @param name The name of the manager, which should include connection details and hashed passwords where possible.
     * @param bufferSize The size of the log event buffer.
     * @param provider A provider instance which will be used to obtain connections to the chosen NoSQL database.
     * @return a new or existing NoSQL manager as applicable.
    public static NoSqlDatabaseManager<?> getNoSqlDatabaseManager(final String name, final int bufferSize,
                                                                  final NoSqlProvider<?> provider) {
        return AbstractDatabaseManager.getManager(name, new FactoryData(bufferSize, provider), FACTORY);

     * Encapsulates data that {@link NoSQLDatabaseManagerFactory} uses to create managers.
    private static final class FactoryData extends AbstractDatabaseManager.AbstractFactoryData {
        private final NoSqlProvider<?> provider;

        protected FactoryData(final int bufferSize, final NoSqlProvider<?> provider) {
            this.provider = provider;

     * Creates managers.
    private static final class NoSQLDatabaseManagerFactory implements
            ManagerFactory<NoSqlDatabaseManager<?>, FactoryData> {
        public NoSqlDatabaseManager<?> createManager(final String name, final FactoryData data) {
            return new NoSqlDatabaseManager(name, data.getBufferSize(), data.provider);



⇒ Downloading Apache Log4j 2.4.1 Package

⇐ Source Code for Apache Log4j JMX GUI

⇑ Downloading and Reviewing Apache Log4j Packages

⇑⇑ FAQ for Apache Log4j

2015-11-04, 7934👍, 0💬