001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.classic;
015
016import org.slf4j.event.EventConstants;
017import org.slf4j.spi.LocationAwareLogger;
018
019/**
020 * Defines the set of levels recognized by logback-classic, that is
021 * {@link #OFF}, {@link #ERROR}, {@link #WARN}, {@link #INFO}, {@link #DEBUG},
022 * {@link #TRACE} and {@link #ALL}.
023 * <p/>
024 * The <code>Level</code> class is final and cannot be sub-classed.
025 * </p>
026 */
027public final class Level implements java.io.Serializable {
028
029    private static final long serialVersionUID = -814092767334282137L;
030
031    public static final int OFF_INT = Integer.MAX_VALUE;
032    public static final int ERROR_INT = 40000;
033    public static final int WARN_INT = 30000;
034    public static final int INFO_INT = 20000;
035    public static final int DEBUG_INT = 10000;
036    public static final int TRACE_INT = 5000;
037    public static final int ALL_INT = Integer.MIN_VALUE;
038
039    public static final Integer OFF_INTEGER = OFF_INT;
040    public static final Integer ERROR_INTEGER = ERROR_INT;
041    public static final Integer WARN_INTEGER = WARN_INT;
042    public static final Integer INFO_INTEGER = INFO_INT;
043    public static final Integer DEBUG_INTEGER = DEBUG_INT;
044    public static final Integer TRACE_INTEGER = TRACE_INT;
045    public static final Integer ALL_INTEGER = ALL_INT;
046
047    /**
048     * The <code>OFF</code> is used to turn off logging.
049     */
050    public static final Level OFF = new Level(OFF_INT, "OFF");
051
052    /**
053     * The <code>ERROR</code> level designates error events which may or not be
054     * fatal to the application.
055     */
056    public static final Level ERROR = new Level(ERROR_INT, "ERROR");
057
058    /**
059     * The <code>WARN</code> level designates potentially harmful situations.
060     */
061    public static final Level WARN = new Level(WARN_INT, "WARN");
062
063    /**
064     * The <code>INFO</code> level designates informational messages highlighting
065     * overall progress of the application.
066     */
067    public static final Level INFO = new Level(INFO_INT, "INFO");
068
069    /**
070     * The <code>DEBUG</code> level designates informational events of lower
071     * importance.
072     */
073    public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG");
074
075    /**
076     * The <code>TRACE</code> level designates informational events of very low
077     * importance.
078     */
079    public static final Level TRACE = new Level(TRACE_INT, "TRACE");
080
081    /**
082     * The <code>ALL</code> is used to turn on all logging.
083     */
084    public static final Level ALL = new Level(ALL_INT, "ALL");
085
086    public final int levelInt;
087    public final String levelStr;
088
089    /**
090     * Instantiate a Level object.
091     */
092    private Level(int levelInt, String levelStr) {
093        this.levelInt = levelInt;
094        this.levelStr = levelStr;
095    }
096
097    /**
098     * Returns the string representation of this Level.
099     */
100    public String toString() {
101        return levelStr;
102    }
103
104    /**
105     * Returns the integer representation of this Level.
106     */
107    public int toInt() {
108        return levelInt;
109    }
110
111    static public Level convertAnSLF4JLevel(org.slf4j.event.Level slf4jLevel) {
112        final int levelInt = slf4jLevel.toInt();
113        return fromLocationAwareLoggerInteger(levelInt);
114    }
115
116    /**
117     * Convert a Level to an Integer object.
118     *
119     * @return This level's Integer mapping.
120     */
121    public Integer toInteger() {
122        switch (levelInt) {
123        case ALL_INT:
124            return ALL_INTEGER;
125        case TRACE_INT:
126            return TRACE_INTEGER;
127        case DEBUG_INT:
128            return DEBUG_INTEGER;
129        case INFO_INT:
130            return INFO_INTEGER;
131        case WARN_INT:
132            return WARN_INTEGER;
133        case ERROR_INT:
134            return ERROR_INTEGER;
135        case OFF_INT:
136            return OFF_INTEGER;
137        default:
138            throw new IllegalStateException("Level " + levelStr + ", " + levelInt + " is unknown.");
139        }
140    }
141
142    /**
143     * Returns <code>true</code> if this Level has a higher or equal Level than the
144     * Level passed as argument, <code>false</code> otherwise.
145     */
146    public boolean isGreaterOrEqual(Level r) {
147        return levelInt >= r.levelInt;
148    }
149
150    /**
151     * Convert the string passed as argument to a Level. If the conversion fails,
152     * then this method returns {@link #DEBUG}.
153     */
154    public static Level toLevel(String sArg) {
155        return toLevel(sArg, Level.DEBUG);
156    }
157
158    /**
159     * This method exists in order to comply with Joran's valueOf convention.
160     *
161     * @param sArg
162     * @return
163     */
164    public static Level valueOf(String sArg) {
165        return toLevel(sArg, Level.DEBUG);
166    }
167
168    /**
169     * Convert an integer passed as argument to a Level. If the conversion fails,
170     * then this method returns {@link #DEBUG}.
171     */
172    public static Level toLevel(int val) {
173        return toLevel(val, Level.DEBUG);
174    }
175
176    /**
177     * Convert an integer passed as argument to a Level. If the conversion fails,
178     * then this method returns the specified default.
179     */
180    public static Level toLevel(int val, Level defaultLevel) {
181        switch (val) {
182        case ALL_INT:
183            return ALL;
184        case TRACE_INT:
185            return TRACE;
186        case DEBUG_INT:
187            return DEBUG;
188        case INFO_INT:
189            return INFO;
190        case WARN_INT:
191            return WARN;
192        case ERROR_INT:
193            return ERROR;
194        case OFF_INT:
195            return OFF;
196        default:
197            return defaultLevel;
198        }
199    }
200
201    /**
202     * Convert the string passed as argument to a Level. If the conversion fails,
203     * then this method returns the value of <code>defaultLevel</code>.
204     */
205    public static Level toLevel(final String sArg, Level defaultLevel) {
206        if (sArg == null) {
207            return defaultLevel;
208        }
209
210        // see LOGBACK-1288
211        final String in = sArg.trim();
212
213        if (in.equalsIgnoreCase("ALL")) {
214            return Level.ALL;
215        }
216        if (in.equalsIgnoreCase("TRACE")) {
217            return Level.TRACE;
218        }
219        if (in.equalsIgnoreCase("DEBUG")) {
220            return Level.DEBUG;
221        }
222        if (in.equalsIgnoreCase("INFO")) {
223            return Level.INFO;
224        }
225        if (in.equalsIgnoreCase("WARN")) {
226            return Level.WARN;
227        }
228        if (in.equalsIgnoreCase("ERROR")) {
229            return Level.ERROR;
230        }
231        if (in.equalsIgnoreCase("OFF")) {
232            return Level.OFF;
233        }
234        return defaultLevel;
235    }
236
237    /**
238     * Return the flyweight instance of the level received through serialization,
239     * i.e. 'this'.
240     *
241     * @return The appropriate flyweight instance
242     */
243    private Object readResolve() {
244        return toLevel(this.levelInt);
245    }
246
247    /**
248     * Convert one of the integer values defined in {@link LocationAwareLogger}
249     * interface to an instance of this class, i.e. a Level.
250     *
251     * @param levelInt An integer value representing a level as defined in
252     *                 LocationAwareLogger
253     * @return an instance of this class, i.e. a Level.
254     * @since 1.0.1
255     */
256    public static Level fromLocationAwareLoggerInteger(int levelInt) {
257        Level level;
258        switch (levelInt) {
259        case EventConstants.TRACE_INT:
260            level = TRACE;
261            break;
262        case EventConstants.DEBUG_INT:
263            level = DEBUG;
264            break;
265        case EventConstants.INFO_INT:
266            level = INFO;
267            break;
268        case EventConstants.WARN_INT:
269            level = WARN;
270            break;
271        case EventConstants.ERROR_INT:
272            level = ERROR;
273            break;
274        default:
275            throw new IllegalArgumentException(levelInt + " not a valid level value");
276        }
277        return level;
278    }
279
280    /**
281     * Convert this level instance to an integer value defined in the
282     * {@link LocationAwareLogger} interface.
283     *
284     * @param level The level to convert to LocationAwareLogger integer
285     * @return int An integer corresponding to this level as defined in
286     *         LocationAwareLogger
287     * @since 1.0.1
288     */
289    public static int toLocationAwareLoggerInteger(Level level) {
290        if (level == null)
291            throw new IllegalArgumentException("null level parameter is not admitted");
292        switch (level.toInt()) {
293        case Level.TRACE_INT:
294            return EventConstants.TRACE_INT;
295        case Level.DEBUG_INT:
296            return EventConstants.DEBUG_INT;
297        case Level.INFO_INT:
298            return EventConstants.INFO_INT;
299        case Level.WARN_INT:
300            return EventConstants.WARN_INT;
301        case Level.ERROR_INT:
302            return EventConstants.ERROR_INT;
303        default:
304            throw new IllegalArgumentException(level + " not a valid level value");
305        }
306    }
307}