diff options
Diffstat (limited to 'java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java')
-rw-r--r-- | java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java | 320 |
1 files changed, 0 insertions, 320 deletions
diff --git a/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java b/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java deleted file mode 100644 index dca62f34b4..0000000000 --- a/java/broker/src/main/java/org/apache/log4j/xml/QpidLog4JConfigurator.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - * - */ -package org.apache.log4j.xml; - -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.xml.sax.ErrorHandler; -import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; - -import org.apache.qpid.server.logging.management.LoggingManagementMBean; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import java.io.File; -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.locks.ReentrantLock; - -/** - * Substitute for the Log4J XMLWatchdog (as used by DOMConfigurator.configureAndWatch) - * - * Extends the default behaviour with a strict parser check on the XML file before allowing the reconfiguration to proceed, - * ensuring that any parser error or warning prevents initiation of a configuration update by Log4J, which aborts mid-update - * upon fatal errors from the parser and proceeds in the event of 'regular' parser errors and warnings, in all cases allowing - * startup to proceed with whatever half-baked configuration then exists. - */ -public class QpidLog4JConfigurator -{ - //lock to protect access to the configuration file - //shared with LoggingManagementMBean - public static final ReentrantLock LOCK = new ReentrantLock(); - private static Logger _logger; - private static DOMConfigurator domConfig = new DOMConfigurator(); - - private QpidLog4JConfigurator() - { - //no instances - } - - public static void configure(String filename) throws IOException, ParserConfigurationException, - SAXException, IllegalLoggerLevelException - { - try - { - LOCK.lock(); - - parseXMLConfigFile(filename); - checkLoggerLevels(filename); - - DOMConfigurator.configure(filename); - - if(_logger == null) - { - _logger = Logger.getLogger(QpidLog4JConfigurator.class); - } - } - finally - { - LOCK.unlock(); - } - } - - public static void configureAndWatch(String filename, long delay) throws IOException, ParserConfigurationException, - SAXException, IllegalLoggerLevelException - { - parseXMLConfigFile(filename); - checkLoggerLevels(filename); - - QpidLog4JXMLWatchdog watchdog = new QpidLog4JXMLWatchdog(filename); - watchdog.setDelay(delay); - watchdog.start(); - } - - private static void parseXMLConfigFile(String fileName) throws IOException, SAXException, - ParserConfigurationException - { - try - { - LOCK.lock(); - - //check file was specified, exists, and is readable - if(fileName == null) - { - throw new IOException("Provided log4j XML configuration filename was null"); - } - - File configFile = new File(fileName); - - if (!configFile.exists()) - { - throw new IOException("The log4j XML configuration file does not exist: " + fileName); - } - else if (!configFile.canRead()) - { - throw new IOException("The log4j XML configuration file is not readable: " + fileName); - } - - //parse it - DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); - DocumentBuilder docBuilder; - - ErrorHandler errHandler = new QpidLog4JSaxErrorHandler(); - - docFactory.setValidating(true); - docBuilder = docFactory.newDocumentBuilder(); - docBuilder.setErrorHandler(errHandler); - docBuilder.setEntityResolver(new Log4jEntityResolver()); - docBuilder.parse(fileName); - } - finally - { - LOCK.unlock(); - } - } - - public static class QpidLog4JSaxErrorHandler implements ErrorHandler - { - public void error(SAXParseException e) throws SAXException - { - if(_logger != null) - { - _logger.warn(constructMessage("Error parsing XML file", e)); - } - else - { - System.err.println(constructMessage("Error parsing XML file", e)); - } - } - - public void fatalError(SAXParseException e) throws SAXException - { - throw new SAXException(constructMessage("Fatal error parsing XML file", e)); - } - - public void warning(SAXParseException e) throws SAXException - { - if(_logger != null) - { - _logger.warn(constructMessage("Warning parsing XML file", e)); - } - else - { - System.err.println(constructMessage("Warning parsing XML file", e)); - } - } - - private static String constructMessage(final String msg, final SAXParseException ex) - { - return msg + ": Line " + ex.getLineNumber()+" column " +ex.getColumnNumber() + ": " + ex.getMessage(); - } - } - - private static class QpidLog4JXMLWatchdog extends XMLWatchdog - { - public QpidLog4JXMLWatchdog(String filename) - { - super(filename); - } - - public void doOnChange() - { - try - { - LOCK.lock(); - - try - { - parseXMLConfigFile(filename); - } - catch (Exception e) - { - //logger will be instantiated following first configuration success, which has been pre-validated - //and so the null check should never actually be required. - if(_logger != null) - { - _logger.warn("Parsing the log4j XML configuration file generated errors/warnings. " + - "The new configuration was not applied. Correct the issues to prompt " + - "another update attempt: " + e.getMessage()); - } - return; - } - - try - { - checkLoggerLevels(filename); - } - catch (Exception e) - { - //logger will be instantiated following first configuration success, which has been pre-validated - //and so the null check should never actually be required. - if(_logger != null) - { - _logger.warn("Errors were found when validating the logger level values in the " + - "log4j XML configuration file. The new configuration was not applied. " + - "Correct the issues to prompt another update attempt: " + e.getMessage()); - } - return; - } - - //everything checked was ok, let the normal update process proceed - super.doOnChange(); - - //a configuration has now been applied, enable logging for future attempts - if(_logger == null) - { - _logger = Logger.getLogger(QpidLog4JConfigurator.class); - } - - _logger.info("Applied log4j configuration from: " + filename); - } - finally - { - LOCK.unlock(); - } - - } - } - - protected static void checkLoggerLevels(String filename) throws IllegalLoggerLevelException, IOException - { - //check that the logger levels specified in the XML are actually valid - - try - { - LOCK.lock(); - - //get the Logger levels to check - Map<String, String> loggersLevels; - loggersLevels = LoggingManagementMBean.retrieveConfigFileLoggersLevels(filename); - //add the RootLogger to the list too - String rootLoggerlevelString = LoggingManagementMBean.retrieveConfigFileRootLoggerLevel(filename); - loggersLevels.put("Root", rootLoggerlevelString); - - - for (Map.Entry<String, String> entry : loggersLevels.entrySet()) - { - String loggerName = entry.getKey(); - String levelString = entry.getValue(); - - //let log4j replace any properties in the string - String log4jConfiguredString = domConfig.subst(levelString); - - if(log4jConfiguredString.equals("") && ! log4jConfiguredString.equals(levelString)) - { - //log4j has returned an empty string but this isnt what we gave it. - //There may have been an undefined property. Unlike an incorrect - //literal value, we will allow this case to proceed, but warn users. - - if(_logger != null) - { - _logger.warn("Unable to detect Level value from '" + levelString - +"' for logger '" + loggerName + "', Log4J will default this to DEBUG"); - } - else - { - System.err.println("Unable to detect Level value from '" + levelString - +"' for logger " + loggerName + ", Log4J will default this to DEBUG"); - } - - continue; - } - - checkLevel(loggerName,log4jConfiguredString); - } - } - finally - { - LOCK.unlock(); - } - } - - private static void checkLevel(String loggerName, String levelString) throws IllegalLoggerLevelException - { - if("null".equalsIgnoreCase(levelString) || "inherited".equalsIgnoreCase(levelString)) - { - //the string "null" signals to inherit from a parent logger - return; - } - - Level level = Level.toLevel(levelString); - - //above Level.toLevel call returns a DEBUG Level if the request fails. Check the result. - if (level.equals(Level.DEBUG) && !(levelString.equalsIgnoreCase("debug"))) - { - //received DEBUG but we did not ask for it, the Level request failed. - throw new IllegalLoggerLevelException("Level '" + levelString + "' specified for Logger '" + loggerName + "' is invalid"); - } - } - - public static class IllegalLoggerLevelException extends Exception - { - private static final long serialVersionUID = 1L; - - public IllegalLoggerLevelException(String msg) - { - super(msg); - } - } -} - |