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/pattern/NameAbbreviator.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.pattern;

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

import org.apache.logging.log4j.util.PerformanceSensitive;


/**
 * NameAbbreviator generates abbreviated logger and class names.
 */
@PerformanceSensitive("allocation")
public abstract class NameAbbreviator {
    /**
     * Default (no abbreviation) abbreviator.
     */
    private static final NameAbbreviator DEFAULT = new NOPAbbreviator();

    /**
     * Gets an abbreviator.
     * <p>
     * For example, "%logger{2}" will output only 2 elements of the logger name, "%logger{1.}" will output only the
     * first character of the non-final elements in the name, "%logger(1~.2~} will output the first character of the
     * first element, two characters of the second and subsequent elements and will use a tilde to indicate abbreviated
     * characters.
     * </p>
     *
     * @param pattern
     *        abbreviation pattern.
     * @return abbreviator, will not be null.
     */
    public static NameAbbreviator getAbbreviator(final String pattern) {
        if (pattern.length() > 0) {
            //  if pattern is just spaces and numbers then
            //     use MaxElementAbbreviator
            final String trimmed = pattern.trim();

            if (trimmed.isEmpty()) {
                return DEFAULT;
            }

            boolean isNegativeNumber;
            final String number;

            // check if number is a negative number
            if (trimmed.length() > 1 && trimmed.charAt(0) == '-') {
                isNegativeNumber = true;
                number = trimmed.substring(1);
            } else {
                isNegativeNumber = false;
                number = trimmed;
            }

            int i = 0;

            while (i < number.length() && number.charAt(i) >= '0'
                    && number.charAt(i) <= '9') {
                i++;
            }

            //
            //  if all blanks and digits
            //
            if (i == number.length()) {
                return new MaxElementAbbreviator(Integer.parseInt(number),
                        isNegativeNumber? MaxElementAbbreviator.Strategy.DROP : MaxElementAbbreviator.Strategy.RETAIN);
            }

            final ArrayList<PatternAbbreviatorFragment> fragments = new ArrayList<>(5);
            char ellipsis;
            int charCount;
            int pos = 0;

            while (pos < trimmed.length() && pos >= 0) {
                int ellipsisPos = pos;

                if (trimmed.charAt(pos) == '*') {
                    charCount = Integer.MAX_VALUE;
                    ellipsisPos++;
                } else if (trimmed.charAt(pos) >= '0' && trimmed.charAt(pos) <= '9') {
                    charCount = trimmed.charAt(pos) - '0';
                    ellipsisPos++;
                } else {
                    charCount = 0;
                }

                ellipsis = '\0';

                if (ellipsisPos < trimmed.length()) {
                    ellipsis = trimmed.charAt(ellipsisPos);

                    if (ellipsis == '.') {
                        ellipsis = '\0';
                    }
                }

                fragments.add(new PatternAbbreviatorFragment(charCount, ellipsis));
                pos = trimmed.indexOf('.', pos);

                if (pos == -1) {
                    break;
                }

                pos++;
            }

            return new PatternAbbreviator(fragments);
        }

        //
        //  no matching abbreviation, return defaultAbbreviator
        //
        return DEFAULT;
    }

    /**
     * Gets default abbreviator.
     *
     * @return default abbreviator.
     */
    public static NameAbbreviator getDefaultAbbreviator() {
        return DEFAULT;
    }

    /**
     * Abbreviates a name in a String.
     *
     * @param original the text to abbreviate, may not be null.
     * @param destination StringBuilder to write the result to
     */
    public abstract void abbreviate(final String original, final StringBuilder destination);

    /**
     * Abbreviator that simply appends full name to buffer.
     */
    private static class NOPAbbreviator extends NameAbbreviator {
        /**
         * Constructor.
         */
        public NOPAbbreviator() {
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void abbreviate(final String original, final StringBuilder destination) {
            destination.append(original);
        }
    }

    /**
     * Abbreviator that drops starting path elements.
     */
    private static class MaxElementAbbreviator extends NameAbbreviator {

        /**
         * <p>When the name is reduced in length by cutting parts, there can be two ways to do it.</p>
         * 1. Remove a given number of parts starting from front - called DROP <br/>
         * 2. Retain a given number of parts starting from the end - called RETAIN
         */
        private enum Strategy {
            DROP(0) {
                @Override
                void abbreviate(final int count, final String original, final StringBuilder destination) {
                    // If a path does not contain enough path elements to drop, none will be dropped.
                    int start = 0;
                    int nextStart;
                    for (int i = 0; i < count; i++) {
                        nextStart = original.indexOf('.', start);
                        if (nextStart == -1) {
                            destination.append(original);
                            return;
                        }
                        start = nextStart + 1;
                    }
                    destination.append(original, start, original.length());
                }
            },
            RETAIN(1) {
                @Override
                void abbreviate(final int count, final String original, final StringBuilder destination) {
                    // We subtract 1 from 'len' when assigning to 'end' to avoid out of
                    // bounds exception in return r.substring(end+1, len). This can happen if
                    // precision is 1 and the category name ends with a dot.
                    int end = original.length() - 1;

                    for (int i = count; i > 0; i--) {
                        end = original.lastIndexOf('.', end - 1);
                        if (end == -1) {
                            destination.append(original);
                            return;
                        }
                    }
                    destination.append(original, end + 1, original.length());
                }
            };

