1 /**
2 * Copyright (c) 2004-2011 QOS.ch
3 * All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25 package org.slf4j.impl;
26
27 import org.slf4j.helpers.FormattingTuple;
28 import org.slf4j.helpers.MarkerIgnoringBase;
29 import org.slf4j.helpers.MessageFormatter;
30
31 /**
32 * A simple (and direct) implementation that logs messages of level INFO or
33 * higher on the console (<code>System.err<code>).
34 *
35 * <p>The output includes the relative time in milliseconds, thread
36 * name, the level, logger name, and the message followed by the line
37 * separator for the host. In log4j terms it amounts to the "%r [%t]
38 * %level %logger - %m%n" pattern. </p>
39 *
40 * <p>Sample output follows.</p>
41 <pre>
42 176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order.
43 225 [main] INFO examples.SortAlgo - Entered the sort method.
44 304 [main] INFO examples.SortAlgo - Dump of integer array:
45 317 [main] INFO examples.SortAlgo - Element [0] = 0
46 331 [main] INFO examples.SortAlgo - Element [1] = 1
47 343 [main] INFO examples.Sort - The next log statement should be an error message.
48 346 [main] ERROR examples.SortAlgo - Tried to dump an uninitialized array.
49 at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
50 at org.log4j.examples.Sort.main(Sort.java:64)
51 467 [main] INFO examples.Sort - Exiting main method.
52 </pre>
53 *
54 * @author Ceki Gülcü
55 */
56 public class SimpleLogger extends MarkerIgnoringBase {
57
58 private static final long serialVersionUID = -6560244151660620173L;
59
60 /**
61 * Mark the time when this class gets loaded into memory.
62 */
63 private static long startTime = System.currentTimeMillis();
64 public static final String LINE_SEPARATOR = System
65 .getProperty("line.separator");
66 private static String INFO_STR = "INFO";
67 private static String WARN_STR = "WARN";
68 private static String ERROR_STR = "ERROR";
69
70 /**
71 * Package access allows only {@link SimpleLoggerFactory} to instantiate
72 * SimpleLogger instances.
73 */
74 SimpleLogger(String name) {
75 this.name = name;
76 }
77
78 /**
79 * Always returns false.
80 *
81 * @return always false
82 */
83 public boolean isTraceEnabled() {
84 return false;
85 }
86
87 /**
88 * A NOP implementation, as this logger is permanently disabled for the TRACE
89 * level.
90 */
91 public void trace(String msg) {
92 // NOP
93 }
94
95 /**
96 * A NOP implementation, as this logger is permanently disabled for the TRACE
97 * level.
98 */
99 public void trace(String format, Object param1) {
100 // NOP
101 }
102
103 /**
104 * A NOP implementation, as this logger is permanently disabled for the TRACE
105 * level.
106 */
107 public void trace(String format, Object param1, Object param2) {
108 // NOP
109 }
110
111 public void trace(String format, Object[] argArray) {
112 // NOP
113 }
114
115 /**
116 * A NOP implementation, as this logger is permanently disabled for the TRACE
117 * level.
118 */
119 public void trace(String msg, Throwable t) {
120 // NOP
121 }
122
123 /**
124 * Always returns false.
125 *
126 * @return always false
127 */
128 public boolean isDebugEnabled() {
129 return false;
130 }
131
132 /**
133 * A NOP implementation, as this logger is permanently disabled for the DEBUG
134 * level.
135 */
136 public void debug(String msg) {
137 // NOP
138 }
139
140 /**
141 * A NOP implementation, as this logger is permanently disabled for the DEBUG
142 * level.
143 */
144 public void debug(String format, Object param1) {
145 // NOP
146 }
147
148 /**
149 * A NOP implementation, as this logger is permanently disabled for the DEBUG
150 * level.
151 */
152 public void debug(String format, Object param1, Object param2) {
153 // NOP
154 }
155
156 public void debug(String format, Object[] argArray) {
157 // NOP
158 }
159
160 /**
161 * A NOP implementation, as this logger is permanently disabled for the DEBUG
162 * level.
163 */
164 public void debug(String msg, Throwable t) {
165 // NOP
166 }
167
168 /**
169 * This is our internal implementation for logging regular (non-parameterized)
170 * log messages.
171 *
172 * @param level
173 * @param message
174 * @param t
175 */
176 private void log(String level, String message, Throwable t) {
177 StringBuffer buf = new StringBuffer();
178
179 long millis = System.currentTimeMillis();
180 buf.append(millis - startTime);
181
182 buf.append(" [");
183 buf.append(Thread.currentThread().getName());
184 buf.append("] ");
185
186 buf.append(level);
187 buf.append(" ");
188
189 buf.append(name);
190 buf.append(" - ");
191
192 buf.append(message);
193
194 buf.append(LINE_SEPARATOR);
195
196 System.err.print(buf.toString());
197 if (t != null) {
198 t.printStackTrace(System.err);
199 }
200 System.err.flush();
201 }
202
203 /**
204 * For formatted messages, first substitute arguments and then log.
205 *
206 * @param level
207 * @param format
208 * @param param1
209 * @param param2
210 */
211 private void formatAndLog(String level, String format, Object arg1,
212 Object arg2) {
213 FormattingTuple tp = MessageFormatter.format(format, arg1, arg2);
214 log(level, tp.getMessage(), tp.getThrowable());
215 }
216
217 /**
218 * For formatted messages, first substitute arguments and then log.
219 *
220 * @param level
221 * @param format
222 * @param argArray
223 */
224 private void formatAndLog(String level, String format, Object[] argArray) {
225 FormattingTuple tp = MessageFormatter.arrayFormat(format, argArray);
226 log(level, tp.getMessage(), tp.getThrowable());
227 }
228
229 /**
230 * Always returns true.
231 */
232 public boolean isInfoEnabled() {
233 return true;
234 }
235
236 /**
237 * A simple implementation which always logs messages of level INFO according
238 * to the format outlined above.
239 */
240 public void info(String msg) {
241 log(INFO_STR, msg, null);
242 }
243
244 /**
245 * Perform single parameter substitution before logging the message of level
246 * INFO according to the format outlined above.
247 */
248 public void info(String format, Object arg) {
249 formatAndLog(INFO_STR, format, arg, null);
250 }
251
252 /**
253 * Perform double parameter substitution before logging the message of level
254 * INFO according to the format outlined above.
255 */
256 public void info(String format, Object arg1, Object arg2) {
257 formatAndLog(INFO_STR, format, arg1, arg2);
258 }
259
260 /**
261 * Perform double parameter substitution before logging the message of level
262 * INFO according to the format outlined above.
263 */
264 public void info(String format, Object[] argArray) {
265 formatAndLog(INFO_STR, format, argArray);
266 }
267
268 /**
269 * Log a message of level INFO, including an exception.
270 */
271 public void info(String msg, Throwable t) {
272 log(INFO_STR, msg, t);
273 }
274
275 /**
276 * Always returns true.
277 */
278 public boolean isWarnEnabled() {
279 return true;
280 }
281
282 /**
283 * A simple implementation which always logs messages of level WARN according
284 * to the format outlined above.
285 */
286 public void warn(String msg) {
287 log(WARN_STR, msg, null);
288 }
289
290 /**
291 * Perform single parameter substitution before logging the message of level
292 * WARN according to the format outlined above.
293 */
294 public void warn(String format, Object arg) {
295 formatAndLog(WARN_STR, format, arg, null);
296 }
297
298 /**
299 * Perform double parameter substitution before logging the message of level
300 * WARN according to the format outlined above.
301 */
302 public void warn(String format, Object arg1, Object arg2) {
303 formatAndLog(WARN_STR, format, arg1, arg2);
304 }
305
306 /**
307 * Perform double parameter substitution before logging the message of level
308 * WARN according to the format outlined above.
309 */
310 public void warn(String format, Object[] argArray) {
311 formatAndLog(WARN_STR, format, argArray);
312 }
313
314 /**
315 * Log a message of level WARN, including an exception.
316 */
317 public void warn(String msg, Throwable t) {
318 log(WARN_STR, msg, t);
319 }
320
321 /**
322 * Always returns true.
323 */
324 public boolean isErrorEnabled() {
325 return true;
326 }
327
328 /**
329 * A simple implementation which always logs messages of level ERROR according
330 * to the format outlined above.
331 */
332 public void error(String msg) {
333 log(ERROR_STR, msg, null);
334 }
335
336 /**
337 * Perform single parameter substitution before logging the message of level
338 * ERROR according to the format outlined above.
339 */
340 public void error(String format, Object arg) {
341 formatAndLog(ERROR_STR, format, arg, null);
342 }
343
344 /**
345 * Perform double parameter substitution before logging the message of level
346 * ERROR according to the format outlined above.
347 */
348 public void error(String format, Object arg1, Object arg2) {
349 formatAndLog(ERROR_STR, format, arg1, arg2);
350 }
351
352 /**
353 * Perform double parameter substitution before logging the message of level
354 * ERROR according to the format outlined above.
355 */
356 public void error(String format, Object[] argArray) {
357 formatAndLog(ERROR_STR, format, argArray);
358 }
359
360 /**
361 * Log a message of level ERROR, including an exception.
362 */
363 public void error(String msg, Throwable t) {
364 log(ERROR_STR, msg, t);
365 }
366 }