1. /*
  2. * $Header: /home/cvs/jakarta-commons/logging/src/java/org/apache/commons/logging/impl/SimpleLog.java,v 1.4 2002/06/15 20:54:48 craigmcc Exp $
  3. * $Revision: 1.4 $
  4. * $Date: 2002/06/15 20:54:48 $
  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. package org.apache.commons.discovery.log;
  62. import java.io.PrintStream;
  63. import java.text.DateFormat;
  64. import java.text.SimpleDateFormat;
  65. import java.util.Date;
  66. import org.apache.commons.logging.Log;
  67. /**
  68. * <p>Simple implementation of Log that sends all enabled log messages,
  69. * for all defined loggers, to System.err.
  70. * </p>
  71. *
  72. * <p>Hacked from commons-logging SimpleLog for use in discovery.
  73. * This is intended to be enough of a Log implementation to bootstrap
  74. * Discovery.
  75. * </p>
  76. *
  77. * <p>One property: <code>org.apache.commons.discovery.log.level</code>.
  78. * valid values: all, trace, debug, info, warn, error, fatal, off.
  79. * </p>
  80. *
  81. * @author Richard A. Sitze
  82. * @author <a href="mailto:sanders@apache.org">Scott Sanders</a>
  83. * @author Rod Waldhoff
  84. * @author Robert Burrell Donkin
  85. *
  86. * @version $Id: SimpleLog.java,v 1.4 2002/06/15 20:54:48 craigmcc Exp $
  87. */
  88. public class SimpleLog implements Log {
  89. // ---------------------------------------------------- Log Level Constants
  90. /** "Trace" level logging. */
  91. public static final int LOG_LEVEL_TRACE = 1;
  92. /** "Debug" level logging. */
  93. public static final int LOG_LEVEL_DEBUG = 2;
  94. /** "Info" level logging. */
  95. public static final int LOG_LEVEL_INFO = 3;
  96. /** "Warn" level logging. */
  97. public static final int LOG_LEVEL_WARN = 4;
  98. /** "Error" level logging. */
  99. public static final int LOG_LEVEL_ERROR = 5;
  100. /** "Fatal" level logging. */
  101. public static final int LOG_LEVEL_FATAL = 6;
  102. /** Enable all logging levels */
  103. public static final int LOG_LEVEL_ALL = (LOG_LEVEL_TRACE - 1);
  104. /** Enable no logging levels */
  105. public static final int LOG_LEVEL_OFF = (LOG_LEVEL_FATAL + 1);
  106. // ------------------------------------------------------- Class Attributes
  107. static protected final String PROP_LEVEL =
  108. "org.apache.commons.discovery.log.level";
  109. /** Include the instance name in the log message? */
  110. static protected boolean showLogName = false;
  111. /** Include the short name ( last component ) of the logger in the log
  112. message. Default to true - otherwise we'll be lost in a flood of
  113. messages without knowing who sends them.
  114. */
  115. static protected boolean showShortName = true;
  116. /** Include the current time in the log message */
  117. static protected boolean showDateTime = false;
  118. /** Used to format times */
  119. static protected DateFormat dateFormatter = null;
  120. /** The current log level */
  121. static protected int logLevel = LOG_LEVEL_INFO;
  122. /**
  123. * Use 'out' instead of 'err' for logging
  124. * to keep in-sync with test messages.
  125. */
  126. static private PrintStream out = System.out;
  127. // ------------------------------------------------------------ Initializer
  128. // initialize class attributes
  129. static {
  130. if(showDateTime) {
  131. dateFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS zzz");
  132. }
  133. // set log level from properties
  134. String lvl = System.getProperty(PROP_LEVEL);
  135. if("all".equalsIgnoreCase(lvl)) {
  136. setLevel(SimpleLog.LOG_LEVEL_ALL);
  137. } else if("trace".equalsIgnoreCase(lvl)) {
  138. setLevel(SimpleLog.LOG_LEVEL_TRACE);
  139. } else if("debug".equalsIgnoreCase(lvl)) {
  140. setLevel(SimpleLog.LOG_LEVEL_DEBUG);
  141. } else if("info".equalsIgnoreCase(lvl)) {
  142. setLevel(SimpleLog.LOG_LEVEL_INFO);
  143. } else if("warn".equalsIgnoreCase(lvl)) {
  144. setLevel(SimpleLog.LOG_LEVEL_WARN);
  145. } else if("error".equalsIgnoreCase(lvl)) {
  146. setLevel(SimpleLog.LOG_LEVEL_ERROR);
  147. } else if("fatal".equalsIgnoreCase(lvl)) {
  148. setLevel(SimpleLog.LOG_LEVEL_FATAL);
  149. } else if("off".equalsIgnoreCase(lvl)) {
  150. setLevel(SimpleLog.LOG_LEVEL_OFF);
  151. }
  152. }
  153. // -------------------------------------------------------- Properties
  154. /**
  155. * <p> Set logging level. </p>
  156. *
  157. * @param level new logging level
  158. */
  159. public static void setLevel(int currentLogLevel) {
  160. logLevel = currentLogLevel;
  161. }
  162. /**
  163. * <p> Get logging level. </p>
  164. */
  165. public static int getLevel() {
  166. return logLevel;
  167. }
  168. /**
  169. * Is the given log level currently enabled?
  170. *
  171. * @param logLevel is this level enabled?
  172. */
  173. protected static boolean isLevelEnabled(int level) {
  174. // log level are numerically ordered so can use simple numeric
  175. // comparison
  176. return (level >= getLevel());
  177. }
  178. // ------------------------------------------------------------- Attributes
  179. /** The name of this simple log instance */
  180. protected String logName = null;
  181. private String prefix=null;
  182. // ------------------------------------------------------------ Constructor
  183. /**
  184. * Construct a simple log with given name.
  185. *
  186. * @param name log name
  187. */
  188. public SimpleLog(String name) {
  189. logName = name;
  190. }
  191. // -------------------------------------------------------- Logging Methods
  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. // append date-time if so configured
  201. if(showDateTime) {
  202. buf.append(dateFormatter.format(new Date()));
  203. buf.append(" ");
  204. }
  205. // append a readable representation of the log leve
  206. switch(type) {
  207. case SimpleLog.LOG_LEVEL_TRACE: buf.append("[TRACE] "); break;
  208. case SimpleLog.LOG_LEVEL_DEBUG: buf.append("[DEBUG] "); break;
  209. case SimpleLog.LOG_LEVEL_INFO: buf.append("[INFO ] "); break;
  210. case SimpleLog.LOG_LEVEL_WARN: buf.append("[WARN ] "); break;
  211. case SimpleLog.LOG_LEVEL_ERROR: buf.append("[ERROR] "); break;
  212. case SimpleLog.LOG_LEVEL_FATAL: buf.append("[FATAL] "); break;
  213. }
  214. // append the name of the log instance if so configured
  215. if( showShortName) {
  216. if( prefix==null ) {
  217. // cut all but the last component of the name for both styles
  218. prefix = logName.substring( logName.lastIndexOf(".") +1) + " - ";
  219. prefix = prefix.substring( prefix.lastIndexOf("/") +1) + "-";
  220. }
  221. buf.append( prefix );
  222. } else if(showLogName) {
  223. buf.append(String.valueOf(logName)).append(" - ");
  224. }
  225. // append the message
  226. buf.append(String.valueOf(message));
  227. // append stack trace if not null
  228. if(t != null) {
  229. buf.append(" <");
  230. buf.append(t.toString());
  231. buf.append(">");
  232. }
  233. // print to System.err
  234. out.println(buf.toString());
  235. if (t != null)
  236. t.printStackTrace(System.err);
  237. }
  238. // -------------------------------------------------------- Log Implementation
  239. /**
  240. * <p> Log a message with debug log level.</p>
  241. */
  242. public final void debug(Object message) {
  243. if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
  244. log(SimpleLog.LOG_LEVEL_DEBUG, message, null);
  245. }
  246. }
  247. /**
  248. * <p> Log an error with debug log level.</p>
  249. */
  250. public final void debug(Object message, Throwable t) {
  251. if (isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG)) {
  252. log(SimpleLog.LOG_LEVEL_DEBUG, message, t);
  253. }
  254. }
  255. /**
  256. * <p> Log a message with debug log level.</p>
  257. */
  258. public final void trace(Object message) {
  259. if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
  260. log(SimpleLog.LOG_LEVEL_TRACE, message, null);
  261. }
  262. }
  263. /**
  264. * <p> Log an error with debug log level.</p>
  265. */
  266. public final void trace(Object message, Throwable t) {
  267. if (isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE)) {
  268. log(SimpleLog.LOG_LEVEL_TRACE, message, t);
  269. }
  270. }
  271. /**
  272. * <p> Log a message with info log level.</p>
  273. */
  274. public final void info(Object message) {
  275. if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
  276. log(SimpleLog.LOG_LEVEL_INFO,message,null);
  277. }
  278. }
  279. /**
  280. * <p> Log an error with info log level.</p>
  281. */
  282. public final void info(Object message, Throwable t) {
  283. if (isLevelEnabled(SimpleLog.LOG_LEVEL_INFO)) {
  284. log(SimpleLog.LOG_LEVEL_INFO, message, t);
  285. }
  286. }
  287. /**
  288. * <p> Log a message with warn log level.</p>
  289. */
  290. public final void warn(Object message) {
  291. if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
  292. log(SimpleLog.LOG_LEVEL_WARN, message, null);
  293. }
  294. }
  295. /**
  296. * <p> Log an error with warn log level.</p>
  297. */
  298. public final void warn(Object message, Throwable t) {
  299. if (isLevelEnabled(SimpleLog.LOG_LEVEL_WARN)) {
  300. log(SimpleLog.LOG_LEVEL_WARN, message, t);
  301. }
  302. }
  303. /**
  304. * <p> Log a message with error log level.</p>
  305. */
  306. public final void error(Object message) {
  307. if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
  308. log(SimpleLog.LOG_LEVEL_ERROR, message, null);
  309. }
  310. }
  311. /**
  312. * <p> Log an error with error log level.</p>
  313. */
  314. public final void error(Object message, Throwable t) {
  315. if (isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR)) {
  316. log(SimpleLog.LOG_LEVEL_ERROR, message, t);
  317. }
  318. }
  319. /**
  320. * <p> Log a message with fatal log level.</p>
  321. */
  322. public final void fatal(Object message) {
  323. if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
  324. log(SimpleLog.LOG_LEVEL_FATAL, message, null);
  325. }
  326. }
  327. /**
  328. * <p> Log an error with fatal log level.</p>
  329. */
  330. public final void fatal(Object message, Throwable t) {
  331. if (isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL)) {
  332. log(SimpleLog.LOG_LEVEL_FATAL, message, t);
  333. }
  334. }
  335. /**
  336. * <p> Are debug messages currently enabled? </p>
  337. *
  338. * <p> This allows expensive operations such as <code>String</code>
  339. * concatenation to be avoided when the message will be ignored by the
  340. * logger. </p>
  341. */
  342. public final boolean isDebugEnabled() {
  343. return isLevelEnabled(SimpleLog.LOG_LEVEL_DEBUG);
  344. }
  345. /**
  346. * <p> Are error messages currently enabled? </p>
  347. *
  348. * <p> This allows expensive operations such as <code>String</code>
  349. * concatenation to be avoided when the message will be ignored by the
  350. * logger. </p>
  351. */
  352. public final boolean isErrorEnabled() {
  353. return isLevelEnabled(SimpleLog.LOG_LEVEL_ERROR);
  354. }
  355. /**
  356. * <p> Are fatal messages currently enabled? </p>
  357. *
  358. * <p> This allows expensive operations such as <code>String</code>
  359. * concatenation to be avoided when the message will be ignored by the
  360. * logger. </p>
  361. */
  362. public final boolean isFatalEnabled() {
  363. return isLevelEnabled(SimpleLog.LOG_LEVEL_FATAL);
  364. }
  365. /**
  366. * <p> Are info messages currently enabled? </p>
  367. *
  368. * <p> This allows expensive operations such as <code>String</code>
  369. * concatenation to be avoided when the message will be ignored by the
  370. * logger. </p>
  371. */
  372. public final boolean isInfoEnabled() {
  373. return isLevelEnabled(SimpleLog.LOG_LEVEL_INFO);
  374. }
  375. /**
  376. * <p> Are trace 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 isTraceEnabled() {
  383. return isLevelEnabled(SimpleLog.LOG_LEVEL_TRACE);
  384. }
  385. /**
  386. * <p> Are warn messages currently enabled? </p>
  387. *
  388. * <p> This allows expensive operations such as <code>String</code>
  389. * concatenation to be avoided when the message will be ignored by the
  390. * logger. </p>
  391. */
  392. public final boolean isWarnEnabled() {
  393. return isLevelEnabled(SimpleLog.LOG_LEVEL_WARN);
  394. }
  395. }