            final int minCount;

            Strategy(final int minCount) {
                this.minCount = minCount;
            }

            abstract void abbreviate(final int count, final String original, final StringBuilder destination);
        }

        /**
         * Maximum number of path elements to output.
         */
        private final int count;

        /**
         * Strategy used for cutting down the size of the name
         */
        private final Strategy strategy;

        /**
         * Create new instance.
         *
         * @param count maximum number of path elements to drop or output.
         * @param strategy drop or retain
         */
        public MaxElementAbbreviator(final int count, final Strategy strategy) {
            this.count = Math.max(count, strategy.minCount);
            this.strategy = strategy;
        }

        /**
         * Abbreviate name.
         *
         * @param original The String to abbreviate.
         * @param destination the buffer to write the abbreviated name into
         */
        @Override
        public void abbreviate(final String original, final StringBuilder destination) {
            strategy.abbreviate(count, original, destination);
        }
    }

    /**
     * Fragment of an pattern abbreviator.
     */
    private static class PatternAbbreviatorFragment {
        /**
         * Count of initial characters of element to output.
         */
        private final int charCount;

        /**
         * Character used to represent dropped characters.
         * '\0' indicates no representation of dropped characters.
         */
        private final char ellipsis;

        /**
         * Creates a PatternAbbreviatorFragment.
         *
         * @param charCount number of initial characters to preserve.
         * @param ellipsis  character to represent elimination of characters,
         *                  '\0' if no ellipsis is desired.
         */
        public PatternAbbreviatorFragment(
            final int charCount, final char ellipsis) {
            this.charCount = charCount;
            this.ellipsis = ellipsis;
        }

        /**
         * Abbreviate element of name.
         *
         * @param buf      buffer to receive element.
         * @param startPos starting index of name element.
         * @return starting index of next element.
         */
        public int abbreviate(final StringBuilder buf, final int startPos) {
            final int start = (startPos < 0) ? 0 : startPos;
            final int max = buf.length();
            int nextDot = -1;
            for (int i = start; i < max; i++) {
                if (buf.charAt(i) == '.') {
                    nextDot = i;
                    break;
                }
            }
            if (nextDot != -1) {
                if (nextDot - startPos > charCount) {
                    buf.delete(startPos + charCount, nextDot);
                    nextDot = startPos + charCount;

                    if (ellipsis != '\0') {
                        buf.insert(nextDot, ellipsis);
                        nextDot++;
                    }
                }
                nextDot++;
            }
            return nextDot;
        }
    }

    /**
     * Pattern abbreviator.
     */
    private static class PatternAbbreviator extends NameAbbreviator {
        /**
         * Element abbreviation patterns.
         */
        private final PatternAbbreviatorFragment[] fragments;

        /**
         * Create PatternAbbreviator.
         *
         * @param fragments element abbreviation patterns.
         */
        public PatternAbbreviator(final List<PatternAbbreviatorFragment> fragments) {
            if (fragments.isEmpty()) {
                throw new IllegalArgumentException(
                    "fragments must have at least one element");
            }

            this.fragments = new PatternAbbreviatorFragment[fragments.size()];
            fragments.toArray(this.fragments);
        }

        /**
         * Abbreviates name.
         *
         * @param original the original string to abbreviate
         * @param destination buffer that abbreviated name is appended to
         */
        @Override
        public void abbreviate(final String original, final StringBuilder destination) {
            //
            //  all non-terminal patterns are executed once
            //
            int pos = destination.length();
            final int max = pos + original.length();

            destination.append(original);

            int fragmentIndex = 0;
            while (pos < max && pos >= 0) {
                pos = fragments[fragmentIndex].abbreviate(destination, pos);
                // last pattern in executed repeatedly
                if (fragmentIndex < fragments.length - 1) {
                    fragmentIndex++;
                }
            }
        }
    }
}

org/apache/logging/log4j/core/pattern/NameAbbreviator.java

 

Or download all of them as a single archive file:

File name: log4j-core-2.14.1-sources.jar
File size: 1281358 bytes
Release date: 2021-03-06
Download 

 

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, 81836👍, 0💬