org.gflogger.log4j.Log4jEntry.java Source code

Java tutorial

Introduction

Here is the source code for org.gflogger.log4j.Log4jEntry.java

Source

/*
 * Licensed 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
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.gflogger.log4j;

import static org.gflogger.util.StackTraceUtils.getCodeLocation;
import static org.gflogger.util.StackTraceUtils.getImplementationVersion;
import static org.gflogger.util.StackTraceUtils.loadClass;

import java.util.Iterator;

import org.apache.commons.logging.Log;
import org.gflogger.DefaultObjectFormatterFactory;
import org.gflogger.FormattedGFLogEntry;
import org.gflogger.GFLogEntry;
import org.gflogger.LogLevel;
import org.gflogger.Loggable;
import org.gflogger.ObjectFormatter;
import org.gflogger.ObjectFormatterFactory;
import org.gflogger.formatter.BufferFormatter;

/**
 * Log4jEntry
 *
 * @author Vladimir Dolzhenko, vladimir.dolzhenko@gmail.com
 */
public class Log4jEntry implements GFLogEntry, FormattedGFLogEntry {

    // 2k
    private static final int DEFAULT_BUFFER_SIZE = 1 << 11;

    private final Log log;
    private final StringBuilder builder;

    private LogLevel logLevel;

    private final ObjectFormatterFactory formatterFactory = new DefaultObjectFormatterFactory();

    private String pattern;
    private int pPos;

    public Log4jEntry(Log log) {
        this.log = log;
        this.builder = new StringBuilder(DEFAULT_BUFFER_SIZE);
    }

    public void setLogLevel(LogLevel logLevel) {
        this.logLevel = logLevel;
    }

    public void setPattern(String pattern) {
        if (pattern == null) {
            throw new IllegalArgumentException("expected not null pattern.");
        }
        this.pattern = pattern;
        this.pPos = 0;
        appendNextPatternChank();
    }

    protected void appendNextPatternChank() {
        final int len = pattern.length();
        for (; pPos < len; pPos++) {
            final char ch = pattern.charAt(pPos);
            if (ch == '%' && (pPos + 1) < len) {
                if (pattern.charAt(pPos + 1) != '%')
                    break;
                pPos++;
            }
            append(ch);
        }
        if (this.pPos == len) {
            commit();
        }
    }

    protected void checkPlaceholder() {
        if (pattern == null) {
            throw new IllegalStateException("Entry has been commited.");
        }
        if (pPos + 2 >= pattern.length()) {
            throw new IllegalStateException("Illegal pattern '" + pattern + "' or position " + pPos);
        }
        final char ch1 = pattern.charAt(pPos);
        final char ch2 = pattern.charAt(pPos + 1);
        if (ch1 != '%' || ch2 != 's') {
            throw new IllegalArgumentException("Illegal pattern placeholder '" + ch1 + "" + ch2 + " at " + pPos);
        }
        pPos += 2;
    }

    protected void checkAndCommit() {
        if (pattern == null)
            return;
        if (pPos + 1 != pattern.length()) {
            throw new IllegalStateException("The pattern has not been finished. More parameters are required.");
        }
        commit();
    }

    public void reset() {
        builder.setLength(0);
    }

    @Override
    public GFLogEntry append(char c) {
        this.builder.append(c);
        return this;
    }

    @Override
    public GFLogEntry append(CharSequence csq) {
        this.builder.append(csq);
        return this;
    }

    @Override
    public GFLogEntry append(CharSequence csq, int start, int end) {
        this.builder.append(csq, start, end);
        return this;
    }

    @Override
    public GFLogEntry append(boolean b) {
        this.builder.append(b);
        return this;
    }

    @Override
    public GFLogEntry append(int i) {
        this.builder.append(i);
        return this;
    }

    @Override
    public GFLogEntry append(long i) {
        this.builder.append(i);
        return this;
    }

    @Override
    public GFLogEntry append(double i) {
        this.builder.append(i);
        return this;
    }

    @Override
    public GFLogEntry append(double i, int precision) {
        long x = (long) i;
        this.builder.append(x);
        this.builder.append('.');
        x = (long) ((i - x) * (precision > 0 ? BufferFormatter.LONG_SIZE_TABLE[precision - 1] : 1));
        this.builder.append(x < 0 ? -x : x);
        return this;
    }

