    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements. See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache license, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License. You may obtain a copy of the License at
    008     *
    009     *      http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the license for the specific language governing permissions and
    015     * limitations under the license.
    016     */
    017    package org.apache.log4j;
    018
    019    import java.io.IOException;
    020    import java.io.ObjectInputStream;
    021    import java.io.ObjectOutputStream;
    022    import java.io.ObjectStreamException;
    023    import java.io.Serializable;
    024
    025    import org.apache.logging.log4j.util.Strings;
    026
    027    /**
    028     * Defines the minimum set of levels recognized by the system, that is
    029     * <code>OFF</code>, <code>FATAL</code>, <code>ERROR</code>,
    030     * <code>WARN</code>, <code>INFO</code>, <code>DEBUG</code>
    031     * and <code>ALL</code>.
    032     * <p>
    033     * The <code>Level</code> class may be subclassed to define a larger
    034     * level set.
    035     * </p>
    036     */
    037    public class Level extends Priority implements Serializable {
    038
    039        /**
    040         * TRACE level integer value.
    041         *
    042         * @since 1.2.12
    043         */
    044        public static final int TRACE_INT = 5000;
    045
    046        /**
    047         * The <code>OFF</code> has the highest possible rank and is
    048         * intended to turn off logging.
    049         */
    050        public static final Level OFF = new Level(OFF_INT, "OFF", 0);
    051
    052        /**
    053         * The <code>FATAL</code> level designates very severe error
    054         * events that will presumably lead the application to abort.
    055         */
    056        public static final Level FATAL = new Level(FATAL_INT, "FATAL", 0);
    057
    058        /**
    059         * The <code>ERROR</code> level designates error events that
    060         * might still allow the application to continue running.
    061         */
    062        public static final Level ERROR = new Level(ERROR_INT, "ERROR", 3);
    063
    064        /**
    065         * The <code>WARN</code> level designates potentially harmful situations.
    066         */
    067        public static final Level WARN = new Level(WARN_INT, "WARN", 4);
    068
    069        /**
    070         * The <code>INFO</code> level designates informational messages
    071         * that highlight the progress of the application at coarse-grained
    072         * level.
    073         */
    074        public static final Level INFO = new Level(INFO_INT, "INFO", 6);
    075
    076        /**
    077         * The <code>DEBUG</code> Level designates fine-grained
    078         * informational events that are most useful to debug an
    079         * application.
    080         */
    081        public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7);
    082
    083        /**
    084         * The <code>TRACE</code> Level designates finer-grained
    085         * informational events than the <code>DEBUG</code> level.
    086         */
    087        public static final Level TRACE = new Level(TRACE_INT, "TRACE", 7);
    088
    089        /**
    090         * The <code>ALL</code> has the lowest possible rank and is intended to
    091         * turn on all logging.
    092         */
    093        public static final Level ALL = new Level(ALL_INT, "ALL", 7);
    094
    095        /**
    096         * Serialization version id.
    097         */
    098        private static final long serialVersionUID = 3491141966387921974L;
    099
    100        /**
    101         * Instantiate a Level object.
    102         *
    103         * @param level            The logging level.
    104         * @param levelStr         The level name.
    105         * @param syslogEquivalent The matching syslog level.
    106         */
    107        protected Level(final int level, final String levelStr, final int syslogEquivalent) {
    108            super(level, levelStr, syslogEquivalent);
    109        }
    110
    111
    112        /**
    113         * Convert the string passed as argument to a level. If the
    114         * conversion fails, then this method returns {@link #DEBUG}.
    115         *
    116         * @param sArg The level name.
    117         * @return The Level.
    118         */
    119        public static Level toLevel(final String sArg) {
    120            return toLevel(sArg, Level.DEBUG);
    121        }
    122
    123        /**
    124         * Convert an integer passed as argument to a level. If the
    125         * conversion fails, then this method returns {@link #DEBUG}.
    126         *
    127         * @param val The integer value of the Level.
    128         * @return The Level.
    129         */
    130        public static Level toLevel(final int val) {
    131            return toLevel(val, Level.DEBUG);
    132        }
    133
    134        /**
    135         * Convert an integer passed as argument to a level. If the
    136         * conversion fails, then this method returns the specified default.
    137         *
    138         * @param val          The integer value of the Level.
    139         * @param defaultLevel the default level if the integer doesn't match.
    140         * @return The matching Level.
    141         */
    142        public static Level toLevel(final int val, final Level defaultLevel) {
    143            switch (val) {
    144                case ALL_INT:
    145                    return ALL;
    146                case DEBUG_INT:
    147                    return Level.DEBUG;
    148                case INFO_INT:
    149                    return Level.INFO;
    150                case WARN_INT:
    151                    return Level.WARN;
    152                case ERROR_INT:
    153                    return Level.ERROR;
    154                case FATAL_INT:
    155                    return Level.FATAL;
    156                case OFF_INT:
    157                    return OFF;
    158                case TRACE_INT:
    159                    return Level.TRACE;
    160                default:
    161                    return defaultLevel;
    162            }
    163        }
    164
    165        /**
    166         * Convert the string passed as argument to a level. If the
    167         * conversion fails, then this method returns the value of
    168         * <code>defaultLevel</code>.
    169         * @param sArg The name of the Level.
    170         * @param defaultLevel The default Level to use.
    171         * @return the matching Level.
    172         */
    173        public static Level toLevel(final String sArg, final Level defaultLevel) {
    174            if (sArg == null) {
    175                return defaultLevel;
    176            }
    177
    178            final String s = sArg.toUpperCase();
    179
    180            if (s.equals("ALL")) {
    181                return Level.ALL;
    182            }
    183            if (s.equals("DEBUG")) {
    184                return Level.DEBUG;
    185            }
    186            if (s.equals("INFO")) {
    187                return Level.INFO;
    188            }
    189            if (s.equals("WARN")) {
    190                return Level.WARN;
    191            }
    192            if (s.equals("ERROR")) {
    193                return Level.ERROR;
    194            }
    195            if (s.equals("FATAL")) {
    196                return Level.FATAL;
    197            }
    198            if (s.equals("OFF")) {
    199                return Level.OFF;
    200            }
    201            if (s.equals("TRACE")) {
    202                return Level.TRACE;
    203            }
    204            //
    205            //   For Turkish i problem, see bug 40937
    206            //
    207            if (s.equals("\u0130NFO")) {
    208                return Level.INFO;
    209            }
    210            return defaultLevel;
    211        }
    212
    213        /**
    214         * Custom deserialization of Level.
    215         *
    216         * @param s serialization stream.
    217         * @throws IOException            if IO exception.
    218         * @throws ClassNotFoundException if class not found.
    219         */
    220        private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException {
    221            s.defaultReadObject();
    222            level = s.readInt();
    223            syslogEquivalent = s.readInt();
    224            levelStr = s.readUTF();
    225            if (levelStr == null) {
    226                levelStr = Strings.EMPTY;
    227            }
    228        }
    229
    230        /**
    231         * Serialize level.
    232         *
    233         * @param s serialization stream.
    234         * @throws IOException if exception during serialization.
    235         */
    236        private void writeObject(final ObjectOutputStream s) throws IOException {
    237            s.defaultWriteObject();
    238            s.writeInt(level);
    239            s.writeInt(syslogEquivalent);
    240            s.writeUTF(levelStr);
    241        }
    242
    243        /**
    244         * Resolved deserialized level to one of the stock instances.
    245         * May be overridden in classes derived from Level.
    246         *
    247         * @return resolved object.
    248         * @throws ObjectStreamException if exception during resolution.
    249         */
    250        protected Object readResolve() throws ObjectStreamException {
    251            //
    252            //  if the deserialized object is exactly an instance of Level
    253            //
    254            if (getClass() == Level.class) {
    255                return toLevel(level);
    256            }
    257            //
    258            //   extension of Level can't substitute stock item
    259            //
    260            return this;
    261        }
    262
    263    }
    264