Source Code for Apache Log4j Core Implementation

Apache Log4j Core Implementation provides the functional components of the logging system. Users are free to create their own plugins and include them in the logging configuration. Apache Log4j Core is a required module to use Apache Log4j.

Bytecode (Java 8) for Apache Log4j Core Implementation is provided in a separate JAR file like log4j-core-2.14.1.jar.

Source Code files for Apache Log4j API are provided in both binary packge like apache-log4j-2.14.1-bin.zip and source package like apache-log4j-2.14.1-src.zip. You can download them at Apache Log4j Website.

You can also browse Source Code files for Apache Log4j Core Implementation 2.14.1 below.

✍: FYIcenter.com

org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java

/*
 * 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
 *
 *      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.apache.logging.log4j.core.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
import org.apache.logging.log4j.core.pattern.TextRenderer;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.Patterns;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.Strings;

/**
 * Contains options which control how a {@link Throwable} pattern is formatted.
 */
public final class ThrowableFormatOptions {

    private static final int DEFAULT_LINES = Integer.MAX_VALUE;

    /**
     * Default instance of {@code ThrowableFormatOptions}.
     */
    protected static final ThrowableFormatOptions DEFAULT = new ThrowableFormatOptions();

    /**
     * Format the whole stack trace.
     */
    private static final String FULL = "full";

    /**
     * Do not format the exception.
     */
    private static final String NONE = "none";

    /**
     * Format only the first line of the throwable.
     */
    private static final String SHORT = "short";

    /**
     * ANSI renderer
     */
    private final TextRenderer textRenderer;

    /**
     * The number of lines to write.
     */
    private final int lines;

    /**
     * The stack trace separator.
     */
    private final String separator;

    private final String suffix;

    /**
     * The list of packages to filter.
     */
    private final List<String> ignorePackages;

    public static final String CLASS_NAME = "short.className";
    public static final String METHOD_NAME = "short.methodName";
    public static final String LINE_NUMBER = "short.lineNumber";
    public static final String FILE_NAME = "short.fileName";
    public static final String MESSAGE = "short.message";
    public static final String LOCALIZED_MESSAGE = "short.localizedMessage";