    @Override
    public <T> GFLogEntry append(T[] array, String separator) {
        if (array == null) {
            append('n').append('u').append('l').append('l');
        } else {
            try {
                append('[');
                ObjectFormatter formatter = null;
                for (int i = 0; i < array.length; i++) {
                    if (i > 0) {
                        append(separator);
                    }
                    final T obj = array[i];
                    if (obj != null) {
                        if (formatter == null) {
                            formatter = formatterFactory.getObjectFormatter(obj);
                        }
                        formatter.append(obj, this);
                    } else {
                        append('n').append('u').append('l').append('l');
                    }
                }
                append(']');
            } catch (Throwable e) {
                //error("append(Object o)", e);
            }
            return this;
        }
        return this;
    }

    @Override
    public <T> GFLogEntry append(Iterable<T> iterable, String separator) {
        if (iterable == null) {
            append('n').append('u').append('l').append('l');
        } else {
            try {
                append('[');
                ObjectFormatter formatter = null;
                for (final Iterator<T> it = iterable.iterator(); it.hasNext();) {
                    final T obj = it.next();
                    if (obj != null) {
                        if (formatter == null) {
                            formatter = formatterFactory.getObjectFormatter(obj);
                        }
                        formatter.append(obj, this);
                    } else {
                        append('n').append('u').append('l').append('l');
                    }
                    if (it.hasNext()) {
                        append(separator);
                    }
                }
                append(']');
            } catch (Throwable e) {
                //error("append(Object o)", e);
            }
        }
        return this;
    }

    @Override
    public GFLogEntry append(Throwable e) {
        if (e != null) {
            try {
                append(e.getClass().getName());
                String message = e.getLocalizedMessage();
                if (message != null) {
                    append(": ").append(message);
                }
                append('\n');
                final StackTraceElement[] trace = e.getStackTrace();
                for (int i = 0; i < trace.length; i++) {
                    append("\tat ").append(trace[i].getClassName()).append('.').append(trace[i].getMethodName());
                    append('(');
                    if (trace[i].isNativeMethod()) {
                        append("native");
                    } else {
                        final String fileName = trace[i].getFileName();
                        final int lineNumber = trace[i].getLineNumber();
                        if (fileName != null) {
                            append(fileName);
                            if (lineNumber >= 0) {
                                append(':').append(lineNumber);
                            }

                            final Class clazz = loadClass(trace[i].getClassName());
                            if (clazz != null) {
                                append('[').append(getCodeLocation(clazz));
                                final String implVersion = getImplementationVersion(clazz);
                                if (implVersion != null) {
                                    append(':').append(implVersion);
                                }
                                append(']');
                            }

                        } else {
                            append("unknown");
                        }
                    }
                    append(')').append('\n');
                }
            } catch (Throwable t) {
                //
                t.printStackTrace();
            }
        }
        return this;
    }

    @Override
    public GFLogEntry append(Loggable loggable) {
        if (loggable != null) {
            loggable.appendTo(this);
        } else {
            append('n').append('u').append('l').append('l');
        }
        return this;
    }

    @Override
    public GFLogEntry append(Object o) {
        try {
            if (o != null) {
                final ObjectFormatter formatter = formatterFactory.getObjectFormatter(o);
                formatter.append(o, this);
            } else {
                append('n').append('u').append('l').append('l');
            }
        } catch (Throwable e) {
            //error("append(Object o)", e);
        }
        return this;
    }

    @Override
    public void appendLast(final char c) {
        append(c);
        commit();
    }

    @Override
    public void appendLast(final CharSequence csq) {
        append(csq);
        commit();
    }

    @Override
    public void appendLast(final CharSequence csq, final int start, final int end) {
        append(csq, start, end);
        commit();
    }

    @Override
    public void appendLast(final boolean b) {
        append(b);
        commit();
    }

    @Override
    public void appendLast(final int i) {
        append(i);
        commit();
    }

    @Override
    public void appendLast(final long i) {
        append(i);
        commit();
    }

    @Override
    public void appendLast(final double i) {
        append(i);
        commit();
    }

    @Override
    public void appendLast(final double i, final int precision) {
        append(i, precision);
        commit();
    }

    @Override
    public <T> void appendLast(T[] array, String separator) {
        append(array, separator);
        commit();
    }

    @Override
    public <T> void appendLast(Iterable<T> iterable, String separator) {
        append(iterable, separator);
        commit();
    }

    @Override
    public void appendLast(Throwable e) {
        append(e);
        commit();
    }

    @Override
    public void appendLast(Loggable loggable) {
        append(loggable);
        commit();
    }

    @Override
    public void appendLast(Object o) {
        append(o);
        commit();
    }

    @Override
    public boolean isPatternEnd() {
        return pPos == pattern.length();
    }

