All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vicrab.log4j2.VicrabAppender Maven / Gradle / Ivy

There is a newer version: 1.2.1
Show newest version
package com.vicrab.log4j2;

import com.vicrab.Vicrab;
import com.vicrab.environment.VicrabEnvironment;
import com.vicrab.event.Event;
import com.vicrab.event.EventBuilder;
import com.vicrab.event.interfaces.ExceptionInterface;
import com.vicrab.event.interfaces.MessageInterface;
import com.vicrab.event.interfaces.StackTraceInterface;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.filter.AbstractFilter;
import org.apache.logging.log4j.message.Message;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Appender for log4j2 in charge of sending the logged events to a Vicrab server.
 */
@Plugin(name = "Vicrab", category = "Core", elementType = "appender", printObject = true)
public class VicrabAppender extends AbstractAppender {
    /**
     * Default name for the appender.
     */
    public static final String APPENDER_NAME = "vicrab";
    /**
     * Name of the {@link Event#extra} property containing NDC details.
     */
    public static final String LOG4J_NDC = "log4j2-NDC";
    /**
     * Name of the {@link Event#extra} property containing Marker details.
     */
    public static final String LOG4J_MARKER = "log4j2-Marker";
    /**
     * Name of the {@link Event#extra} property containing the Thread name.
     */
    public static final String THREAD_NAME = "Vicrab-Threadname";

    /**
     * Creates an instance of VicrabAppender.
     */
    public VicrabAppender() {
        this(APPENDER_NAME, null);
    }

    /**
     * Creates an instance of VicrabAppender.
     *
     * @param name The Appender name.
     * @param filter The Filter to associate with the Appender.
     */
    protected VicrabAppender(String name, Filter filter) {
        super(name, filter, null, true);
        this.addFilter(new DropVicrabFilter());
    }

    /**
     * Create a Vicrab Appender.
     *
     * @param name                The name of the Appender.
     * @param filter              The filter, if any, to use.
     * @return The VicrabAppender.
     */
    @PluginFactory
    @SuppressWarnings("checkstyle:parameternumber")
    public static VicrabAppender createAppender(@PluginAttribute("name") final String name,
                                                @PluginElement("filter") final Filter filter) {

        if (name == null) {
            LOGGER.error("No name provided for VicrabAppender");
            return null;
        }
        return new VicrabAppender(name, filter);
    }

    /**
     * Transforms a {@link Level} into an {@link Event.Level}.
     *
     * @param level original level as defined in log4j2.
     * @return log level used within vicrab.
     */
    protected static Event.Level formatLevel(Level level) {
        if (level.isMoreSpecificThan(Level.FATAL)) {
            return Event.Level.FATAL;
        } else if (level.isMoreSpecificThan(Level.ERROR)) {
            return Event.Level.ERROR;
        } else if (level.isMoreSpecificThan(Level.WARN)) {
            return Event.Level.WARNING;
        } else if (level.isMoreSpecificThan(Level.INFO)) {
            return Event.Level.INFO;
        } else {
            return Event.Level.DEBUG;
        }
    }

    /**
     * Extracts message parameters into a List of Strings.
     * 

* null parameters are kept as null. * * @param parameters parameters provided to the logging system. * @return the parameters formatted as Strings in a List. */ protected static List formatMessageParameters(Object[] parameters) { List stringParameters = new ArrayList<>(parameters.length); for (Object parameter : parameters) { stringParameters.add((parameter != null) ? parameter.toString() : null); } return stringParameters; } @Override public void append(LogEvent logEvent) { // Do not log the event if the current thread is managed by vicrab if (VicrabEnvironment.isManagingThread()) { return; } VicrabEnvironment.startManagingThread(); try { EventBuilder eventBuilder = createEventBuilder(logEvent); Vicrab.capture(eventBuilder); } catch (Exception e) { error("An exception occurred while creating a new event in Vicrab", logEvent, e); } finally { VicrabEnvironment.stopManagingThread(); } } /** * Builds an EventBuilder based on the logging event. * * @param event Log generated. * @return EventBuilder containing details provided by the logging system. */ protected EventBuilder createEventBuilder(LogEvent event) { Message eventMessage = event.getMessage(); EventBuilder eventBuilder = new EventBuilder() .withSdkIntegration("log4j2") .withTimestamp(new Date(event.getTimeMillis())) .withMessage(eventMessage.getFormattedMessage()) .withLogger(event.getLoggerName()) .withLevel(formatLevel(event.getLevel())) .withExtra(THREAD_NAME, event.getThreadName()); if (eventMessage.getFormat() != null && !eventMessage.getFormat().equals("") && !eventMessage.getFormattedMessage().equals(eventMessage.getFormat())) { eventBuilder.withVicrabInterface(new MessageInterface( eventMessage.getFormat(), formatMessageParameters(eventMessage.getParameters()), eventMessage.getFormattedMessage())); } Throwable throwable = event.getThrown(); if (throwable != null) { eventBuilder.withVicrabInterface(new ExceptionInterface(throwable)); } else if (event.getSource() != null) { StackTraceElement[] stackTrace = {event.getSource()}; eventBuilder.withVicrabInterface(new StackTraceInterface(stackTrace)); } if (event.getContextStack() != null) { eventBuilder.withExtra(LOG4J_NDC, event.getContextStack().asList()); } if (event.getContextMap() != null) { for (Map.Entry contextEntry : event.getContextMap().entrySet()) { if (Vicrab.getStoredClient().getMdcTags().contains(contextEntry.getKey())) { eventBuilder.withTag(contextEntry.getKey(), contextEntry.getValue()); } else { eventBuilder.withExtra(contextEntry.getKey(), contextEntry.getValue()); } } } if (event.getMarker() != null) { eventBuilder.withTag(LOG4J_MARKER, event.getMarker().getName()); } return eventBuilder; } @Override public void stop() { VicrabEnvironment.startManagingThread(); try { if (!isStarted()) { return; } super.stop(); Vicrab.close(); } catch (Exception e) { error("An exception occurred while closing the Vicrab connection", e); } finally { VicrabEnvironment.stopManagingThread(); } } private class DropVicrabFilter extends AbstractFilter { @Override public Result filter(Logger logger, Level level, Marker marker, String msg, Object... params) { return filter(logger.getName()); } @Override public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) { return filter(logger.getName()); } @Override public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) { return filter(logger.getName()); } @Override public Result filter(LogEvent event) { return filter(event.getLoggerName()); } private Result filter(String loggerName) { if (loggerName != null && loggerName.startsWith("com.vicrab")) { return Result.DENY; } return Result.NEUTRAL; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy