You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2017/03/08 03:58:08 UTC

[02/11] logging-log4j2 git commit: merge master

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f3be8790/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
----------------------------------------------------------------------
diff --cc log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
index abb733f,d6bafca..81cb5dc
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
@@@ -1,311 -1,295 +1,314 @@@
 -/*
 - * 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.TextRenderer;
 -import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
 -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;
 -
 -    /**
 -     * 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
 -     */
 -    protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,
 -            final TextRenderer textRenderer) {
 -        this.lines = lines;
 -        this.separator = separator == null ? Strings.LINE_SEPARATOR : separator;
 -        this.ignorePackages = ignorePackages;
 -        this.textRenderer = textRenderer == null ? PlainTextRenderer.getInstance() : textRenderer;
 -    }
 -
 -    /**
 -     * 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);
 -    }
 -
 -    /**
 -     * Constructs the options for printing stack trace.
 -     */
 -    protected ThrowableFormatOptions() {
 -        this(DEFAULT_LINES, 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;
 -        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.equalsIgnoreCase(FULL)) {
 -                    lines = Integer.parseInt(option);
 -                }
 -            }
 -        }
 -        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer);
 -    }
 -
 -}
 +/*
 + * 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.Arrays;
++import java.util.Collections;
 +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.Constants;
++import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
 +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 List<String> mdcKeys;
++
 +    /**
 +     * The list of packages to filter.
 +     */
 +    private final List<String> ignorePackages;
 +
-     private final List<String> mdcKeys;
- 
 +    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
 +     * @param mdcKeys
 +     */
 +    protected ThrowableFormatOptions(final int lines, final String separator, final List<String> ignorePackages,
-                                      TextRenderer textRenderer, final List<String> mdcKeys) {
++                                     final TextRenderer textRenderer, final List<String> mdcKeys) {
 +        this.lines = lines;
-         this.separator = separator == null ? Constants.LINE_SEPARATOR : separator;
++        this.separator = separator == null ? Strings.LINE_SEPARATOR : separator;
 +        this.ignorePackages = ignorePackages;
 +        this.textRenderer = textRenderer == null ? PlainTextRenderer.getInstance() : textRenderer;
 +        this.mdcKeys = mdcKeys;
 +    }
 +
 +    /**
 +     * 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;
++        List<String> mdcKeys = DEFAULT.mdcKeys;
 +        String separator = DEFAULT.separator;
 +        List<String> packages = DEFAULT.ignorePackages;
 +        TextRenderer ansiRenderer = DEFAULT.textRenderer;
-         List<String> mdcKeys = DEFAULT.mdcKeys;
 +        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()) {
-                         String styleMapStr = option.equals("ansi") ? Strings.EMPTY
++                        final String styleMapStr = option.equals("ansi") ? Strings.EMPTY
 +                                : option.substring("ansi(".length(), option.length() - 1);
-                         ansiRenderer = new JAnsiTextRenderer(new String[] {null, styleMapStr},
++                        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("mdc(") && option.endsWith(")")){
 +                    String suffixPattern = option.substring("mdc(".length(), option.length() - 1);
 +                    mdcKeys = parseMdcKeys(suffixPattern);
 +                } else if (option.startsWith("X(") && option.endsWith(")")){
 +                    String suffixPattern = option.substring("X(".length(), option.length() - 1);
 +                    mdcKeys = parseMdcKeys(suffixPattern);
 +                } else if (!option.equalsIgnoreCase(FULL)) {
 +                    lines = Integer.parseInt(option);
 +                }
 +            }
 +        }
 +        return new ThrowableFormatOptions(lines, separator, packages, ansiRenderer, mdcKeys);
 +    }
 +
-     private static List<String> parseMdcKeys(final String mdcKeyExp) {
-         String[] keys = mdcKeyExp.split(",");
-         return Arrays.asList(keys);
++    private static List<String> parseMdcKeys(final String suffixPattern) {
++        if (suffixPattern.trim().isEmpty()) {
++            return Collections.emptyList();
++        } else {
++            return Arrays.asList(suffixPattern.split(","));
++        }
 +    }
 +
 +}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f3be8790/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/f3be8790/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/RootThrowablePatternConverter.java
----------------------------------------------------------------------