/* * Password Management Servlets (PWM) * http://www.pwm-project.org * * Copyright (c) 2006-2009 Novell, Inc. * Copyright (c) 2009-2017 The PWM Project * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package password.pwm.util.logging; import com.novell.ldapchai.ChaiUser; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Layout; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.apache.log4j.RollingFileAppender; import org.apache.log4j.xml.DOMConfigurator; import password.pwm.AppProperty; import password.pwm.PwmApplication; import password.pwm.PwmApplicationMode; import password.pwm.PwmConstants; import password.pwm.config.Configuration; import password.pwm.util.java.FileSystemUtility; import password.pwm.util.localdb.LocalDB; import password.pwm.util.localdb.LocalDBException; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; public class PwmLogManager { private static final PwmLogger LOGGER = PwmLogger.forClass(PwmLogManager.class); public static final List<Package> LOGGING_PACKAGES = Collections.unmodifiableList(Arrays.asList( PwmApplication.class.getPackage(), ChaiUser.class.getPackage(), Package.getPackage("org.jasig.cas.client") )); public static void deinitializeLogger() { // clear all existing package loggers for (final Package logPackage : LOGGING_PACKAGES) { if (logPackage != null) { final Logger logger = Logger.getLogger(logPackage.getName()); logger.setAdditivity(false); logger.removeAllAppenders(); logger.setLevel(Level.TRACE); } } PwmLogger.setLocalDBLogger(null,null); PwmLogger.setPwmApplication(null); PwmLogger.setFileAppender(null); } public static void initializeLogger( final PwmApplication pwmApplication, final Configuration config, final File log4jConfigFile, final String consoleLogLevel, final File pwmApplicationPath, final String fileLogLevel ) { PwmLogger.setPwmApplication(pwmApplication); // try to configure using the log4j config file (if it exists) if (log4jConfigFile != null) { try { if (!log4jConfigFile.exists()) { throw new Exception("file not found: " + log4jConfigFile.getAbsolutePath()); } DOMConfigurator.configure(log4jConfigFile.getAbsolutePath()); LOGGER.debug("successfully initialized log4j using file " + log4jConfigFile.getAbsolutePath()); return; } catch (Exception e) { LOGGER.error("error loading log4jconfig file '" + log4jConfigFile + "' error: " + e.getMessage()); } } deinitializeLogger(); initConsoleLogger(config, consoleLogLevel); initFileLogger(config, fileLogLevel, pwmApplicationPath); // disable jersey warnings. java.util.logging.Logger.getLogger("org.glassfish.jersey").setLevel(java.util.logging.Level.SEVERE); } private static void initConsoleLogger( final Configuration config, final String consoleLogLevel ) { final Layout patternLayout = new PatternLayout(config.readAppProperty(AppProperty.LOGGING_PATTERN)); // configure console logging if (consoleLogLevel != null && consoleLogLevel.length() > 0 && !"Off".equals(consoleLogLevel)) { final ConsoleAppender consoleAppender = new ConsoleAppender(patternLayout); final Level level = Level.toLevel(consoleLogLevel); consoleAppender.setThreshold(level); for (final Package logPackage : LOGGING_PACKAGES) { if (logPackage != null) { final Logger logger = Logger.getLogger(logPackage.getName()); logger.setLevel(Level.TRACE); logger.addAppender(consoleAppender); } } LOGGER.debug("successfully initialized default console log4j config at log level " + level.toString()); } else { LOGGER.debug("skipping stdout log4j initialization due to blank setting for log level"); } } private static void initFileLogger( final Configuration config, final String fileLogLevel, final File pwmApplicationPath ) { final Layout patternLayout = new PatternLayout(config.readAppProperty(AppProperty.LOGGING_PATTERN)); // configure file logging final String logDirectorySetting = config.readAppProperty(AppProperty.LOGGING_FILE_PATH); final File logDirectory = FileSystemUtility.figureFilepath(logDirectorySetting, pwmApplicationPath); if (logDirectory != null && fileLogLevel != null && fileLogLevel.length() > 0 && !"Off".equals(fileLogLevel)) { try { if (!logDirectory.exists()) { if (logDirectory.mkdir()) { LOGGER.info("created directory " + logDirectory.getAbsoluteFile()); } else { throw new IOException("failed to create directory " + logDirectory.getAbsoluteFile()); } } final String fileName = logDirectory.getAbsolutePath() + File.separator + PwmConstants.PWM_APP_NAME + ".log"; final RollingFileAppender fileAppender = new RollingFileAppender(patternLayout,fileName,true); final Level level = Level.toLevel(fileLogLevel); fileAppender.setThreshold(level); fileAppender.setMaxBackupIndex(Integer.parseInt(config.readAppProperty(AppProperty.LOGGING_FILE_MAX_ROLLOVER))); fileAppender.setMaxFileSize(config.readAppProperty(AppProperty.LOGGING_FILE_MAX_SIZE)); PwmLogger.setFileAppender(fileAppender); for (final Package logPackage : LOGGING_PACKAGES) { if (logPackage != null) { //if (!logPackage.equals(PwmApplication.class.getPackage())) { final Logger logger = Logger.getLogger(logPackage.getName()); logger.setLevel(Level.TRACE); logger.addAppender(fileAppender); //} } } LOGGER.debug("successfully initialized default file log4j config at log level " + level.toString()); } catch (IOException e) { LOGGER.debug("error initializing RollingFileAppender: " + e.getMessage()); } } } public static LocalDBLogger initializeLocalDBLogger(final PwmApplication pwmApplication) { final LocalDB localDB = pwmApplication.getLocalDB(); if (pwmApplication.getApplicationMode() == PwmApplicationMode.READ_ONLY) { LOGGER.trace("skipping initialization of LocalDBLogger due to read-only mode"); return null; } // initialize the localDBLogger final LocalDBLogger localDBLogger; final PwmLogLevel localDBLogLevel = pwmApplication.getConfig().getEventLogLocalDBLevel(); try { localDBLogger = initLocalDBLogger(localDB, pwmApplication); if (localDBLogger != null) { PwmLogger.setLocalDBLogger(localDBLogLevel, localDBLogger); } } catch (Exception e) { LOGGER.warn("unable to initialize localDBLogger: " + e.getMessage()); return null; } // add appender for other packages; try { final LocalDBLog4jAppender localDBLog4jAppender = new LocalDBLog4jAppender(localDBLogger); localDBLog4jAppender.setThreshold(localDBLogLevel.getLog4jLevel()); for (final Package logPackage : LOGGING_PACKAGES) { if (logPackage != null && !logPackage.equals(PwmApplication.class.getPackage())) { final Logger logger = Logger.getLogger(logPackage.getName()); logger.addAppender(localDBLog4jAppender); logger.setLevel(Level.TRACE); } } } catch (Exception e) { LOGGER.warn("unable to initialize localDBLogger/extraAppender: " + e.getMessage()); } return localDBLogger; } static LocalDBLogger initLocalDBLogger( final LocalDB pwmDB, final PwmApplication pwmApplication ) { try { final LocalDBLoggerSettings settings = LocalDBLoggerSettings.fromConfiguration(pwmApplication.getConfig()); return new LocalDBLogger(pwmApplication, pwmDB, settings); } catch (LocalDBException e) { //nothing to do; } return null; } }