    @Override
    public FormattedGFLogEntry with(char c) {
        checkPlaceholder();
        append(c);
        appendNextPatternChank();
        return this;
    }

    @Override
    public FormattedGFLogEntry with(CharSequence csq) {
        checkPlaceholder();
        append(csq);
        appendNextPatternChank();
        return this;
    }

    @Override
    public FormattedGFLogEntry with(CharSequence csq, int start, int end) {
        checkPlaceholder();
        append(csq, start, end);
        appendNextPatternChank();
        return this;
    }

    @Override
    public FormattedGFLogEntry with(boolean b) {
        checkPlaceholder();
        append(b);
        appendNextPatternChank();
        return this;
    }

    @Override
    public FormattedGFLogEntry with(int i) {
        checkPlaceholder();
        append(i);
        appendNextPatternChank();
        return this;
    }

    @Override
    public FormattedGFLogEntry with(long i) {
        checkPlaceholder();
        append(i);
        appendNextPatternChank();
        return this;
    }

    @Override
    public FormattedGFLogEntry with(double i) {
        checkPlaceholder();
        append(i);
        appendNextPatternChank();
        return this;
    }

    @Override
    public FormattedGFLogEntry with(double i, int precision) {
        checkPlaceholder();
        append(i, precision);
        appendNextPatternChank();
        return this;
    }

    @Override
    public <T> FormattedGFLogEntry with(T[] array, String separator) {
        checkPlaceholder();
        append(array, separator);
        appendNextPatternChank();
        return this;
    }

    @Override
    public <T> FormattedGFLogEntry with(Iterable<T> iterable, String separator) {
        checkPlaceholder();
        append(iterable, separator);
        appendNextPatternChank();
        return this;
    }

    @Override
    public FormattedGFLogEntry with(Throwable e) {
        checkPlaceholder();
        append(e);
        appendNextPatternChank();
        return this;
    }

    @Override
    public FormattedGFLogEntry with(Loggable loggable) {
        checkPlaceholder();
        append(loggable);
        appendNextPatternChank();
        return this;
    }

    @Override
    public FormattedGFLogEntry with(Object o) {
        checkPlaceholder();
        append(o);
        appendNextPatternChank();
        return this;
    }

    @Override
    public void withLast(char c) {
        with(c);
        checkAndCommit();
    }

    @Override
    public void withLast(CharSequence csq) {
        with(csq);
        checkAndCommit();
    }

    @Override
    public void withLast(CharSequence csq, int start, int end) {
        with(csq, start, end);
        checkAndCommit();
    }

    @Override
    public void withLast(boolean b) {
        with(b);
        checkAndCommit();
    }

    @Override
    public void withLast(int i) {
        with(i);
        checkAndCommit();
    }

    @Override
    public void withLast(long i) {
        with(i);
        checkAndCommit();
    }

    @Override
    public void withLast(double i) {
        with(i);
        checkAndCommit();
    }

    @Override
    public void withLast(double i, int precision) {
        with(i, precision);
        checkAndCommit();
    }

    @Override
    public <T> void withLast(T[] array, String separator) {
        with(array, separator);
        checkAndCommit();
    }

    @Override
    public <T> void withLast(Iterable<T> iterable, String separator) {
        with(iterable, separator);
        checkAndCommit();
    }

    @Override
    public void withLast(Throwable e) {
        with(e);
        checkAndCommit();
    }

    @Override
    public void withLast(Loggable loggable) {
        with(loggable);
        checkAndCommit();
    }

    @Override
    public void withLast(Object o) {
        with(o);
        checkAndCommit();
    }

    @Override
    public void commit() {
        switch (logLevel) {
        case TRACE:
            if (log.isTraceEnabled()) {
                log.trace(builder.toString());
            }
            break;
        case DEBUG:
            if (log.isDebugEnabled()) {
                log.debug(builder.toString());
            }
            break;
        case INFO:
            if (log.isInfoEnabled()) {
                log.info(builder.toString());
            }
            break;
        case WARN:
            if (log.isWarnEnabled()) {
                log.warn(builder.toString());
            }
            break;
        case ERROR:
            if (log.isErrorEnabled()) {
                log.error(builder.toString());
            }
            break;
        case FATAL:
            if (log.isFatalEnabled()) {
                log.fatal(builder.toString());
            }
            break;
        }
        if (builder.length() > DEFAULT_BUFFER_SIZE) {
            builder.setLength(DEFAULT_BUFFER_SIZE);
            builder.trimToSize();
        }
        builder.setLength(0);
        pattern = null;
    }
}