001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.discovery.log;
018
019import java.io.PrintStream;
020import java.text.DateFormat;
021import java.text.SimpleDateFormat;
022import java.util.Date;
023
024import org.apache.commons.logging.Log;
025
026/**
027 * <p>Simple implementation of Log that sends all enabled log messages,
028 * for all defined loggers, to System.err.
029 * </p>
030 *
031 * <p>Hacked from commons-logging SimpleLog for use in discovery.
032 * This is intended to be enough of a Log implementation to bootstrap
033 * Discovery.
034 * </p>
035 *
036 * <p>One property: <code>org.apache.commons.discovery.log.level</code>.
037 * valid values: all, trace, debug, info, warn, error, fatal, off.
038 * </p>
039 *
040 * @deprecated Starting from commons-discovery-05, Log is totally delegated to commons-logging
041 * @version $Id: SimpleLog.java 1089489 2011-04-06 15:20:24Z sebb $
042 */
043@Deprecated
044public class SimpleLog implements Log {
045      // ---------------------------------------------------- Log Level Constants
046
047    /** "Trace" level logging. */
048    public static final int LOG_LEVEL_TRACE  = 1;
049
050    /** "Debug" level logging. */
051    public static final int LOG_LEVEL_DEBUG  = 2;
052
053    /** "Info" level logging. */
054    public static final int LOG_LEVEL_INFO   = 3;
055
056    /** "Warn" level logging. */
057    public static final int LOG_LEVEL_WARN   = 4;
058
059    /** "Error" level logging. */
060    public static final int LOG_LEVEL_ERROR  = 5;
061
062    /** "Fatal" level logging. */
063    public static final int LOG_LEVEL_FATAL  = 6;
064
065    /** Enable all logging levels */
066    public static final int LOG_LEVEL_ALL    = (LOG_LEVEL_TRACE - 1);
067
068    /** Enable no logging levels */
069    public static final int LOG_LEVEL_OFF    = (LOG_LEVEL_FATAL + 1);
070
071    // ------------------------------------------------------- Class Attributes
072
073    static protected final String PROP_LEVEL =
074        "org.apache.commons.discovery.log.level";
075
076    /** Include the instance name in the log message? */
077    static protected boolean showLogName = false;
078
079    /** Include the short name ( last component ) of the logger in the log
080        message. Default to true - otherwise we'll be lost in a flood of
081        messages without knowing who sends them.
082    */
083    static protected boolean showShortName = true;
084
085    /** Include the current time in the log message */
086    static protected boolean showDateTime = false;
087
088    /** Used to format times */
089    static protected DateFormat dateFormatter = null;
090
091    /** The current log level */
092    static protected int logLevel = LOG_LEVEL_INFO;
093
094    /**
095     * Use 'out' instead of 'err' for logging
096     * to keep in-sync with test messages.
097     */
098    static private PrintStream out = System.out;
099
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     * Get logging level.
151     *
152     * @return The logging level
153     */
154    public static int getLevel() {
155        return logLevel;
156    }
157
158    /**
159     * Is the given log level currently enabled?
160     *
161     * @param level is this level enabled?
162     * @return true, if the input level is enabled, false otherwise
163     */
164    protected static boolean isLevelEnabled(int level) {
165        // log level are numerically ordered so can use simple numeric
166        // comparison
167        return (level >= getLevel());
168    }
169
170    // ------------------------------------------------------------- Attributes
171
172    /** The name of this simple log instance */
173    protected String logName = null;
174
175    private String prefix=null;
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    // -------------------------------------------------------- Logging Methods
189
190    /**
191     * Do the actual logging.
192     *
193     * This method assembles the message and then prints to {@code System.err}.
194     *
195     * @param type The logging level
196     * @param message The message to log
197     * @param t The error cause, if any
198     */
199    protected void log(int type, Object message, Throwable t) {
200        // use a string buffer for better performance
201        StringBuffer buf = new StringBuffer();
202
203        // append date-time if so configured
204        if(showDateTime) {
205            buf.append(dateFormatter.format(new Date()));
206            buf.append(" ");
207        }
208
209        // append a readable representation of the log leve
210        switch(type) {
211            case SimpleLog.LOG_LEVEL_TRACE: buf.append("[TRACE] "); break;
212            case SimpleLog.LOG_LEVEL_DEBUG: buf.append("[DEBUG] "); break;
213            case SimpleLog.LOG_LEVEL_INFO:  buf.append("[INFO ] "); break;
214            case SimpleLog.LOG_LEVEL_WARN:  buf.append("[WARN ] "); break;
215            case SimpleLog.LOG_LEVEL_ERROR: buf.append("[ERROR] "); break;
216            case SimpleLog.LOG_LEVEL_FATAL: buf.append("[FATAL] "); break;
217        }
218
219        // append the name of the log instance if so configured
220        if( showShortName) {
221            if( prefix==null ) {
222                // cut all but the last component of the name for both styles
223                prefix = logName.substring( logName.lastIndexOf(".") +1) + " - ";
224                prefix = prefix.substring( prefix.lastIndexOf("/") +1) + "-";
225            }
226            buf.append( prefix );
227        } else if(showLogName) {
228            buf.append(String.valueOf(logName)).append(" - ");
229        }
230
231        // append the message
232        buf.append(String.valueOf(message));
233
234        // append stack trace if not null
235        if(t != null) {
236            buf.append(" <");
237            buf.append(t.toString());
238            buf.append(">");
239        }
240
241        // print to System.err
242        out.println(buf.toString());
243
244        if (t != null) {
245            t.printStackTrace(System.err);
246        }
247    }
248
249    // -------------------------------------------------------- Log Implementation
250
251    /**
252     * Log a message with debug log level.
253     *
254     * @param message The message to log
255     */
256    public final void debug(Object message) {
257        if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
258            log(SimpleLog.LOG_LEVEL_DEBUG, message, null);
259        }
260    }
261
262    /**
263     * Log an error with debug log level.
264     *
265     * @param message The message to log
266     * @param t The error cause, if any
267     */
268    public final void debug(Object message, Throwable t) {
269        if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
270            log(SimpleLog.LOG_LEVEL_DEBUG, message, t);
271        }
272    }
273
274    /**
275     * Log a message with debug log level.
276     *
277     * @param message The message to log
278     */
279    public final void trace(Object message) {
280        if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
281            log(SimpleLog.LOG_LEVEL_TRACE, message, null);
282        }
283    }
284
285    /**
286     * Log an error with debug log level.
287     *
288     * @param message The message to log
289     * @param t The error cause, if any
290     */
291    public final void trace(Object message, Throwable t) {
292        if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
293            log(SimpleLog.LOG_LEVEL_TRACE, message, t);
294        }
295    }
296
297    /**
298     * Log a message with info log level.
299     *
300     * @param message The message to log
301     */
302    public final void info(Object message) {
303        if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
304            log(SimpleLog.LOG_LEVEL_INFO,message,null);
305        }
306    }
307
308    /**
309     * Log an error with info log level.
310     *
311     * @param message The message to log
312     * @param t The error cause, if any
313     */
314    public final void info(Object message, Throwable t) {
315        if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
316            log(SimpleLog.LOG_LEVEL_INFO, message, t);
317        }
318    }
319
320    /**
321     * Log a message with warn log level.
322     *
323     * @param message The message to log
324     */
325    public final void warn(Object message) {
326        if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
327            log(SimpleLog.LOG_LEVEL_WARN, message, null);
328        }
329    }
330
331    /**
332     * Log an error with warn log level.
333     *
334     * @param message The message to log
335     * @param t The error cause, if any
336     */
337    public final void warn(Object message, Throwable t) {
338        if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
339            log(SimpleLog.LOG_LEVEL_WARN, message, t);
340        }
341    }
342
343    /**
344     * Log a message with error log level.
345     *
346     * @param message The message to log
347     */
348    public final void error(Object message) {
349        if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
350            log(SimpleLog.LOG_LEVEL_ERROR, message, null);
351        }
352    }
353
354    /**
355     * Log an error with error log level.
356     *
357     * @param message The message to log
358     * @param t The error cause, if any
359     */
360    public final void error(Object message, Throwable t) {
361        if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
362            log(SimpleLog.LOG_LEVEL_ERROR, message, t);
363        }
364    }
365
366    /**
367     * Log a message with fatal log level.
368     *
369     * @param message The message to log
370     */
371    public final void fatal(Object message) {
372        if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
373            log(SimpleLog.LOG_LEVEL_FATAL, message, null);
374        }
375    }
376
377    /**
378     * Log an error with fatal log level.
379     *
380     * @param message The message to log
381     * @param t The error cause, if any
382     */
383    public final void fatal(Object message, Throwable t) {
384        if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
385            log(SimpleLog.LOG_LEVEL_FATAL, message, t);
386        }
387    }
388
389    /**
390     * <p> Are debug messages currently enabled? </p>
391     *
392     * <p> This allows expensive operations such as <code>String</code>
393     * concatenation to be avoided when the message will be ignored by the
394     * logger. </p>
395     *
396     * @return true, if the {@link SimpleLog#LOG_LEVEL_DEBUG} is enabled, false otherwise
397     */
398    public final boolean isDebugEnabled() {
399        return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG);
400    }
401
402    /**
403     * <p> Are error messages currently enabled? </p>
404     *
405     * <p> This allows expensive operations such as <code>String</code>
406     * concatenation to be avoided when the message will be ignored by the
407     * logger. </p>
408     *
409     * @return true, if the {@link SimpleLog#LOG_LEVEL_ERROR} is enabled, false otherwise
410     */
411    public final boolean isErrorEnabled() {
412        return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR);
413    }
414
415    /**
416     * <p> Are fatal messages currently enabled? </p>
417     *
418     * <p> This allows expensive operations such as <code>String</code>
419     * concatenation to be avoided when the message will be ignored by the
420     * logger. </p>
421     *
422     * @return true, if the {@link SimpleLog#LOG_LEVEL_FATAL} is enabled, false otherwise
423     */
424    public final boolean isFatalEnabled() {
425        return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL);
426    }
427
428    /**
429     * <p> Are info messages currently enabled? </p>
430     *
431     * <p> This allows expensive operations such as <code>String</code>
432     * concatenation to be avoided when the message will be ignored by the
433     * logger. </p>
434     *
435     * @return true, if the {@link SimpleLog#LOG_LEVEL_INFO} is enabled, false otherwise
436     */
437    public final boolean isInfoEnabled() {
438        return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO);
439    }
440
441    /**
442     * <p> Are trace messages currently enabled? </p>
443     *
444     * <p> This allows expensive operations such as <code>String</code>
445     * concatenation to be avoided when the message will be ignored by the
446     * logger. </p>
447     *
448     * @return true, if the {@link SimpleLog#LOG_LEVEL_TRACE} is enabled, false otherwise
449     */
450    public final boolean isTraceEnabled() {
451        return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE);
452    }
453
454    /**
455     * <p> Are warn messages currently enabled? </p>
456     *
457     * <p> This allows expensive operations such as <code>String</code>
458     * concatenation to be avoided when the message will be ignored by the
459     * logger. </p>
460     *
461     * @return true, if the {@link SimpleLog#LOG_LEVEL_WARN} is enabled, false otherwise
462     */
463    public final boolean isWarnEnabled() {
464        return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN);
465    }
466
467}