/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at * * http://www.dspace.org/license/ */ package org.dspace.core; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.util.Enumeration; import java.util.Properties; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; import org.apache.log4j.xml.DOMConfigurator; import org.dspace.services.ConfigurationService; import org.dspace.services.KernelStartupCallbackService; import org.dspace.services.factory.DSpaceServicesFactory; /** * Service which simply initializes DSpace logging *after* the kernel starts * * @author Tim Donohue */ public class LoggerServiceImpl implements KernelStartupCallbackService { /** log4j category */ private static Logger log = Logger.getLogger(LoggerServiceImpl.class); // System property which will disable DSpace's log4j setup private final String LOG_DISABLE_PROPERTY = "dspace.log.init.disable"; // Logging settings which are specified in DSpace's configuration private final String LOG_CONFIG_PROPERTY = "log.init.config"; /** * After kernel starts up, initialize Log4j based on the logging settings * in our ConfigurationService. */ @Override public void executeCallback() { try { /* * Initialize Logging once ConfigurationManager is initialized. * * This is controlled by a property in dspace.cfg. If the property * is absent then nothing will be configured and the application * will use the defaults provided by log4j. * * Property format is: * * log.init.config = ${dspace.dir}/config/log4j.properties * or * log.init.config = ${dspace.dir}/config/log4j.xml * * See default log4j initialization documentation here: * http://logging.apache.org/log4j/docs/manual.html * * If there is a problem with the file referred to in * "log.configuration", it needs to be sent to System.err * so do not instantiate another Logging configuration. * */ ConfigurationService config = DSpaceServicesFactory.getInstance().getConfigurationService(); String dsLogConfiguration = config.getProperty(LOG_CONFIG_PROPERTY); if (dsLogConfiguration == null || System.getProperty(LOG_DISABLE_PROPERTY) != null) { /* * Do nothing if log config not set in dspace.cfg or "dspace.log.init.disable" * system property set. Leave it upto log4j to properly init its logging * via classpath or system properties. */ info("Using default log4j provided log configuration." + " If unintended, check your dspace.cfg for (" +LOG_CONFIG_PROPERTY+ ")"); } else { info("Using dspace provided log configuration (" +LOG_CONFIG_PROPERTY+ ")"); File logConfigFile = new File(dsLogConfiguration); if(logConfigFile.exists()) { info("Loading: " + dsLogConfiguration); // Check if we have an XML config if(logConfigFile.getName().endsWith(".xml")) { // Configure log4j via the DOMConfigurator DOMConfigurator.configure(logConfigFile.toURI().toURL()); } else // Otherwise, assume a Properties file { // Parse our log4j properties file Properties log4jProps = new Properties(); try(InputStream fis = new FileInputStream(logConfigFile)) { log4jProps.load(fis); } catch(IOException e) { fatal("Can't load dspace provided log4j configuration from " + logConfigFile.getAbsolutePath(), e); } // Configure log4j based on all its properties PropertyConfigurator.configure(log4jProps); } } else { info("File does not exist: " + dsLogConfiguration); } } } catch (MalformedURLException e) { fatal("Can't load dspace provided log4j configuration", e); throw new IllegalStateException("Cannot load dspace provided log4j configuration",e); } } /** * Attempt to log an INFO statement. If Log4j is not yet setup, send to System OUT * @param string */ private void info(String string) { if (!isLog4jConfigured()) { System.out.println("INFO: " + string); } else { log.info(string); } } /** * Attempt to log a WARN statement. If Log4j is not yet setup, send to System OUT * @param string */ private void warn(String string) { if (!isLog4jConfigured()) { System.out.println("WARN: " + string); } else { log.warn(string); } } /** * Attempt to log a FATAL statement. If Log4j is not yet setup, send to System ERR * @param string * @param e */ private void fatal(String string, Exception e) { if (!isLog4jConfigured()) { System.err.println("FATAL: " + string); e.printStackTrace(System.err); } else { log.fatal(string, e); } } /** * Only current solution available to detect if log4j is truly configured. * <p> * Based on samples here: http://wiki.apache.org/logging-log4j/UsefulCode */ private boolean isLog4jConfigured() { Enumeration<?> appenders = org.apache.log4j.LogManager.getRootLogger() .getAllAppenders(); if (!(appenders instanceof org.apache.log4j.helpers.NullEnumeration)) { return true; } else { Enumeration<?> loggers = org.apache.log4j.LogManager.getCurrentLoggers(); while (loggers.hasMoreElements()) { Logger c = (Logger) loggers.nextElement(); if (!(c.getAllAppenders() instanceof org.apache.log4j.helpers.NullEnumeration)) { return true; } } } return false; } }