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     * Mark the time when this class gets loaded into memory.
67     */
68    private static long startTime = System.currentTimeMillis();
69    public static final String LINE_SEPARATOR =
70      System.getProperty("line.separator");
71    private static String INFO_STR = "INFO";
72    private static String WARN_STR = "WARN";
73    private static String ERROR_STR = "ERROR";
74    String name;
75  
76    /**
77     * Package access allows only {@link SimpleLoggerFactory} to instantiate
78     * SimpleLogger instances.
79     */
80    SimpleLogger(String name) {
81      this.name = name;
82    }
83  
84    public String getName() {
85      return name;    
86    }
87   
88    /**
89     * Always returns false.
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
98     * the TRACE level.
99     */
100   public void trace(String msg) {
101     // NOP
102   }
103 
104   /**
105    * A NOP implementation, as this logger is permanently disabled for
106    * the TRACE level.
107    */
108   public void trace(String format, Object param1) {
109     // NOP
110   }
111 
112   
113   /**
114    * A NOP implementation, as this logger is permanently disabled for
115    * the TRACE level.
116    */
117   public void trace(String format, Object param1, Object param2) {
118     // NOP
119   }
120 
121   public void trace(String format, Object[] argArray) {
122     // NOP
123   }
124   
125   /**
126    * A NOP implementation, as this logger is permanently disabled for
127    * the TRACE level.
128    */
129   public void trace(String msg, Throwable t) {
130     // NOP
131   }
132 
133   
134   /**
135    * Always returns false.
136    * @return always false
137    */
138   public boolean isDebugEnabled() {
139     return false;
140   }
141 
142   /**
143    * A NOP implementation, as this logger is permanently disabled for
144    * the DEBUG level.
145    */
146   public void debug(String msg) {
147     // NOP
148   }
149 
150   /**
151    * A NOP implementation, as this logger is permanently disabled for
152    * the DEBUG level.
153    */
154   public void debug(String format, Object param1) {
155     // NOP
156   }
157 
158   
159   /**
160    * A NOP implementation, as this logger is permanently disabled for
161    * the DEBUG level.
162    */
163   public void debug(String format, Object param1, Object param2) {
164     // NOP
165   }
166 
167   public void debug(String format, Object[] argArray) {
168     // NOP
169   }
170   
171   /**
172    * A NOP implementation, as this logger is permanently disabled for
173    * the DEBUG level.
174    */
175   public void debug(String msg, Throwable t) {
176     // NOP
177   }
178 
179   /**
180    * This is our internal implementation for logging regular (non-parameterized)
181    * log messages.
182    *
183    * @param level
184    * @param message
185    * @param t
186    */
187   private void log(String level, String message, Throwable t) {
188     StringBuffer buf = new StringBuffer();
189 
190     long millis = System.currentTimeMillis();
191     buf.append(millis - startTime);
192 
193     buf.append(" [");
194     buf.append(Thread.currentThread().getName());
195     buf.append("] ");
196 
197     buf.append(level);
198     buf.append(" ");
199 
200     buf.append(name);
201     buf.append(" - ");
202 
203     buf.append(message);
204 
205     buf.append(LINE_SEPARATOR);
206 
207     System.err.print(buf.toString());
208     if (t != null) {
209       t.printStackTrace(System.err);
210     }
211     System.err.flush();
212   }
213 
214   /**
215    * For formatted messages, first substitute arguments and then log.
216    *
217    * @param level
218    * @param format
219    * @param param1
220    * @param param2
221    */
222   private void formatAndLog(
223     String level, String format, Object arg1, Object arg2) {
224     String message = MessageFormatter.format(format, arg1, arg2);
225     log(level, message, null);
226   }
227   
228   /**
229    * For formatted messages, first substitute arguments and then log.
230    * 
231    * @param level
232    * @param format
233    * @param argArray
234    */
235   private void formatAndLog(String level, String format, Object[] argArray) {
236     String message = MessageFormatter.arrayFormat(format, argArray);
237     log(level, message, null);
238   }
239 
240   /**
241    * Always returns true.
242    */
243   public boolean isInfoEnabled() {
244     return true;
245   }
246 
247   /**
248    * A simple implementation which always logs messages of level INFO according
249    * to the format outlined above.
250    */
251   public void info(String msg) {
252     log(INFO_STR, msg, null);
253   }
254 
255   /**
256    * Perform single parameter substitution before logging the message of level
257    * INFO according to the format outlined above.
258    */
259   public void info(String format, Object arg) {
260     formatAndLog(INFO_STR, format, arg, null);
261   }
262 
263   /**
264    * Perform double parameter substitution before logging the message of level
265    * INFO according to the format outlined above.
266    */
267   public void info(String format, Object arg1, Object arg2) {
268     formatAndLog(INFO_STR, format, arg1, arg2);
269   }
270 
271   /**
272    * Perform double parameter substitution before logging the message of level
273    * INFO according to the format outlined above.
274    */
275   public void info(String format, Object[] argArray) {
276     formatAndLog(INFO_STR, format, argArray);
277   }
278 
279 
280   /**
281    * Log a message of level INFO, including an exception.
282    */
283   public void info(String msg, Throwable t) {
284     log(INFO_STR, msg, t);
285   }
286 
287   /**
288    * Always returns true.
289    */
290   public boolean isWarnEnabled() {
291     return true;
292   }
293   
294   /**
295    * A simple implementation which always logs messages of level WARN according
296    * to the format outlined above.
297   */
298   public void warn(String msg) {
299     log(WARN_STR, msg, null);
300   }
301 
302   /**
303    * Perform single parameter substitution before logging the message of level
304    * WARN according to the format outlined above.
305    */
306   public void warn(String format, Object arg) {
307     formatAndLog(WARN_STR, format, arg, null);
308   }
309 
310   /**
311    * Perform double parameter substitution before logging the message of level
312    * WARN according to the format outlined above.
313    */
314   public void warn(String format, Object arg1, Object arg2) {
315     formatAndLog(WARN_STR, format, arg1, arg2);
316   }
317 
318   /**
319    * Perform double parameter substitution before logging the message of level
320    * WARN according to the format outlined above.
321    */
322   public void warn(String format, Object[] argArray) {
323     formatAndLog(WARN_STR, format, argArray);
324   }
325 
326   /**
327    * Log a message of level WARN, including an exception.
328    */
329   public void warn(String msg, Throwable t) {
330     log(WARN_STR, msg, t);
331   }
332 
333   /**
334    * Always returns true.
335    */
336   public boolean isErrorEnabled() {
337     return true;
338   }
339 
340   /**
341    * A simple implementation which always logs messages of level ERROR according
342    * to the format outlined above.
343    */
344   public void error(String msg) {
345     log(ERROR_STR, msg, null);
346   }
347 
348   /**
349    * Perform single parameter substitution before logging the message of level
350    * ERROR according to the format outlined above.
351    */
352   public void error(String format, Object arg) {
353     formatAndLog(ERROR_STR, format, arg, null);
354   }
355 
356   /**
357    * Perform double parameter substitution before logging the message of level
358    * ERROR according to the format outlined above.
359    */
360   public void error(String format, Object arg1, Object arg2) {
361     formatAndLog(ERROR_STR, format, arg1, arg2);
362   }
363 
364   /**
365    * Perform double parameter substitution before logging the message of level
366    * ERROR according to the format outlined above.
367    */
368   public void error(String format, Object[] argArray) {
369     formatAndLog(ERROR_STR, format, argArray);
370   }
371 
372   
373   /**
374    * Log a message of level ERROR, including an exception.
375    */
376   public void error(String msg, Throwable t) {
377     log(ERROR_STR, msg, t);
378   }
379 }