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.MarkerIgnoringBase;
37  import org.slf4j.helpers.MessageFormatter;
38  
39  /**
40   * A simple (and direct) implementation that logs messages of level
41   * INFO or higher on the console (<code>System.err<code>).
42   *
43   * <p>The output includes the relative time in milliseconds, thread
44   * name, the level, logger name, and the message followed by the line
45   * separator for the host.  In log4j terms it amounts to the "%r [%t]
46   * %level %logger - %m%n" pattern. </p>
47   *
48   * <p>Sample output follows.</p>
49  <pre>
50  176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse order.
51  225 [main] INFO examples.SortAlgo - Entered the sort method.
52  304 [main] INFO examples.SortAlgo - Dump of integer array:
53  317 [main] INFO examples.SortAlgo - Element [0] = 0
54  331 [main] INFO examples.SortAlgo - Element [1] = 1
55  343 [main] INFO examples.Sort - The next log statement should be an error message.
56  346 [main] ERROR examples.SortAlgo - Tried to dump an uninitialized array.
57          at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
58          at org.log4j.examples.Sort.main(Sort.java:64)
59  467 [main] INFO  examples.Sort - Exiting main method.
60  </pre>
61   *
62   * @author Ceki G&uuml;lc&uuml;
63   */
64  public class SimpleLogger extends MarkerIgnoringBase {
65    
66    private static final long serialVersionUID = -6560244151660620173L;
67   
68    /**
69     * Mark the time when this class gets loaded into memory.
70     */
71    private static long startTime = System.currentTimeMillis();
72    public static final String LINE_SEPARATOR =
73      System.getProperty("line.separator");
74    private static String INFO_STR = "INFO";
75    private static String WARN_STR = "WARN";
76    private static String ERROR_STR = "ERROR";
77  
78    /**
79     * Package access allows only {@link SimpleLoggerFactory} to instantiate
80     * SimpleLogger instances.
81     */
82    SimpleLogger(String name) {
83      this.name = name;
84    }
85  
86    /**
87     * Always returns false.
88     * @return always false
89     */
90    public boolean isTraceEnabled() {
91      return false;
92    }
93  
94    /**
95     * A NOP implementation, as this logger is permanently disabled for
96     * the TRACE level.
97     */
98    public void trace(String msg) {
99      // NOP
100   }
101 
102   /**
103    * A NOP implementation, as this logger is permanently disabled for
104    * the TRACE level.
105    */
106   public void trace(String format, Object param1) {
107     // NOP
108   }
109 
110   
111   /**
112    * A NOP implementation, as this logger is permanently disabled for
113    * the TRACE level.
114    */
115   public void trace(String format, Object param1, Object param2) {
116     // NOP
117   }
118 
119   public void trace(String format, Object[] argArray) {
120     // NOP
121   }
122   
123   /**
124    * A NOP implementation, as this logger is permanently disabled for
125    * the TRACE level.
126    */
127   public void trace(String msg, Throwable t) {
128     // NOP
129   }
130 
131   
132   /**
133    * Always returns false.
134    * @return always false
135    */
136   public boolean isDebugEnabled() {
137     return false;
138   }
139 
140   /**
141    * A NOP implementation, as this logger is permanently disabled for
142    * the DEBUG level.
143    */
144   public void debug(String msg) {
145     // NOP
146   }
147 
148   /**
149    * A NOP implementation, as this logger is permanently disabled for
150    * the DEBUG level.
151    */
152   public void debug(String format, Object param1) {
153     // NOP
154   }
155 
156   
157   /**
158    * A NOP implementation, as this logger is permanently disabled for
159    * the DEBUG 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
171    * the DEBUG 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(
221     String level, String format, Object arg1, Object arg2) {
222     String message = MessageFormatter.format(format, arg1, arg2);
223     log(level, message, null);
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     String message = MessageFormatter.arrayFormat(format, argArray);
235     log(level, message, null);
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   /**
279    * Log a message of level INFO, including an exception.
280    */
281   public void info(String msg, Throwable t) {
282     log(INFO_STR, msg, t);
283   }
284 
285   /**
286    * Always returns true.
287    */
288   public boolean isWarnEnabled() {
289     return true;
290   }
291   
292   /**
293    * A simple implementation which always logs messages of level WARN according
294    * to the format outlined above.
295   */
296   public void warn(String msg) {
297     log(WARN_STR, msg, null);
298   }
299 
300   /**
301    * Perform single parameter substitution before logging the message of level
302    * WARN according to the format outlined above.
303    */
304   public void warn(String format, Object arg) {
305     formatAndLog(WARN_STR, format, arg, null);
306   }
307 
308   /**
309    * Perform double parameter substitution before logging the message of level
310    * WARN according to the format outlined above.
311    */
312   public void warn(String format, Object arg1, Object arg2) {
313     formatAndLog(WARN_STR, format, arg1, arg2);
314   }
315 
316   /**
317    * Perform double parameter substitution before logging the message of level
318    * WARN according to the format outlined above.
319    */
320   public void warn(String format, Object[] argArray) {
321     formatAndLog(WARN_STR, format, argArray);
322   }
323 
324   /**
325    * Log a message of level WARN, including an exception.
326    */
327   public void warn(String msg, Throwable t) {
328     log(WARN_STR, msg, t);
329   }
330 
331   /**
332    * Always returns true.
333    */
334   public boolean isErrorEnabled() {
335     return true;
336   }
337 
338   /**
339    * A simple implementation which always logs messages of level ERROR according
340    * to the format outlined above.
341    */
342   public void error(String msg) {
343     log(ERROR_STR, msg, null);
344   }
345 
346   /**
347    * Perform single parameter substitution before logging the message of level
348    * ERROR according to the format outlined above.
349    */
350   public void error(String format, Object arg) {
351     formatAndLog(ERROR_STR, format, arg, null);
352   }
353 
354   /**
355    * Perform double parameter substitution before logging the message of level
356    * ERROR according to the format outlined above.
357    */
358   public void error(String format, Object arg1, Object arg2) {
359     formatAndLog(ERROR_STR, format, arg1, arg2);
360   }
361 
362   /**
363    * Perform double parameter substitution before logging the message of level
364    * ERROR according to the format outlined above.
365    */
366   public void error(String format, Object[] argArray) {
367     formatAndLog(ERROR_STR, format, argArray);
368   }
369 
370   
371   /**
372    * Log a message of level ERROR, including an exception.
373    */
374   public void error(String msg, Throwable t) {
375     log(ERROR_STR, msg, t);
376   }
377 }