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

com.addc.server.commons.tomcat.JuliLog4jEventFactory Maven / Gradle / Ivy

There is a newer version: 2.9
Show newest version
package com.addc.server.commons.tomcat;

import java.util.List;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.impl.DefaultLogEventFactory;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.message.Message;

import com.addc.commons.annotation.CoberturaIgnore;

/**
 * The JuliLog4jEventFactory supplies an event factory that modifies the source
 * method such that traces from tomcat do come out with the source class
 * org.apache.juli.logging.DirectJDKLog but with the correct source class name
 */
public class JuliLog4jEventFactory extends DefaultLogEventFactory {
    static final String JULI_LOG_NAME= "org.apache.juli.logging.DirectJDKLog";

    /**
     * The JuliLog4jEvent represents a log event generated from Juli in tomcat
     */
    public static class JuliLog4jEvent extends Log4jLogEvent {
        private static final long serialVersionUID= -6876090939767814360L;
        private StackTraceElement source;

        /**
         * Create a new JuliLogEvent
         */
        public JuliLog4jEvent() {
            super();
        }

        /**
         * Create a new JuliLogEvent called from the factory
         * 
         * @param loggerName
         *            The name of the Logger.
         * @param marker
         *            The Marker or null.
         * @param loggerFQCN
         *            The fully qualified class name of the caller.
         * @param level
         *            The logging Level.
         * @param message
         *            The Message.
         * @param properties
         *            the properties to be merged with ThreadContext key-value
         *            pairs into the event's ReadOnlyStringMap.
         * @param t
         *            A Throwable or null.
         */
        public JuliLog4jEvent(String loggerName, Marker marker, String loggerFQCN, Level level, Message message,
                List properties, Throwable t) {
            super(loggerName, marker, loggerFQCN, level, message, properties, t);
        }

        @Override
        public StackTraceElement getSource() {
            if (source != null) {
                return source;
            }
            String loggerFqcn= getLoggerFqcn();
            if (loggerFqcn == null || !isIncludeLocation()) {
                return null;
            }
            source= JuliLog4jEventFactory.calcLocation(loggerFqcn);
            return source;
        }

        @Override
        @CoberturaIgnore
        public int hashCode() {
            final int prime= 31;
            int result= super.hashCode();
            result= prime * result + ((source == null) ? 0 : source.hashCode());
            return result;
        }

        @Override
        @CoberturaIgnore
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (!super.equals(obj)) {
                return false;
            }
            if (!(obj instanceof JuliLog4jEvent)) {
                return false;
            }
            JuliLog4jEvent other= (JuliLog4jEvent) obj;
            if (source == null) {
                if (other.source != null) {
                    return false;
                }
            } else if (!source.equals(other.source)) {
                return false;
            }
            return true;
        }

        @Override
        @CoberturaIgnore
        public String toString() {
            StringBuilder sb= new StringBuilder();
            sb.append("JuliLog4jEvent [source=");
            sb.append(source).append(", ");
            sb.append(super.toString());
            sb.append(']');
            return sb.toString();
        }

    }

    /**
     * Create a new JuliLog4jEventFactory
     */
    public JuliLog4jEventFactory() {
    }

    @Override
    public LogEvent createEvent(String loggerName, Marker marker, String fqcn, Level level, Message data,
            List properties, Throwable t) {
        return new JuliLog4jEvent(loggerName, marker, fqcn, level, data, properties, t);
    }

    /**
     * Method called from the log event to find the correct StackTraceElement to
     * use
     *
     * @param fqcnOfLogger
     *            The fully qualified class name of the logger
     * @return The point in the stack where the call originated
     */
    public static StackTraceElement calcLocation(final String fqcnOfLogger) {
        if (fqcnOfLogger == null) {
            return null;
        }
        final StackTraceElement[] stackTrace= new Throwable().getStackTrace();
        StackTraceElement last= null;
        for (int i= stackTrace.length - 1; i > 0; i--) {
            final String className= stackTrace[i].getClassName();
            if (fqcnOfLogger.equals(className) || JULI_LOG_NAME.equals(className)) {
                return last;
            }
            last= stackTrace[i];
        }
        return null;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy