KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > logicalcobwebs > logging > impl > SimpleLog


1 /*
2  * $Header: /cvsroot/proxool/proxool/src/java/org/logicalcobwebs/logging/impl/SimpleLog.java,v 1.3 2003/03/11 00:02:10 billhorsman Exp $
3  * $Revision: 1.3 $
4  * $Date: 2003/03/11 00:02:10 $
5  *
6  * ====================================================================
7  *
8  * The Apache Software License, Version 1.1
9  *
10  * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
11  * reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  *
17  * 1. Redistributions of source code must retain the above copyright
18  * notice, this list of conditions and the following disclaimer.
19  *
20  * 2. Redistributions in binary form must reproduce the above copyright
21  * notice, this list of conditions and the following disclaimer in
22  * the documentation and/or other materials provided with the
23  * distribution.
24  *
25  * 3. The end-user documentation included with the redistribution, if
26  * any, must include the following acknowlegement:
27  * "This product includes software developed by the
28  * Apache Software Foundation (http://www.apache.org/)."
29  * Alternately, this acknowlegement may appear in the software itself,
30  * if and wherever such third-party acknowlegements normally appear.
31  *
32  * 4. The names "The Jakarta Project", "Commons", and "Apache Software
33  * Foundation" must not be used to endorse or promote products derived
34  * from this software without prior written permission. For written
35  * permission, please contact apache@apache.org.
36  *
37  * 5. Products derived from this software may not be called "Apache"
38  * nor may "Apache" appear in their names without prior written
39  * permission of the Apache Group.
40  *
41  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
42  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
45  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
48  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52  * SUCH DAMAGE.
53  * ====================================================================
54  *
55  * This software consists of voluntary contributions made by many
56  * individuals on behalf of the Apache Software Foundation. For more
57  * information on the Apache Software Foundation, please see
58  * <http://www.apache.org/>.
59  *
60  */

61
62 package org.logicalcobwebs.logging.impl;
63
64 import org.logicalcobwebs.logging.Log;
65
66 import java.io.InputStream;
67 import java.lang.reflect.Method;
68 import java.security.AccessControlException;
69 import java.text.DateFormat;
70 import java.text.SimpleDateFormat;
71 import java.util.Date;
72 import java.util.Enumeration;
73 import java.util.Properties;
74
75 /**
76  * <p>Simple implementation of Log that sends all enabled log messages,
77  * for all defined loggers, to System.err. The following system properties
78  * are supported to configure the behavior of this logger:</p>
79  * <ul>
80  * <li><code>org.apache.commons.logging.simplelog.defaultlog</code> -
81  * Default logging detail level for all instances of SimpleLog.
82  * Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
83  * If not specified, defaults to "info". </li>
84  * <li><code>org.apache.commons.logging.simplelog.log.xxxxx</code> -
85  * Logging detail level for a SimpleLog instance named "xxxxx".
86  * Must be one of ("trace", "debug", "info", "warn", "error", or "fatal").
87  * If not specified, the default logging detail level is used.</li>
88  * <li><code>org.apache.commons.logging.simplelog.showlogname</code> -
89  * Set to <code>true</code> if you want the Log instance name to be
90  * included in output messages. Defaults to false</li>
91  * <li><code>org.apache.commons.logging.simplelog.showShortLogname</code> -
92  * Set to <code>true</code> if you want the last componet of the name to be
93  * included in output messages. Defaults to true.</li>
94  * <li><code>org.apache.commons.logging.simplelog.showdatetime</code> -
95  * Set to <code>true</code> if you want the current date and time
96  * to be included in output messages. Default is false.</li>
97  * </ul>
98  *
99  * <p>In addition to looking for system properties with the names specified
100  * above, this implementation also checks for a class loader resource named
101  * <code>"simplelog.properties"</code>, and includes any matching definitions
102  * from this resource (if it exists).</p>
103  *
104  * @author <a HREF="mailto:sanders@apache.org">Scott Sanders</a>
105  * @author Rod Waldhoff
106  * @author Robert Burrell Donkin
107  *
108  * @version $Id: SimpleLog.java,v 1.3 2003/03/11 00:02:10 billhorsman Exp $
109  */

110 public class SimpleLog implements Log {
111
112     // ------------------------------------------------------- Class Attributes
113

114     /** All system properties used by <code>Simple</code> start with this */
115     protected static final String SYSTEM_PREFIX =
116             "org.apache.commons.logging.simplelog.";
117
118     /** All system properties which start with {@link #SYSTEM_PREFIX} */
119     protected static final Properties SIMLE_LOG_PROPS = new Properties ();
120     /** Include the instance name in the log message? */
121     private static boolean showLogName = false;
122     /** Include the short name (last component) of the logger in the log
123      message. Default to true - otherwise we'll be lost in a flood of
124      messages without knowing who sends them.
125      */

126     private static boolean showShortName = true;
127     /** Include the current time in the log message */
128     private static boolean showDateTime = false;
129     /** Used to format times */
130     private static DateFormat dateFormatter = null;
131
132     // ---------------------------------------------------- Log Level Constants
133

134
135     /** "Trace" level logging. */
136     public static final int LOG_LEVEL_TRACE = 1;
137     /** "Debug" level logging. */
138     public static final int LOG_LEVEL_DEBUG = 2;
139     /** "Info" level logging. */
140     public static final int LOG_LEVEL_INFO = 3;
141     /** "Warn" level logging. */
142     public static final int LOG_LEVEL_WARN = 4;
143     /** "Error" level logging. */
144     public static final int LOG_LEVEL_ERROR = 5;
145     /** "Fatal" level logging. */
146     public static final int LOG_LEVEL_FATAL = 6;
147
148     /** Enable all logging levels */
149     public static final int LOG_LEVEL_ALL = (LOG_LEVEL_TRACE - 1);
150
151     /** Enable no logging levels */
152     public static final int LOG_LEVEL_OFF = (LOG_LEVEL_FATAL + 1);
153
154     // ------------------------------------------------------------ Initializer
155

156     // initialize class attributes
157
static {
158
159         try {
160             // add all system props that start with the specified prefix
161
Enumeration enum = System.getProperties ().propertyNames ();
162             while (enum.hasMoreElements ()) {
163                 String name = (String) (enum.nextElement ());
164                 if (null != name && name.startsWith (SYSTEM_PREFIX)) {
165                     SIMLE_LOG_PROPS.setProperty (name, System.getProperty (name));
166                 }
167             }
168
169             // identify the class loader to attempt resource loading with
170
ClassLoader classLoader = null;
171             try {
172                 Method method =
173                         Thread.class.getMethod ("getContextClassLoader", null);
174                 classLoader = (ClassLoader)
175                         method.invoke (Thread.currentThread (), null);
176             } catch (Exception e) {
177                 ; // Ignored (security exception or JDK 1.1)
178
}
179             if (classLoader == null) {
180                 classLoader = SimpleLog.class.getClassLoader ();
181             }
182
183             // add props from the resource simplelog.properties
184
InputStream in =
185                     classLoader.getResourceAsStream ("simplelog.properties");
186             if (null != in) {
187                 try {
188                     SIMLE_LOG_PROPS.load (in);
189                     in.close ();
190                 } catch (java.io.IOException e) {
191                     // ignored
192
}
193             }
194
195             /* That's a strange way to set properties. If the property
196                is not set, we'll override the default
197
198                 showLogName = "true".equalsIgnoreCase(
199                         SIMLE_LOG_PROPS.getProperty(
200                         SYSTEM_PREFIX + "showlogname","true"));
201             */

202
203             String prop = SIMLE_LOG_PROPS.getProperty (SYSTEM_PREFIX + "showlogname");
204
205             if (prop != null) {
206                 showLogName = "true".equalsIgnoreCase (prop);
207             }
208
209             prop = SIMLE_LOG_PROPS.getProperty (SYSTEM_PREFIX + "showShortLogname");
210             if (prop != null) {
211                 showShortName = "true".equalsIgnoreCase (prop);
212             }
213
214             prop = SIMLE_LOG_PROPS.getProperty (SYSTEM_PREFIX + "showdatetime");
215             if (prop != null) {
216                 showDateTime = "true".equalsIgnoreCase (prop);
217             }
218
219             if (showDateTime) {
220                 dateFormatter = new SimpleDateFormat (
221                         SIMLE_LOG_PROPS.getProperty (
222                                 SYSTEM_PREFIX + "dateformat", "yyyy/MM/dd HH:mm:ss:SSS zzz"));
223             }
224         } catch (AccessControlException e) {
225             // ignore access control exceptions when trying to check system properties
226
}
227     }
228
229
230     // ------------------------------------------------------------- Attributes
231

232     /** The name of this simple log instance */
233     private String logName = null;
234     /** The current log level */
235     private int currentLogLevel;
236
237     private String prefix = null;
238
239
240     // ------------------------------------------------------------ Constructor
241

242     /**
243      * Construct a simple log with given name.
244      *
245      * @param name log name
246      */

247     public SimpleLog (String name) {
248
249         logName = name;
250
251         // set initial log level
252
// Used to be: set default log level to ERROR
253
// IMHO it should be lower, but at least info (costin).
254
setLevel (SimpleLog.LOG_LEVEL_INFO);
255
256         // set log level from properties
257
String lvl = SIMLE_LOG_PROPS.getProperty (SYSTEM_PREFIX + "log." + logName);
258         int i = String.valueOf (name).lastIndexOf (".");
259         while (null == lvl && i > -1) {
260             name = name.substring (0, i);
261             lvl = SIMLE_LOG_PROPS.getProperty (SYSTEM_PREFIX + "log." + name);
262             i = String.valueOf (name).lastIndexOf (".");
263         }
264
265         if (null == lvl) {
266             lvl = SIMLE_LOG_PROPS.getProperty (SYSTEM_PREFIX + "defaultlog");
267         }
268
269         if ("all".equalsIgnoreCase (lvl)) {
270             setLevel (SimpleLog.LOG_LEVEL_ALL);
271         } else if ("trace".equalsIgnoreCase (lvl)) {
272             setLevel (SimpleLog.LOG_LEVEL_TRACE);
273         } else if ("debug".equalsIgnoreCase (lvl)) {
274             setLevel (SimpleLog.LOG_LEVEL_DEBUG);
275         } else if ("info".equalsIgnoreCase (lvl)) {
276             setLevel (SimpleLog.LOG_LEVEL_INFO);
277         } else if ("warn".equalsIgnoreCase (lvl)) {
278             setLevel (SimpleLog.LOG_LEVEL_WARN);
279         } else if ("error".equalsIgnoreCase (lvl)) {
280             setLevel (SimpleLog.LOG_LEVEL_ERROR);
281         } else if ("fatal".equalsIgnoreCase (lvl)) {
282             setLevel (SimpleLog.LOG_LEVEL_FATAL);
283         } else if ("off".equalsIgnoreCase (lvl)) {
284             setLevel (SimpleLog.LOG_LEVEL_OFF);
285         }
286
287     }
288
289
290     // -------------------------------------------------------- Properties
291

292     /**
293      * <p> Set logging level. </p>
294      *
295      * @param currentLogLevel new logging level
296      */

297     public void setLevel (int currentLogLevel) {
298
299         this.currentLogLevel = currentLogLevel;
300
301     }
302
303     /**
304      * <p> Get logging level. </p>
305      */

306     public int getLevel () {
307
308         return currentLogLevel;
309     }
310
311
312     // -------------------------------------------------------- Logging Methods
313

314
315     /**
316      * <p> Do the actual logging.
317      * This method assembles the message
318      * and then prints to <code>System.err</code>.</p>
319      */

320     protected void log (int type, Object message, Throwable t) {
321         // use a string buffer for better performance
322
StringBuffer buf = new StringBuffer ();
323
324         // append date-time if so configured
325
if (showDateTime) {
326             buf.append (dateFormatter.format (new Date ()));
327             buf.append (" ");
328         }
329
330         // append a readable representation of the log leve
331
switch (type) {
332             case SimpleLog.LOG_LEVEL_TRACE:
333                 buf.append ("[TRACE] ");
334                 break;
335             case SimpleLog.LOG_LEVEL_DEBUG:
336                 buf.append ("[DEBUG] ");
337                 break;
338             case SimpleLog.LOG_LEVEL_INFO:
339                 buf.append ("[INFO] ");
340                 break;
341             case SimpleLog.LOG_LEVEL_WARN:
342                 buf.append ("[WARN] ");
343                 break;
344             case SimpleLog.LOG_LEVEL_ERROR:
345                 buf.append ("[ERROR] ");
346                 break;
347             case SimpleLog.LOG_LEVEL_FATAL:
348                 buf.append ("[FATAL] ");
349                 break;
350         }
351
352         // append the name of the log instance if so configured
353
if (showShortName) {
354             if (prefix == null) {
355 // cut all but the last component of the name for both styles
356
prefix = logName.substring (logName.lastIndexOf (".") + 1) + " - ";
357                 prefix = prefix.substring (prefix.lastIndexOf ("/") + 1) + "-";
358             }
359             buf.append (prefix);
360         } else if (showLogName) {
361             buf.append (String.valueOf (logName)).append (" - ");
362         }
363
364         // append the message
365
buf.append (String.valueOf (message));
366
367         // append stack trace if not null
368
if (t != null) {
369             buf.append (" <");
370             buf.append (t.toString ());
371             buf.append (">");
372             t.printStackTrace ();
373         }
374
375         // print to System.err
376
System.err.println (buf.toString ());
377     }
378
379     /**
380      * Is the given log level currently enabled?
381      *
382      * @param logLevel is this level enabled?
383      */

384     protected boolean isLevelEnabled (int logLevel) {
385         // log level are numerically ordered so can use simple numeric
386
// comparison
387
return (logLevel >= currentLogLevel);
388     }
389
390
391     // -------------------------------------------------------- Log Implementation
392

393
394     /**
395      * <p> Log a message with debug log level.</p>
396      */

397     public final void debug (Object message) {
398
399         if (isLevelEnabled (SimpleLog.LOG_LEVEL_DEBUG)) {
400             log (SimpleLog.LOG_LEVEL_DEBUG, message, null);
401         }
402     }
403
404     /**
405      * <p> Log an error with debug log level.</p>
406      */

407     public final void debug (Object message, Throwable t) {
408
409         if (isLevelEnabled (SimpleLog.LOG_LEVEL_DEBUG)) {
410             log (SimpleLog.LOG_LEVEL_DEBUG, message, t);
411         }
412     }
413
414     /**
415      * <p> Log a message with debug log level.</p>
416      */

417     public final void trace (Object message) {
418
419         if (isLevelEnabled (SimpleLog.LOG_LEVEL_TRACE)) {
420             log (SimpleLog.LOG_LEVEL_TRACE, message, null);
421         }
422     }
423
424     /**
425      * <p> Log an error with debug log level.</p>
426      */

427     public final void trace (Object message, Throwable t) {
428
429         if (isLevelEnabled (SimpleLog.LOG_LEVEL_TRACE)) {
430             log (SimpleLog.LOG_LEVEL_TRACE, message, t);
431         }
432     }
433
434     /**
435      * <p> Log a message with info log level.</p>
436      */

437     public final void info (Object message) {
438
439         if (isLevelEnabled (SimpleLog.LOG_LEVEL_INFO)) {
440             log (SimpleLog.LOG_LEVEL_INFO, message, null);
441         }
442     }
443
444     /**
445      * <p> Log an error with info log level.</p>
446      */

447     public final void info (Object message, Throwable t) {
448
449         if (isLevelEnabled (SimpleLog.LOG_LEVEL_INFO)) {
450             log (SimpleLog.LOG_LEVEL_INFO, message, t);
451         }
452     }
453
454     /**
455      * <p> Log a message with warn log level.</p>
456      */

457     public final void warn (Object message) {
458
459         if (isLevelEnabled (SimpleLog.LOG_LEVEL_WARN)) {
460             log (SimpleLog.LOG_LEVEL_WARN, message, null);
461         }
462     }
463
464     /**
465      * <p> Log an error with warn log level.</p>
466      */

467     public final void warn (Object message, Throwable t) {
468
469         if (isLevelEnabled (SimpleLog.LOG_LEVEL_WARN)) {
470             log (SimpleLog.LOG_LEVEL_WARN, message, t);
471         }
472     }
473
474     /**
475      * <p> Log a message with error log level.</p>
476      */

477     public final void error (Object message) {
478
479         if (isLevelEnabled (SimpleLog.LOG_LEVEL_ERROR)) {
480             log (SimpleLog.LOG_LEVEL_ERROR, message, null);
481         }
482     }
483
484     /**
485      * <p> Log an error with error log level.</p>
486      */

487     public final void error (Object message, Throwable t) {
488
489         if (isLevelEnabled (SimpleLog.LOG_LEVEL_ERROR)) {
490             log (SimpleLog.LOG_LEVEL_ERROR, message, t);
491         }
492     }
493
494     /**
495      * <p> Log a message with fatal log level.</p>
496      */

497     public final void fatal (Object message) {
498
499         if (isLevelEnabled (SimpleLog.LOG_LEVEL_FATAL)) {
500             log (SimpleLog.LOG_LEVEL_FATAL, message, null);
501         }
502     }
503
504     /**
505      * <p> Log an error with fatal log level.</p>
506      */

507     public final void fatal (Object message, Throwable t) {
508
509         if (isLevelEnabled (SimpleLog.LOG_LEVEL_FATAL)) {
510             log (SimpleLog.LOG_LEVEL_FATAL, message, t);
511         }
512     }
513
514     /**
515      * <p> Are debug messages currently enabled? </p>
516      *
517      * <p> This allows expensive operations such as <code>String</code>
518      * concatenation to be avoided when the message will be ignored by the
519      * logger. </p>
520      */

521     public final boolean isDebugEnabled () {
522
523         return isLevelEnabled (SimpleLog.LOG_LEVEL_DEBUG);
524     }
525
526     /**
527      * <p> Are error messages currently enabled? </p>
528      *
529      * <p> This allows expensive operations such as <code>String</code>
530      * concatenation to be avoided when the message will be ignored by the
531      * logger. </p>
532      */

533     public final boolean isErrorEnabled () {
534
535         return isLevelEnabled (SimpleLog.LOG_LEVEL_ERROR);
536     }
537
538     /**
539      * <p> Are fatal messages currently enabled? </p>
540      *
541      * <p> This allows expensive operations such as <code>String</code>
542      * concatenation to be avoided when the message will be ignored by the
543      * logger. </p>
544      */

545     public final boolean isFatalEnabled () {
546
547         return isLevelEnabled (SimpleLog.LOG_LEVEL_FATAL);
548     }
549
550     /**
551      * <p> Are info messages currently enabled? </p>
552      *
553      * <p> This allows expensive operations such as <code>String</code>
554      * concatenation to be avoided when the message will be ignored by the
555      * logger. </p>
556      */

557     public final boolean isInfoEnabled () {
558
559         return isLevelEnabled (SimpleLog.LOG_LEVEL_INFO);
560     }
561
562     /**
563      * <p> Are trace messages currently enabled? </p>
564      *
565      * <p> This allows expensive operations such as <code>String</code>
566      * concatenation to be avoided when the message will be ignored by the
567      * logger. </p>
568      */

569     public final boolean isTraceEnabled () {
570
571         return isLevelEnabled (SimpleLog.LOG_LEVEL_TRACE);
572     }
573
574     /**
575      * <p> Are warn messages currently enabled? </p>
576      *
577      * <p> This allows expensive operations such as <code>String</code>
578      * concatenation to be avoided when the message will be ignored by the
579      * logger. </p>
580      */

581     public final boolean isWarnEnabled () {
582
583         return isLevelEnabled (SimpleLog.LOG_LEVEL_WARN);
584     }
585 }
586
587
588
Popular Tags