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