View Javadoc

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.commons.discovery.log;
18  
19  import java.io.PrintStream;
20  import java.text.DateFormat;
21  import java.text.SimpleDateFormat;
22  import java.util.Date;
23  
24  import org.apache.commons.logging.Log;
25  
26  
27  /***
28   * <p>Simple implementation of Log that sends all enabled log messages,
29   * for all defined loggers, to System.err.
30   * </p>
31   * 
32   * <p>Hacked from commons-logging SimpleLog for use in discovery.
33   * This is intended to be enough of a Log implementation to bootstrap
34   * Discovery.
35   * </p>
36   * 
37   * <p>One property: <code>org.apache.commons.discovery.log.level</code>.
38   * valid values: all, trace, debug, info, warn, error, fatal, off.
39   * </p>
40   * 
41   * @author Richard A. Sitze
42   * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
43   * @author Rod Waldhoff
44   * @author Robert Burrell Donkin
45   *
46   * @version $Id: SimpleLog.java 480374 2006-11-29 03:33:25Z niallp $
47   */
48  public class SimpleLog implements Log {
49        // ---------------------------------------------------- Log Level Constants
50  
51      /*** "Trace" level logging. */
52      public static final int LOG_LEVEL_TRACE  = 1;
53      /*** "Debug" level logging. */
54      public static final int LOG_LEVEL_DEBUG  = 2;
55      /*** "Info" level logging. */
56      public static final int LOG_LEVEL_INFO   = 3;
57      /*** "Warn" level logging. */
58      public static final int LOG_LEVEL_WARN   = 4;
59      /*** "Error" level logging. */
60      public static final int LOG_LEVEL_ERROR  = 5;
61      /*** "Fatal" level logging. */
62      public static final int LOG_LEVEL_FATAL  = 6;
63  
64      /*** Enable all logging levels */
65      public static final int LOG_LEVEL_ALL    = (LOG_LEVEL_TRACE - 1);
66  
67      /*** Enable no logging levels */
68      public static final int LOG_LEVEL_OFF    = (LOG_LEVEL_FATAL + 1);
69  
70      // ------------------------------------------------------- Class Attributes
71  
72      static protected final String PROP_LEVEL =
73          "org.apache.commons.discovery.log.level";
74  
75      /*** Include the instance name in the log message? */
76      static protected boolean showLogName = false;
77  
78      /*** Include the short name ( last component ) of the logger in the log
79          message. Default to true - otherwise we'll be lost in a flood of
80          messages without knowing who sends them.
81      */
82      static protected boolean showShortName = true;
83  
84      /*** Include the current time in the log message */
85      static protected boolean showDateTime = false;
86  
87      /*** Used to format times */
88      static protected DateFormat dateFormatter = null;
89  
90      /*** The current log level */
91      static protected int logLevel = LOG_LEVEL_INFO;
92      
93      
94      /***
95       * Use 'out' instead of 'err' for logging
96       * to keep in-sync with test messages.
97       */
98      static private PrintStream out = System.out;
99  
100     // ------------------------------------------------------------ Initializer
101 
102     // initialize class attributes
103     static {
104         if(showDateTime) {
105             dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS zzz");
106         }
107 
108         try {
109         // set log level from properties
110         String lvl = System.getProperty(PROP_LEVEL);
111 
112         if("all".equalsIgnoreCase(lvl)) {
113             setLevel(SimpleLog.LOG_LEVEL_ALL);
114         } else if("trace".equalsIgnoreCase(lvl)) {
115             setLevel(SimpleLog.LOG_LEVEL_TRACE);
116         } else if("debug".equalsIgnoreCase(lvl)) {
117             setLevel(SimpleLog.LOG_LEVEL_DEBUG);
118         } else if("info".equalsIgnoreCase(lvl)) {
119             setLevel(SimpleLog.LOG_LEVEL_INFO);
120         } else if("warn".equalsIgnoreCase(lvl)) {
121             setLevel(SimpleLog.LOG_LEVEL_WARN);
122         } else if("error".equalsIgnoreCase(lvl)) {
123             setLevel(SimpleLog.LOG_LEVEL_ERROR);
124         } else if("fatal".equalsIgnoreCase(lvl)) {
125             setLevel(SimpleLog.LOG_LEVEL_FATAL);
126         } else if("off".equalsIgnoreCase(lvl)) {
127             setLevel(SimpleLog.LOG_LEVEL_OFF);
128         }
129       } catch (SecurityException ignored) {
130       //do nothing. We get here if running discovery
131       //under a servlet with restricted security rights, and
132       //cannot read the system property.
133      //In which case, the default is what you get to keep.	
134       }
135 
136     }
137 
138     // -------------------------------------------------------- Properties
139 
140     /***
141      * <p> Set logging level. </p>
142      *
143      * @param currentLogLevel new logging level
144      */
145     public static void setLevel(int currentLogLevel) {
146         logLevel = currentLogLevel;
147     }
148 
149     /***
150      * <p> Get logging level. </p>
151      */
152     public static int getLevel() {
153         return logLevel;
154     }
155 
156     /***
157      * Is the given log level currently enabled?
158      *
159      * @param level is this level enabled?
160      */
161     protected static boolean isLevelEnabled(int level) {
162         // log level are numerically ordered so can use simple numeric
163         // comparison
164         return (level >= getLevel());
165     }
166 
167 
168 
169     // ------------------------------------------------------------- Attributes
170 
171     /*** The name of this simple log instance */
172     protected String logName = null;
173 
174     private String prefix=null;
175 
176     
177     // ------------------------------------------------------------ Constructor
178     
179     /***
180      * Construct a simple log with given name.
181      *
182      * @param name log name
183      */
184     public SimpleLog(String name) {
185         logName = name;
186     }
187 
188 
189     // -------------------------------------------------------- Logging Methods
190 
191 
192     /***
193      * <p> Do the actual logging.
194      * This method assembles the message
195      * and then prints to <code>System.err</code>.</p>
196      */
197     protected void log(int type, Object message, Throwable t) {
198         // use a string buffer for better performance
199         StringBuffer buf = new StringBuffer();
200 
201         // append date-time if so configured
202         if(showDateTime) {
203             buf.append(dateFormatter.format(new Date()));
204             buf.append(" ");
205         }
206 
207         // append a readable representation of the log leve
208         switch(type) {
209             case SimpleLog.LOG_LEVEL_TRACE: buf.append("[TRACE] "); break;
210             case SimpleLog.LOG_LEVEL_DEBUG: buf.append("[DEBUG] "); break;
211             case SimpleLog.LOG_LEVEL_INFO:  buf.append("[INFO ] "); break;
212             case SimpleLog.LOG_LEVEL_WARN:  buf.append("[WARN ] "); break;
213             case SimpleLog.LOG_LEVEL_ERROR: buf.append("[ERROR] "); break;
214             case SimpleLog.LOG_LEVEL_FATAL: buf.append("[FATAL] "); break;
215         }
216 
217         // append the name of the log instance if so configured
218      	if( showShortName) {
219             if( prefix==null ) {
220                 // cut all but the last component of the name for both styles
221                 prefix = logName.substring( logName.lastIndexOf(".") +1) + " - ";
222                 prefix = prefix.substring( prefix.lastIndexOf("/") +1) + "-";
223             }
224             buf.append( prefix );
225         } else if(showLogName) {
226             buf.append(String.valueOf(logName)).append(" - ");
227         }
228 
229         // append the message
230         buf.append(String.valueOf(message));
231 
232         // append stack trace if not null
233         if(t != null) {
234             buf.append(" <");
235             buf.append(t.toString());
236             buf.append(">");
237         }
238 
239         // print to System.err
240         out.println(buf.toString());
241         
242         if (t != null)
243             t.printStackTrace(System.err);
244     }
245 
246 
247     // -------------------------------------------------------- Log Implementation
248 
249 
250     /***
251      * <p> Log a message with debug log level.</p>
252      */
253     public final void debug(Object message) {
254         if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
255             log(SimpleLog.LOG_LEVEL_DEBUG, message, null);
256         }
257     }
258 
259 
260     /***
261      * <p> Log an error with debug log level.</p>
262      */
263     public final void debug(Object message, Throwable t) {
264         if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
265             log(SimpleLog.LOG_LEVEL_DEBUG, message, t);
266         }
267     }
268 
269 
270     /***
271      * <p> Log a message with debug log level.</p>
272      */
273     public final void trace(Object message) {
274         if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
275             log(SimpleLog.LOG_LEVEL_TRACE, message, null);
276         }
277     }
278 
279 
280     /***
281      * <p> Log an error with debug log level.</p>
282      */
283     public final void trace(Object message, Throwable t) {
284         if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
285             log(SimpleLog.LOG_LEVEL_TRACE, message, t);
286         }
287     }
288 
289 
290     /***
291      * <p> Log a message with info log level.</p>
292      */
293     public final void info(Object message) {
294         if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
295             log(SimpleLog.LOG_LEVEL_INFO,message,null);
296         }
297     }
298 
299 
300     /***
301      * <p> Log an error with info log level.</p>
302      */
303     public final void info(Object message, Throwable t) {
304         if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
305             log(SimpleLog.LOG_LEVEL_INFO, message, t);
306         }
307     }
308 
309 
310     /***
311      * <p> Log a message with warn log level.</p>
312      */
313     public final void warn(Object message) {
314         if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
315             log(SimpleLog.LOG_LEVEL_WARN, message, null);
316         }
317     }
318 
319 
320     /***
321      * <p> Log an error with warn log level.</p>
322      */
323     public final void warn(Object message, Throwable t) {
324         if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
325             log(SimpleLog.LOG_LEVEL_WARN, message, t);
326         }
327     }
328 
329 
330     /***
331      * <p> Log a message with error log level.</p>
332      */
333     public final void error(Object message) {
334         if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
335             log(SimpleLog.LOG_LEVEL_ERROR, message, null);
336         }
337     }
338 
339 
340     /***
341      * <p> Log an error with error log level.</p>
342      */
343     public final void error(Object message, Throwable t) {
344         if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
345             log(SimpleLog.LOG_LEVEL_ERROR, message, t);
346         }
347     }
348 
349 
350     /***
351      * <p> Log a message with fatal log level.</p>
352      */
353     public final void fatal(Object message) {
354         if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
355             log(SimpleLog.LOG_LEVEL_FATAL, message, null);
356         }
357     }
358 
359 
360     /***
361      * <p> Log an error with fatal log level.</p>
362      */
363     public final void fatal(Object message, Throwable t) {
364         if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
365             log(SimpleLog.LOG_LEVEL_FATAL, message, t);
366         }
367     }
368 
369 
370     /***
371      * <p> Are debug messages currently enabled? </p>
372      *
373      * <p> This allows expensive operations such as <code>String</code>
374      * concatenation to be avoided when the message will be ignored by the
375      * logger. </p>
376      */
377     public final boolean isDebugEnabled() {
378         return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG);
379     }
380 
381 
382     /***
383      * <p> Are error messages currently enabled? </p>
384      *
385      * <p> This allows expensive operations such as <code>String</code>
386      * concatenation to be avoided when the message will be ignored by the
387      * logger. </p>
388      */
389     public final boolean isErrorEnabled() {
390         return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR);
391     }
392 
393 
394     /***
395      * <p> Are fatal messages currently enabled? </p>
396      *
397      * <p> This allows expensive operations such as <code>String</code>
398      * concatenation to be avoided when the message will be ignored by the
399      * logger. </p>
400      */
401     public final boolean isFatalEnabled() {
402         return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL);
403     }
404 
405 
406     /***
407      * <p> Are info messages currently enabled? </p>
408      *
409      * <p> This allows expensive operations such as <code>String</code>
410      * concatenation to be avoided when the message will be ignored by the
411      * logger. </p>
412      */
413     public final boolean isInfoEnabled() {
414         return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO);
415     }
416 
417 
418     /***
419      * <p> Are trace messages currently enabled? </p>
420      *
421      * <p> This allows expensive operations such as <code>String</code>
422      * concatenation to be avoided when the message will be ignored by the
423      * logger. </p>
424      */
425     public final boolean isTraceEnabled() {
426         return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE);
427     }
428 
429 
430     /***
431      * <p> Are warn messages currently enabled? </p>
432      *
433      * <p> This allows expensive operations such as <code>String</code>
434      * concatenation to be avoided when the message will be ignored by the
435      * logger. </p>
436      */
437     public final boolean isWarnEnabled() {
438         return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN);
439     }
440 }