/* * $Id: NetBeansLog.java,v 1.3 2006/09/25 08:52:36 acaproni Exp $ * * $Date: 2006/09/25 08:52:36 $ * $Revision: 1.3 $ * $Author: acaproni $ * * Copyright CERN, All Rights Reserved. */ package cern.gp.logging; import java.io.InputStream; import java.lang.reflect.Method; import java.security.AccessControlException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.Properties; import cern.gp.util.GPManager; import org.apache.commons.logging.Log; import org.openide.ErrorManager; /** * <p>NetBeans implementation of Log that uses the default ErrorManager. * The following system properties are supported to configure the behavior of this logger:</p> * <ul> * <li><code>{@link #LOG_LEVEL_PROPERTY}</code> - Default logging detail level for all instances of NetBeansLog. * Must be one of ("trace", "debug", "info", "warn", "error", or "fatal"). If not specified, defaults to * {@link #LOG_LEVEL_DEFAULT}.</li> * <li><code>{@link #SHOW_LOG_NAME_PROPERTY}</code> - Set to <code>true</code> if you want the Log instance name to be * included in output messages. Defaults to {@link #SHOW_LOG_NAME_DEFAULT}</li> * <li><code>{@link #SHOW_SHORT_LOG_NAME_PROPERTY}</code> - Set to <code>true</code> if you want the last component of * the name to be included in output messages. Defaults to {@link #SHOW_SHORT_LOG_NAME_DEFAULT}.</li> * <li><code>{@link #SHOW_DATE_TIME_PROPERTY}</code> - Set to <code>true</code> if you want the current date and time to * be included in output messages. Default is {@link #SHOW_DATE_TIME_DEFAULT}.</li> * <li><code>{@link #SYSTEM_PREFIX}.log.xxxxx</code> - Logging detail level for a NetBeansLog instance named "xxxxx". * Must be one of ("trace", "debug", "info", "warn", "error", or "fatal"). If not specified, the default * logging detail level is used.</li> * </ul> * * <p>In addition to looking for system properties with the names specified above, this implementation also checks for a * class loader resource named <code>{@link #LOG_PROPERTIES}</code>, and includes any matching definitions from this * resource (if it exists). * </p> * * @author Katarina Sigerud * * @version $Id: NetBeansLog.java,v 1.3 2006/09/25 08:52:36 acaproni Exp $ */ public class NetBeansLog implements Log { // // -- CLASS ATTRIBUTES --------------------------------------------- // // // -- LOG PROPERTY CONSTANTS --------------------------------------- // public static final String SYSTEM_PREFIX = "cern.gp.logging"; public static final String LOG_LEVEL_PROPERTY = SYSTEM_PREFIX + ".DefaultLevel"; public static final String SHOW_LOG_NAME_PROPERTY = SYSTEM_PREFIX + ".ShowLogName"; public static final String SHOW_SHORT_LOG_NAME_PROPERTY = SYSTEM_PREFIX + ".ShowShortLogName"; public static final String SHOW_DATE_TIME_PROPERTY = SYSTEM_PREFIX + ".ShowDateTime"; public static final String DATE_FORMAT_PROPERTY = SYSTEM_PREFIX + ".DateFormat"; //public static final String LOG_PROPERTIES = "nblog.properties"; public static final String DATE_FORMAT_DEFAULT = "yyyy/MM/dd HH:mm:ss:SSS zzz"; public static final String LOG_LEVEL_DEFAULT = "info"; public static final boolean SHOW_LOG_NAME_DEFAULT = false; public static final boolean SHOW_SHORT_LOG_NAME_DEFAULT = true; public static final boolean SHOW_DATE_TIME_DEFAULT = false; /* Default ErrorManager */ static protected final ErrorManager errMgr = ErrorManager.getDefault(); /* All system properties which start with {@link #SYSTEM_PREFIX} */ static protected final Properties nblogProps = new Properties(); /* Include the instance name in the log message? */ static protected boolean showLogName = SHOW_LOG_NAME_DEFAULT; /* Include the short name ( last component ) of the logger in the log message. * Default to true - otherwise we'll be lost in a flood of messages without knowing who sends them. */ static protected boolean showShortName = SHOW_SHORT_LOG_NAME_DEFAULT; /* Include the current time in the log message. */ static protected boolean showDateTime = SHOW_DATE_TIME_DEFAULT; /* Used to format times */ static protected DateFormat dateFormatter = null; // // -- LOG LEVEL CONSTANTS ------------------------------------------ // /** "Finest" level logging (<code>Debug window</code>). */ public static final int LOG_LEVEL_TRACE = ErrorManager.INFORMATIONAL; /** "Finer" level logging (<code>ErrorManager.INFORMATIONAL + 1</code>) */ public static final int LOG_LEVEL_DEBUG = ErrorManager.INFORMATIONAL + 1; /** "Config" level logging (<code>ErrorManager.WARNING</code>). */ public static final int LOG_LEVEL_INFO = ErrorManager.USER; /** "Info" level logging (<code>ErrorManager.USER</code>) */ public static final int LOG_LEVEL_WARN = ErrorManager.WARNING; /** "Warning" level logging = <code>ErrorManager.EXCEPTION</code> */ public static final int LOG_LEVEL_ERROR = ErrorManager.EXCEPTION; /** "Severe" level logging = <code>ErrorManager.ERROR</code> */ public static final int LOG_LEVEL_FATAL = ErrorManager.ERROR; /** Enable all logging levels */ public static final int LOG_LEVEL_ALL = (LOG_LEVEL_TRACE - 1); /** Disable all logging levels */ public static final int LOG_LEVEL_OFF = (LOG_LEVEL_FATAL + 1); // // -- INITIALIZER --------------------------------------------- // // initialize class attributes static { try { // add all system props that start with the specified prefix Enumeration enumer = System.getProperties().propertyNames(); while (enumer.hasMoreElements()) { String name = (String) (enumer.nextElement()); if (null != name && name.startsWith(SYSTEM_PREFIX)) { nblogProps.setProperty(name, System.getProperty(name)); } } // identify the class loader to attempt resource loading with ClassLoader classLoader = null; try { Method method = Thread.class.getMethod("getContextClassLoader", null); classLoader = (ClassLoader) method.invoke(Thread.currentThread(), null); } catch (Exception e) { e.printStackTrace(); // Ignored (security exception or JDK 1.1) } if (classLoader == null) { classLoader = NetBeansLog.class.getClassLoader(); } // add props from the resource nblog.properties //InputStream in = null; //in = NetBeansLog.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES); //InputStream in = classLoader.getResourceAsStream("nblog.properties"); //if (in != null) { // try { // nblogProps.load(in); // in.close(); // } catch (java.io.IOException e) { // e.printStackTrace(); // ignored // } //} /* That's a strange way to set properties. If the property is not set, we'll override the default showLogName = "true".equalsIgnoreCase( nblogProps.getProperty( SYSTEM_PREFIX + "showlogname","true")); */ String prop = nblogProps.getProperty(SHOW_LOG_NAME_PROPERTY); if (prop != null) showLogName = "true".equalsIgnoreCase(prop); prop = nblogProps.getProperty(SHOW_SHORT_LOG_NAME_PROPERTY); if (prop != null) { showShortName = "true".equalsIgnoreCase(prop); } prop = nblogProps.getProperty(SHOW_DATE_TIME_PROPERTY); if (prop != null) { showDateTime = "true".equalsIgnoreCase(prop); } if (showDateTime) { dateFormatter = new SimpleDateFormat(nblogProps.getProperty(DATE_FORMAT_PROPERTY, DATE_FORMAT_DEFAULT)); } } catch (AccessControlException e) { e.printStackTrace(); // ignore access control exceptions when trying to check system properties } } // // -- PROTECTED ATTRIBUTES --------------------------------------------- // /** The name of this simple log instance */ protected String logName = null; /** The current log level */ protected int currentLogLevel; private String prefix = null; // // -- CONSTRUCTOR --------------------------------------------- // /** * Construct a simple log with given name. * @param name log name */ public NetBeansLog(String name) { logName = name; // set initial log level setLevel(NetBeansLog.LOG_LEVEL_WARN); // set log level from properties String lvl = nblogProps.getProperty(SYSTEM_PREFIX + ".log." + logName); int i = String.valueOf(name).lastIndexOf("."); while (null == lvl && i > -1) { name = name.substring(0, i); lvl = nblogProps.getProperty(SYSTEM_PREFIX + ".log." + name); i = String.valueOf(name).lastIndexOf("."); } if (null == lvl) { lvl = nblogProps.getProperty(LOG_LEVEL_PROPERTY); } if ("all".equalsIgnoreCase(lvl)) { setLevel(NetBeansLog.LOG_LEVEL_ALL); } else if ("trace".equalsIgnoreCase(lvl)) { setLevel(NetBeansLog.LOG_LEVEL_TRACE); } else if ("debug".equalsIgnoreCase(lvl)) { setLevel(NetBeansLog.LOG_LEVEL_DEBUG); } else if ("info".equalsIgnoreCase(lvl)) { setLevel(NetBeansLog.LOG_LEVEL_INFO); } else if ("warn".equalsIgnoreCase(lvl)) { setLevel(NetBeansLog.LOG_LEVEL_WARN); } else if ("error".equalsIgnoreCase(lvl)) { setLevel(NetBeansLog.LOG_LEVEL_ERROR); } else if ("fatal".equalsIgnoreCase(lvl)) { setLevel(NetBeansLog.LOG_LEVEL_FATAL); } else if ("off".equalsIgnoreCase(lvl)) { setLevel(NetBeansLog.LOG_LEVEL_OFF); } } // // -- PUBLIC METHODS --------------------------------------------- // /** * Set logging level. </p> * @param level new logging level */ public void setLevel(int currentLogLevel) { this.currentLogLevel = currentLogLevel; } /** * Get logging level. </p> */ public int getLevel() { return currentLogLevel; } // // -- implements Log --------------------------------------------- // /* (non-Javadoc) * @see org.apache.commons.logging.Log#isTraceEnabled() */ public boolean isTraceEnabled() { return isLevelEnabled(NetBeansLog.LOG_LEVEL_TRACE); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#isDebugEnabled() */ public boolean isDebugEnabled() { return isLevelEnabled(NetBeansLog.LOG_LEVEL_DEBUG); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#isInfoEnabled() */ public boolean isInfoEnabled() { return isLevelEnabled(NetBeansLog.LOG_LEVEL_INFO); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#isWarnEnabled() */ public boolean isWarnEnabled() { return isLevelEnabled(NetBeansLog.LOG_LEVEL_WARN); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#isErrorEnabled() */ public boolean isErrorEnabled() { return isLevelEnabled(NetBeansLog.LOG_LEVEL_ERROR); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#isFatalEnabled() */ public boolean isFatalEnabled() { return isLevelEnabled(NetBeansLog.LOG_LEVEL_FATAL); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#trace(java.lang.Object) */ public void trace(Object message) { trace(message, null); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#trace(java.lang.Object, java.lang.Throwable) */ public void trace(Object message, Throwable t) { int logLevel = LOG_LEVEL_TRACE; if (isLevelEnabled(logLevel)) { display(logLevel, message, t); log(logLevel, message, t); } } /* (non-Javadoc) * @see org.apache.commons.logging.Log#debug(java.lang.Object) */ public void debug(Object message) { debug(message, null); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#debug(java.lang.Object, java.lang.Throwable) */ public void debug(Object message, Throwable t) { int logLevel = LOG_LEVEL_DEBUG; if (isLevelEnabled(logLevel)) { display(logLevel, message, t); log(logLevel, message, t); } } /* (non-Javadoc) * @see org.apache.commons.logging.Log#info(java.lang.Object) */ public void info(Object message) { info(message, null); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#info(java.lang.Object, java.lang.Throwable) */ public void info(Object message, Throwable t) { int logLevel = LOG_LEVEL_INFO; if (isLevelEnabled(logLevel)) { display(logLevel, message, t); log(logLevel, message, t); } } /* (non-Javadoc) * @see org.apache.commons.logging.Log#warn(java.lang.Object) */ public void warn(Object message) { warn(message, null); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#warn(java.lang.Object, java.lang.Throwable) */ public void warn(Object message, Throwable t) { int logLevel = LOG_LEVEL_WARN; if (isLevelEnabled(logLevel)) { display(logLevel, message, t); log(logLevel, message, t); } } /* (non-Javadoc) * @see org.apache.commons.logging.Log#error(java.lang.Object) */ public void error(Object message) { error(message, null); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#error(java.lang.Object, java.lang.Throwable) */ public void error(Object message, Throwable t) { int logLevel = LOG_LEVEL_ERROR; if (isLevelEnabled(logLevel)) { display(logLevel, message, t); log(logLevel, message, t); } } /* (non-Javadoc) * @see org.apache.commons.logging.Log#fatal(java.lang.Object) */ public void fatal(Object message) { fatal(message, null); } /* (non-Javadoc) * @see org.apache.commons.logging.Log#fatal(java.lang.Object, java.lang.Throwable) */ public void fatal(Object message, Throwable t) { int logLevel = LOG_LEVEL_FATAL; if (isLevelEnabled(logLevel)) { display(logLevel, message, t); log(logLevel, message, t); } } // // -- PROTECTED METHODS --------------------------------------------- // protected void display(int logLevel, Object message, Throwable t) { String tStr = ""; if (t != null) tStr = " < " + t.getMessage() + " > "; //GPManager.getIO("LOG", false).getOut().println(createLogMessage(logLevel, message) + tStr); } /** * Do the actual logging. This method assembles the message and then logs using the default * <code>ErrorManager</code>. */ protected void log(int type, Object msg, Throwable t) { String message = createLogMessage(type, msg); if (t == null) { errMgr.log(type, message); } else { errMgr.notify(type, errMgr.annotate(t, message)); } } protected String createLogMessage(int type, Object message) { // use a string buffer for better performance StringBuffer buf = new StringBuffer(); // append date-time if so configured if (showDateTime) { buf.append(dateFormatter.format(new Date())); buf.append(" "); } // append a readable representation of the log leve switch (type) { case NetBeansLog.LOG_LEVEL_TRACE : buf.append("[TRACE] "); break; case NetBeansLog.LOG_LEVEL_DEBUG : buf.append("[DEBUG] "); break; case NetBeansLog.LOG_LEVEL_INFO : buf.append("[INFO] "); break; case NetBeansLog.LOG_LEVEL_WARN : buf.append("[WARN] "); break; case NetBeansLog.LOG_LEVEL_ERROR : buf.append("[ERROR] "); break; case NetBeansLog.LOG_LEVEL_FATAL : buf.append("[FATAL] "); break; } // append the name of the log instance if so configured if (showShortName) { if (prefix == null) { // cut all but the last component of the name for both styles prefix = logName.substring(logName.lastIndexOf(".") + 1) + " - "; prefix = prefix.substring(prefix.lastIndexOf("/") + 1) + "-"; } buf.append(prefix); } else if (showLogName) { buf.append(String.valueOf(logName)).append(" - "); } // append the message buf.append(String.valueOf(message)); // append stack trace if not null // if (t != null) { // buf.append(" <"); // buf.append(t.toString()); // buf.append(">"); // t.printStackTrace(); // } return buf.toString(); } /** * Is the given log level currently enabled? * * @param logLevel is this level enabled? */ protected boolean isLevelEnabled(int logLevel) { // log level are numerically ordered so can use simple numeric comparison return (logLevel >= currentLogLevel); } }