    /**
     * Constructs the options for printing stack trace.
     *
     * @param lines
     *            The number of lines.
     * @param separator
     *            The stack trace separator.
     * @param ignorePackages
     *            The packages to filter.
     * @param textRenderer
     *            The ANSI renderer
     * @param suffix
     */
    protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,
            final TextRenderer textRenderer, final String suffix) {
        this.lines = lines;
        this.separator = separator == null ? Strings.LINE_SEPARATOR : separator;
        this.ignorePackages = ignorePackages;
        this.textRenderer = textRenderer == null ? PlainTextRenderer.getInstance() : textRenderer;
        this.suffix = suffix;
    }

    /**
     * Constructs the options for printing stack trace.
     *
     * @param packages
     *            The packages to filter.
     */
    protected ThrowableFormatOptions(final List<String> packages) {
        this(DEFAULT_LINES, null, packages, null, null);
    }

    /**
     * Constructs the options for printing stack trace.
     */
    protected ThrowableFormatOptions() {
        this(DEFAULT_LINES, null, null, null, null);
    }

    /**
     * Returns the number of lines to write.
     *
     * @return The number of lines to write.
     */
    public int getLines() {
        return this.lines;
    }

    /**
     * Returns the stack trace separator.
     *
     * @return The stack trace separator.
     */
    public String getSeparator() {
        return this.separator;
    }

    /**
     * Returns the message rendered.
     *
     * @return the message rendered.
     */
    public TextRenderer getTextRenderer() {
        return textRenderer;
    }

    /**
     * Returns the list of packages to ignore (filter out).
     *
     * @return The list of packages to ignore (filter out).
     */
    public List<String> getIgnorePackages() {
        return this.ignorePackages;
    }

    /**
     * Determines if all lines should be printed.
     *
     * @return true for all lines, false otherwise.
     */
    public boolean allLines() {
        return this.lines == DEFAULT_LINES;
    }

    /**
     * Determines if any lines should be printed.
     *
     * @return true for any lines, false otherwise.
     */
    public boolean anyLines() {
        return this.lines > 0;
    }

    /**
     * Returns the minimum between the lines and the max lines.
     *
     * @param maxLines
     *            The maximum number of lines.
     * @return The number of lines to print.
     */
    public int minLines(final int maxLines) {
        return this.lines > maxLines ? maxLines : this.lines;
    }

    /**
     * Determines if there are any packages to filter.
     *
     * @return true if there are packages, false otherwise.
     */
    public boolean hasPackages() {
        return this.ignorePackages != null && !this.ignorePackages.isEmpty();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        final StringBuilder s = new StringBuilder();
        s.append('{')
                .append(allLines() ? FULL : this.lines == 2 ? SHORT : anyLines() ? String.valueOf(this.lines) : NONE)
                .append('}');
        s.append("{separator(").append(this.separator).append(")}");
        if (hasPackages()) {
            s.append("{filters(");
            for (final String p : this.ignorePackages) {
                s.append(p).append(',');
            }
            s.deleteCharAt(s.length() - 1);
            s.append(")}");
        }
        return s.toString();
    }

    /**
     * Creates a new instance based on the array of options.
     *
     * @param options
     *            The array of options.
     * @return A new initialized instance.
     */
    public static ThrowableFormatOptions newInstance(String[] options) {
        if (options == null || options.length == 0) {
            return DEFAULT;
        }
        // NOTE: The following code is present for backward compatibility
        // and was copied from Extended/RootThrowablePatternConverter.
        // This supports a single option with the format:
        // %xEx{["none"|"short"|"full"|depth],[filters(packages)}
        // However, the convention for multiple options should be:
        // %xEx{["none"|"short"|"full"|depth]}[{filters(packages)}]
        if (options.length == 1 && Strings.isNotEmpty(options[0])) {
            final String[] opts = options[0].split(Patterns.COMMA_SEPARATOR, 2);
            final String first = opts[0].trim();
            try (final Scanner scanner = new Scanner(first)) {
                if (opts.length > 1 && (first.equalsIgnoreCase(FULL) || first.equalsIgnoreCase(SHORT)
                        || first.equalsIgnoreCase(NONE) || scanner.hasNextInt())) {
                    options = new String[] { first, opts[1].trim() };
                }
            }
        }

        int lines = DEFAULT.lines;
        String separator = DEFAULT.separator;
        List<String> packages = DEFAULT.ignorePackages;
        TextRenderer ansiRenderer = DEFAULT.textRenderer;
        String suffix = DEFAULT.getSuffix();
        for (final String rawOption : options) {
            if (rawOption != null) {
                final String option = rawOption.trim();
                if (option.isEmpty()) {
                    // continue;
                } else if (option.startsWith("separator(") && option.endsWith(")")) {
                    separator = option.substring("separator(".length(), option.length() - 1);
                } else if (option.startsWith("filters(") && option.endsWith(")")) {
                    final String filterStr = option.substring("filters(".length(), option.length() - 1);
                    if (filterStr.length() > 0) {
                        final String[] array = filterStr.split(Patterns.COMMA_SEPARATOR);
                        if (array.length > 0) {
                            packages = new ArrayList<>(array.length);
                            for (String token : array) {
                                token = token.trim();
                                if (token.length() > 0) {
                                    packages.add(token);
                                }
                            }
                        }
                    }
                } else if (option.equalsIgnoreCase(NONE)) {
                    lines = 0;
                } else if (option.equalsIgnoreCase(SHORT) || option.equalsIgnoreCase(CLASS_NAME)
                        || option.equalsIgnoreCase(METHOD_NAME) || option.equalsIgnoreCase(LINE_NUMBER)
                        || option.equalsIgnoreCase(FILE_NAME) || option.equalsIgnoreCase(MESSAGE)
                        || option.equalsIgnoreCase(LOCALIZED_MESSAGE)) {
                    lines = 2;
                } else if (option.startsWith("ansi(") && option.endsWith(")") || option.equals("ansi")) {
                    if (Loader.isJansiAvailable()) {
                        final String styleMapStr = option.equals("ansi") ? Strings.EMPTY
                                : option.substring("ansi(".length(), option.length() - 1);
                        ansiRenderer = new JAnsiTextRenderer(new String[] { null, styleMapStr },
                                JAnsiTextRenderer.DefaultExceptionStyleMap);
                    } else {
                        StatusLogger.getLogger().warn(
                                "You requested ANSI exception rendering but JANSI is not on the classpath. Please see https://logging.apache.org/log4j/2.x/runtime-dependencies.html");
                    }
                } else if (option.startsWith("S(") && option.endsWith(")")){
                    suffix = option.substring("S(".length(), option.length() - 1);
                } else if (option.startsWith("suffix(") && option.endsWith(")")){
                    suffix = option.substring("suffix(".length(), option.length() - 1);
                } else if (!option.equalsIgnoreCase(FULL)) {
                    lines = Integer.parseInt(option);
                }
            }
        }
        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer, suffix);
    }

    public String getSuffix() {
        return suffix;
    }

}

org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java

 

⇒ Source Code for Apache Log4j JDK Logging Adapter

⇐ Source Code for Apache Log4j API

⇑ Downloading and Reviewing Apache Log4j Packages

⇑⇑ FAQ for Apache Log4j

2015-11-03, 51096👍, 0💬