1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache license, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the license for the specific language governing permissions and
15 * limitations under the license.
16 */
17 package org.apache.log4j;
18
19 import java.io.IOException;
20 import java.io.ObjectInputStream;
21 import java.io.ObjectOutputStream;
22 import java.io.ObjectStreamException;
23 import java.io.Serializable;
24
25 import org.apache.logging.log4j.util.Strings;
26
27 /**
28 * Defines the minimum set of levels recognized by the system, that is
29 * <code>OFF</code>, <code>FATAL</code>, <code>ERROR</code>,
30 * <code>WARN</code>, <code>INFO</code>, <code>DEBUG</code>
31 * and <code>ALL</code>.
32 * <p>
33 * The <code>Level</code> class may be subclassed to define a larger
34 * level set.
35 * </p>
36 */
37 public class Level extends Priority implements Serializable {
38
39 /**
40 * TRACE level integer value.
41 *
42 * @since 1.2.12
43 */
44 public static final int TRACE_INT = 5000;
45
46 /**
47 * The <code>OFF</code> has the highest possible rank and is
48 * intended to turn off logging.
49 */
50 public static final Level OFF = new Level(OFF_INT, "OFF", 0);
51
52 /**
53 * The <code>FATAL</code> level designates very severe error
54 * events that will presumably lead the application to abort.
55 */
56 public static final Level FATAL = new Level(FATAL_INT, "FATAL", 0);
57
58 /**
59 * The <code>ERROR</code> level designates error events that
60 * might still allow the application to continue running.
61 */
62 public static final Level ERROR = new Level(ERROR_INT, "ERROR", 3);
63
64 /**
65 * The <code>WARN</code> level designates potentially harmful situations.
66 */
67 public static final Level WARN = new Level(WARN_INT, "WARN", 4);
68
69 /**
70 * The <code>INFO</code> level designates informational messages
71 * that highlight the progress of the application at coarse-grained
72 * level.
73 */
74 public static final Level INFO = new Level(INFO_INT, "INFO", 6);
75
76 /**
77 * The <code>DEBUG</code> Level designates fine-grained
78 * informational events that are most useful to debug an
79 * application.
80 */
81 public static final Level DEBUG = new Level(DEBUG_INT, "DEBUG", 7);
82
83 /**
84 * The <code>TRACE</code> Level designates finer-grained
85 * informational events than the <code>DEBUG</code> level.
86 */
87 public static final Level TRACE = new Level(TRACE_INT, "TRACE", 7);
88
89 /**
90 * The <code>ALL</code> has the lowest possible rank and is intended to
91 * turn on all logging.
92 */
93 public static final Level ALL = new Level(ALL_INT, "ALL", 7);
94
95 /**
96 * Serialization version id.
97 */
98 private static final long serialVersionUID = 3491141966387921974L;
99
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