/******************************************************************************* * Copyright (c) 2006-2010 eBay Inc. All Rights Reserved. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 *******************************************************************************/ package org.ebayopensource.turmeric.eclipse.core.logging; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.OutputStream; import java.net.URL; import java.util.Hashtable; import java.util.logging.ConsoleHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.ebayopensource.turmeric.eclipse.core.logging.system.ISOALoggingSystemProvider; import org.ebayopensource.turmeric.eclipse.core.logging.system.SOALoggingSystemExtensionRegistry; import org.ebayopensource.turmeric.eclipse.utils.lang.StringUtil; import org.eclipse.core.runtime.Platform; /** * A wrapper class for logging. * @author Yang Yu(yayu@ebay.com) * */ public final class SOALogger extends Logger{ private static Hashtable<String,SOALogger> loggers = null; //public static final String USAGE_TRACKING = "!USAGE_TRACKING: "; /** The Constant DEBUG. */ public static final boolean DEBUG; /** Codegen and runtime global logger ID. */ public static final String GLOBAL_LOGGER_ID = "org.ebayopensource.turmeric"; /** Plugin global logger ID. */ public static final String GLOBAL_LOGGER_ID_PLUGIN = "org.ebayopensource.turmeric.eclipse"; private static final PluginLogDelegateHandler pluginLogHandler = new PluginLogDelegateHandler(); /** The Constant GLOBAL_LOGGER. */ public static final Logger GLOBAL_LOGGER = Logger.getLogger(""); private static final String FILENAME_LOGGING_PROPERTIES = "turmeric-plugin-logging.properties"; /** The Constant CONSOLE_HANDLER. */ public static final ConsoleHandler CONSOLE_HANDLER; static { boolean trace = false; ConsoleHandler consoleHandler = null; try { loggers = new Hashtable<String,SOALogger>(); GLOBAL_LOGGER.addHandler( pluginLogHandler ); String value = Platform.getDebugOption("org.ebayopensource.turmeric.eclipse.logging/debug"); trace = "true".equalsIgnoreCase(value); value = Platform.getDebugOption("org.ebayopensource.turmeric.eclipse.logging/debug/level"); Level tracingLevel = value != null ? Level.parse(value) : Level.FINER; if (trace) { //This is a way to share the logging level between Plugin and CodeGen. Logger.getLogger( GLOBAL_LOGGER_ID ).setLevel(tracingLevel); Logger.getLogger( GLOBAL_LOGGER_ID_PLUGIN ).setLevel(tracingLevel); } if (GLOBAL_LOGGER.getHandlers() != null) { for (Handler handler : GLOBAL_LOGGER.getHandlers()) { if (handler instanceof ConsoleHandler) { consoleHandler = (ConsoleHandler)handler; break; } } } } catch (Exception e) { Logger.getLogger( GLOBAL_LOGGER_ID_PLUGIN ).throwing(SOALogger.class.getName(), "<static>", e); } CONSOLE_HANDLER = consoleHandler; try { ISOALoggingSystemProvider logSystemProvider = SOALoggingSystemExtensionRegistry.getInstance() .getLoggingSystemIDProvider(PluginLogDelegateHandler.getBuildSystemName()); if (logSystemProvider != null) { logSystemProvider.initLoggingSystem(); } } catch (Exception e) { //ignore the issue e.printStackTrace(); } URL input = SOALogger.class.getResource(FILENAME_LOGGING_PROPERTIES); if (input != null) { String localConfigFile = new StringBuilder().append( System.getProperty("user.home")).append(File.separator) //$NON-NLS-1$ .append(".turmeric").append(File.separator).append( //$NON-NLS-1$ FILENAME_LOGGING_PROPERTIES).toString(); //$NON-NLS-1$ File configFile = new File(localConfigFile); if (configFile.exists() == false) { OutputStream output = null; try { FileUtils.copyURLToFile(input, configFile); } catch (Exception e) { //ignore the issue e.printStackTrace(); } finally { IOUtils.closeQuietly(output); } } if (configFile.exists()) { System.setProperty("java.util.logging.config.file", configFile.getAbsolutePath()); } } LogManager.getLogManager().addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent event) { try { ISOALoggingSystemProvider logSystemProvider = SOALoggingSystemExtensionRegistry.getInstance() .getLoggingSystemIDProvider(PluginLogDelegateHandler.getBuildSystemName()); if (logSystemProvider != null) { logSystemProvider.loggingPropertyChanged(event); } } catch (Exception e) { //ignore the issue e.printStackTrace(); } } }); DEBUG = trace; } /** * Gets the log handler. * * @return the log handler */ public static Handler getLogHandler() { return pluginLogHandler; } /** * Gets the single instance of SOALogger. * * @param clazz the clazz * @return single instance of SOALogger */ public static SOALogger getInstance(Class< ? > clazz) { return getInstance(clazz.getName()); } /** * Gets the single instance of SOALogger. * * @param clazz the clazz * @return single instance of SOALogger */ public static SOALogger getInstance(String clazz) { // We want 1 logger per subsystem String subsystem = ""; if (clazz != null) { // TODO: after plugin added SOABinding in. add this back // subsystem = BindingUtils.getPackageName(clazz); if (subsystem.length() == 0) { subsystem = clazz; } } else { subsystem = ""; } return getLogger(subsystem); } private SOALogger(String loggerName) { super(loggerName, null); } /** * If the tracing is enabled, then the logging level will be setup accordingly. * * @param clazz the clazz * @return An instance of <code>LogManager</code> */ public static synchronized SOALogger getLogger(String clazz) { java.util.logging.LogManager manager = java.util.logging.LogManager.getLogManager(); Logger result = manager.getLogger(clazz); if (result instanceof SOALogger) { return (SOALogger)result; } else if (result != null) {//there is an existing logger instance if (loggers.keySet().contains(clazz)) { return loggers.get(clazz); } SOALogger logger = new SOALogger(clazz); logger.setLevel(result.getLevel()); logger.setFilter(result.getFilter()); logger.setParent(result.getParent()); logger.setUseParentHandlers(logger.getUseParentHandlers()); loggers.put(clazz, logger); return logger; } else {//can not find a logger, so let's create one. result = new SOALogger(clazz); } manager.addLogger(result); SOALogger logger = (SOALogger)manager.getLogger(clazz); try { ISOALoggingSystemProvider logSystemProvider = SOALoggingSystemExtensionRegistry.getInstance() .getLoggingSystemIDProvider(PluginLogDelegateHandler.getBuildSystemName()); if (logSystemProvider != null) { logSystemProvider.newLoggerCreated(logger); } } catch (Exception e) { //ignore the issue e.printStackTrace(); } return logger; } /** * Sets the builds the system name. * * @param name the new builds the system name */ public static void setBuildSystemName(String name) { PluginLogDelegateHandler.setBuildSystemName(name); } /** * Gets the logger. * * @param clazz The <code>Class</code> instance that is used for constructing <code>Logger</code> instance. * @return the logger */ public static SOALogger getLogger(Class<?> clazz) { SOALogger logger = getLogger(clazz.getName()); return logger; } /** * The logger name is automatically obtained. * @return An instance of <code>LogManager</code> */ public static SOALogger getLogger() { StackTraceElement[] elements = new Throwable().getStackTrace(); return getLogger(elements[1].getClassName()); } ////////////////////////////////////////// //Info Logging ////////////////////////////////////////// /** * Info. * * @param msgs The messages * @see java.util.logging.Level#INFO */ public void info(Object... msgs) { StackTraceElement[] elements = new Throwable().getStackTrace(); logp(Level.INFO, elements[1].getClassName(), elements[1].getMethodName(), StringUtil.toString(msgs)); } /** * Checks if is info enabled. * * @return <code>True</code> if the <code>INFO</code> logging level is enabled, or <code>False</code> otherwise. * @see java.util.logging.Level#INFO */ public boolean isInfoEnabled() { return isLoggable(Level.INFO); } ////////////////////////////////////////// //Warning Logging ////////////////////////////////////////// /** * Warning. * * @param messages the messages * @see java.util.logging.Level#WARNING */ public void warning(Object... messages) { StackTraceElement[] elements = new Throwable().getStackTrace(); logp(Level.WARNING, elements[1].getClassName(), elements[1].getMethodName(), StringUtil.toString(messages)); } /** * Warning. * * @param cause the cause * @param messages The warning messages * @see java.util.logging.Level#WARNING */ public void warning(Throwable cause, Object... messages) { StackTraceElement[] elements = new Throwable().getStackTrace(); logp(Level.WARNING, elements[1].getClassName(), elements[1].getMethodName(), StringUtil.toString(messages), cause); } /** * <p>This method will work if the <code>WARNING</code> logging level is enabled.</p> * @param message The message * @param cause The cause of the problem * @see java.util.logging.Level#WARNING */ public void warning(Object message, Throwable cause) { StackTraceElement[] elements = new Throwable().getStackTrace(); logp(Level.WARNING, elements[1].getClassName(), elements[1].getMethodName(), String.valueOf(message), cause); } ////////////////////////////////////////// //Error Logging ////////////////////////////////////////// /** * Error. * * @param msg The error message * @see java.util.logging.Level#SEVERE */ public void error(String msg) { StackTraceElement[] elements = new Throwable().getStackTrace(); logp(Level.SEVERE, elements[1].getClassName(), elements[1].getMethodName(), String.valueOf(msg)); } /** * Error. * * @param message The error message * @param cause The cause of the error * @see java.util.logging.Level#SEVERE */ public void error(Object message, Throwable cause) { StackTraceElement[] elements = new Throwable().getStackTrace(); logp(Level.SEVERE, elements[1].getClassName(), elements[1].getMethodName(), String.valueOf(message), cause); } /** * Error. * * @param cause The cause of the error * @see java.util.logging.Level#SEVERE */ public void error(Throwable cause) { StackTraceElement[] elements = new Throwable().getStackTrace(); logp(Level.SEVERE, elements[1].getClassName(), elements[1].getMethodName(),cause.getLocalizedMessage(), cause); } /** * Throwing. * * @param thrown The instance of <code>Throwable</code> * @see java.util.logging.Level#SEVERE */ public void throwing(Throwable thrown) { StackTraceElement[] elements = new Throwable().getStackTrace(); throwing(elements[1].getClassName(), elements[1].getMethodName(), thrown); } ////////////////////////////////////////// //Debug Logging ////////////////////////////////////////// /** * Debug. * * @param msgs the msgs * @see java.util.logging.Level#FINE */ public void debug(Object... msgs) { StackTraceElement[] elements = new Throwable().getStackTrace(); logp(Level.FINE, elements[1].getClassName(), elements[1].getMethodName(), StringUtil.toString(msgs)); } ////////////////////////////////////////// //Logging Entry/Exit ////////////////////////////////////////// /** * Entering. * * @param params The multiple parameters that passed in * @see java.util.logging.Level#FINER */ public void entering(Object... params) { StackTraceElement[] elements = new Throwable().getStackTrace(); if (params != null) entering(elements[1].getClassName(), elements[1].getMethodName(), params); else entering(elements[1].getClassName(), elements[1].getMethodName()); } /** * <p>Suitable for logging methods with <code>void</code> return type.</p> * @see java.util.logging.Level#FINER */ public void exiting() { StackTraceElement[] elements = new Throwable().getStackTrace(); exiting(elements[1].getClassName(), elements[1].getMethodName()); } /** * Exiting. * * @param result The result of the method call * @see java.util.logging.Level#FINER */ public void exiting(Object result) { StackTraceElement[] elements = new Throwable().getStackTrace(); exiting(elements[1].getClassName(), elements[1].getMethodName(), result); } }