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: */
017: package org.apache.commons.discovery.log;
018:
019: import java.io.PrintStream;
020: import java.text.DateFormat;
021: import java.text.SimpleDateFormat;
022: import java.util.Date;
023:
024: import 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: * @author Richard A. Sitze
041: * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
042: * @author Rod Waldhoff
043: * @author Robert Burrell Donkin
044: *
045: * @version $Id: SimpleLog.java 480374 2006-11-29 03:33:25Z niallp $
046: */
047: public class SimpleLog implements Log {
048: // ---------------------------------------------------- Log Level Constants
049:
050: /** "Trace" level logging. */
051: public static final int LOG_LEVEL_TRACE = 1;
052: /** "Debug" level logging. */
053: public static final int LOG_LEVEL_DEBUG = 2;
054: /** "Info" level logging. */
055: public static final int LOG_LEVEL_INFO = 3;
056: /** "Warn" level logging. */
057: public static final int LOG_LEVEL_WARN = 4;
058: /** "Error" level logging. */
059: public static final int LOG_LEVEL_ERROR = 5;
060: /** "Fatal" level logging. */
061: public static final int LOG_LEVEL_FATAL = 6;
062:
063: /** Enable all logging levels */
064: public static final int LOG_LEVEL_ALL = (LOG_LEVEL_TRACE - 1);
065:
066: /** Enable no logging levels */
067: public static final int LOG_LEVEL_OFF = (LOG_LEVEL_FATAL + 1);
068:
069: // ------------------------------------------------------- Class Attributes
070:
071: static protected final String PROP_LEVEL = "org.apache.commons.discovery.log.level";
072:
073: /** Include the instance name in the log message? */
074: static protected boolean showLogName = false;
075:
076: /** Include the short name ( last component ) of the logger in the log
077: message. Default to true - otherwise we'll be lost in a flood of
078: messages without knowing who sends them.
079: */
080: static protected boolean showShortName = true;
081:
082: /** Include the current time in the log message */
083: static protected boolean showDateTime = false;
084:
085: /** Used to format times */
086: static protected DateFormat dateFormatter = null;
087:
088: /** The current log level */
089: static protected int logLevel = LOG_LEVEL_INFO;
090:
091: /**
092: * Use 'out' instead of 'err' for logging
093: * to keep in-sync with test messages.
094: */
095: static private PrintStream out = System.out;
096:
097: // ------------------------------------------------------------ Initializer
098:
099: // initialize class attributes
100: static {
101: if (showDateTime) {
102: dateFormatter = new SimpleDateFormat(
103: "yyyy/MM/dd HH:mm:ss:SSS zzz");
104: }
105:
106: try {
107: // set log level from properties
108: String lvl = System.getProperty(PROP_LEVEL);
109:
110: if ("all".equalsIgnoreCase(lvl)) {
111: setLevel(SimpleLog.LOG_LEVEL_ALL);
112: } else if ("trace".equalsIgnoreCase(lvl)) {
113: setLevel(SimpleLog.LOG_LEVEL_TRACE);
114: } else if ("debug".equalsIgnoreCase(lvl)) {
115: setLevel(SimpleLog.LOG_LEVEL_DEBUG);
116: } else if ("info".equalsIgnoreCase(lvl)) {
117: setLevel(SimpleLog.LOG_LEVEL_INFO);
118: } else if ("warn".equalsIgnoreCase(lvl)) {
119: setLevel(SimpleLog.LOG_LEVEL_WARN);
120: } else if ("error".equalsIgnoreCase(lvl)) {
121: setLevel(SimpleLog.LOG_LEVEL_ERROR);
122: } else if ("fatal".equalsIgnoreCase(lvl)) {
123: setLevel(SimpleLog.LOG_LEVEL_FATAL);
124: } else if ("off".equalsIgnoreCase(lvl)) {
125: setLevel(SimpleLog.LOG_LEVEL_OFF);
126: }
127: } catch (SecurityException ignored) {
128: //do nothing. We get here if running discovery
129: //under a servlet with restricted security rights, and
130: //cannot read the system property.
131: //In which case, the default is what you get to keep.
132: }
133:
134: }
135:
136: // -------------------------------------------------------- Properties
137:
138: /**
139: * <p> Set logging level. </p>
140: *
141: * @param currentLogLevel new logging level
142: */
143: public static void setLevel(int currentLogLevel) {
144: logLevel = currentLogLevel;
145: }
146:
147: /**
148: * <p> Get logging level. </p>
149: */
150: public static int getLevel() {
151: return logLevel;
152: }
153:
154: /**
155: * Is the given log level currently enabled?
156: *
157: * @param level is this level enabled?
158: */
159: protected static boolean isLevelEnabled(int level) {
160: // log level are numerically ordered so can use simple numeric
161: // comparison
162: return (level >= getLevel());
163: }
164:
165: // ------------------------------------------------------------- Attributes
166:
167: /** The name of this simple log instance */
168: protected String logName = null;
169:
170: private String prefix = null;
171:
172: // ------------------------------------------------------------ Constructor
173:
174: /**
175: * Construct a simple log with given name.
176: *
177: * @param name log name
178: */
179: public SimpleLog(String name) {
180: logName = name;
181: }
182:
183: // -------------------------------------------------------- Logging Methods
184:
185: /**
186: * <p> Do the actual logging.
187: * This method assembles the message
188: * and then prints to <code>System.err</code>.</p>
189: */
190: protected void log(int type, Object message, Throwable t) {
191: // use a string buffer for better performance
192: StringBuffer buf = new StringBuffer();
193:
194: // append date-time if so configured
195: if (showDateTime) {
196: buf.append(dateFormatter.format(new Date()));
197: buf.append(" ");
198: }
199:
200: // append a readable representation of the log leve
201: switch (type) {
202: case SimpleLog.LOG_LEVEL_TRACE:
203: buf.append("[TRACE] ");
204: break;
205: case SimpleLog.LOG_LEVEL_DEBUG:
206: buf.append("[DEBUG] ");
207: break;
208: case SimpleLog.LOG_LEVEL_INFO:
209: buf.append("[INFO ] ");
210: break;
211: case SimpleLog.LOG_LEVEL_WARN:
212: buf.append("[WARN ] ");
213: break;
214: case SimpleLog.LOG_LEVEL_ERROR:
215: buf.append("[ERROR] ");
216: break;
217: case SimpleLog.LOG_LEVEL_FATAL:
218: buf.append("[FATAL] ");
219: break;
220: }
221:
222: // append the name of the log instance if so configured
223: if (showShortName) {
224: if (prefix == null) {
225: // cut all but the last component of the name for both styles
226: prefix = logName
227: .substring(logName.lastIndexOf(".") + 1)
228: + " - ";
229: prefix = prefix.substring(prefix.lastIndexOf("/") + 1)
230: + "-";
231: }
232: buf.append(prefix);
233: } else if (showLogName) {
234: buf.append(String.valueOf(logName)).append(" - ");
235: }
236:
237: // append the message
238: buf.append(String.valueOf(message));
239:
240: // append stack trace if not null
241: if (t != null) {
242: buf.append(" <");
243: buf.append(t.toString());
244: buf.append(">");
245: }
246:
247: // print to System.err
248: out.println(buf.toString());
249:
250: if (t != null)
251: t.printStackTrace(System.err);
252: }
253:
254: // -------------------------------------------------------- Log Implementation
255:
256: /**
257: * <p> Log a message with debug log level.</p>
258: */
259: public final void debug(Object message) {
260: if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
261: log(SimpleLog.LOG_LEVEL_DEBUG, message, null);
262: }
263: }
264:
265: /**
266: * <p> Log an error with debug log level.</p>
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: * <p> Log a message with debug log level.</p>
276: */
277: public final void trace(Object message) {
278: if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
279: log(SimpleLog.LOG_LEVEL_TRACE, message, null);
280: }
281: }
282:
283: /**
284: * <p> Log an error with debug log level.</p>
285: */
286: public final void trace(Object message, Throwable t) {
287: if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
288: log(SimpleLog.LOG_LEVEL_TRACE, message, t);
289: }
290: }
291:
292: /**
293: * <p> Log a message with info log level.</p>
294: */
295: public final void info(Object message) {
296: if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
297: log(SimpleLog.LOG_LEVEL_INFO, message, null);
298: }
299: }
300:
301: /**
302: * <p> Log an error with info log level.</p>
303: */
304: public final void info(Object message, Throwable t) {
305: if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
306: log(SimpleLog.LOG_LEVEL_INFO, message, t);
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: * <p> Log an error with warn log level.</p>
321: */
322: public final void warn(Object message, Throwable t) {
323: if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
324: log(SimpleLog.LOG_LEVEL_WARN, message, t);
325: }
326: }
327:
328: /**
329: * <p> Log a message with error log level.</p>
330: */
331: public final void error(Object message) {
332: if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
333: log(SimpleLog.LOG_LEVEL_ERROR, message, null);
334: }
335: }
336:
337: /**
338: * <p> Log an error with error log level.</p>
339: */
340: public final void error(Object message, Throwable t) {
341: if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
342: log(SimpleLog.LOG_LEVEL_ERROR, message, t);
343: }
344: }
345:
346: /**
347: * <p> Log a message with fatal log level.</p>
348: */
349: public final void fatal(Object message) {
350: if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
351: log(SimpleLog.LOG_LEVEL_FATAL, message, null);
352: }
353: }
354:
355: /**
356: * <p> Log an error with fatal log level.</p>
357: */
358: public final void fatal(Object message, Throwable t) {
359: if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
360: log(SimpleLog.LOG_LEVEL_FATAL, message, t);
361: }
362: }
363:
364: /**
365: * <p> Are debug messages currently enabled? </p>
366: *
367: * <p> This allows expensive operations such as <code>String</code>
368: * concatenation to be avoided when the message will be ignored by the
369: * logger. </p>
370: */
371: public final boolean isDebugEnabled() {
372: return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG);
373: }
374:
375: /**
376: * <p> Are error messages currently enabled? </p>
377: *
378: * <p> This allows expensive operations such as <code>String</code>
379: * concatenation to be avoided when the message will be ignored by the
380: * logger. </p>
381: */
382: public final boolean isErrorEnabled() {
383: return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR);
384: }
385:
386: /**
387: * <p> Are fatal messages currently enabled? </p>
388: *
389: * <p> This allows expensive operations such as <code>String</code>
390: * concatenation to be avoided when the message will be ignored by the
391: * logger. </p>
392: */
393: public final boolean isFatalEnabled() {
394: return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL);
395: }
396:
397: /**
398: * <p> Are info messages currently enabled? </p>
399: *
400: * <p> This allows expensive operations such as <code>String</code>
401: * concatenation to be avoided when the message will be ignored by the
402: * logger. </p>
403: */
404: public final boolean isInfoEnabled() {
405: return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO);
406: }
407:
408: /**
409: * <p> Are trace messages currently enabled? </p>
410: *
411: * <p> This allows expensive operations such as <code>String</code>
412: * concatenation to be avoided when the message will be ignored by the
413: * logger. </p>
414: */
415: public final boolean isTraceEnabled() {
416: return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE);
417: }
418:
419: /**
420: * <p> Are warn messages currently enabled? </p>
421: *
422: * <p> This allows expensive operations such as <code>String</code>
423: * concatenation to be avoided when the message will be ignored by the
424: * logger. </p>
425: */
426: public final boolean isWarnEnabled() {
427: return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN);
428: }
429: }
|