| /* |
| * 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.qpid.server.logging.management; |
| |
| import org.apache.log4j.Level; |
| import org.apache.log4j.LogManager; |
| import org.apache.log4j.Logger; |
| import org.apache.log4j.xml.Log4jEntityResolver; |
| import org.apache.log4j.xml.QpidLog4JConfigurator; |
| import org.apache.log4j.xml.QpidLog4JConfigurator.IllegalLoggerLevelException; |
| import org.apache.log4j.xml.QpidLog4JConfigurator.QpidLog4JSaxErrorHandler; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.NodeList; |
| import org.xml.sax.ErrorHandler; |
| import org.xml.sax.SAXException; |
| |
| import org.apache.qpid.management.common.mbeans.LoggingManagement; |
| import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription; |
| import org.apache.qpid.server.management.AMQManagedObject; |
| |
| import javax.management.JMException; |
| import javax.management.openmbean.CompositeData; |
| import javax.management.openmbean.CompositeDataSupport; |
| import javax.management.openmbean.CompositeType; |
| import javax.management.openmbean.OpenDataException; |
| import javax.management.openmbean.OpenType; |
| import javax.management.openmbean.SimpleType; |
| import javax.management.openmbean.TabularData; |
| import javax.management.openmbean.TabularDataSupport; |
| import javax.management.openmbean.TabularType; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.parsers.ParserConfigurationException; |
| import javax.xml.transform.OutputKeys; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerException; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.stream.StreamResult; |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Random; |
| |
| import static org.apache.log4j.xml.QpidLog4JConfigurator.LOCK; |
| |
| |
| /** MBean class for BrokerLoggingManagerMBean. It implements all the management features exposed for managing logging. */ |
| @MBeanDescription("Logging Management Interface") |
| public class LoggingManagementMBean extends AMQManagedObject implements LoggingManagement |
| { |
| |
| private static final Logger _logger = Logger.getLogger(LoggingManagementMBean.class); |
| private String _log4jConfigFileName; |
| private int _log4jLogWatchInterval; |
| private static final String INHERITED = "INHERITED"; |
| private static final String[] LEVELS = new String[]{Level.ALL.toString(), Level.TRACE.toString(), |
| Level.DEBUG.toString(), Level.INFO.toString(), |
| Level.WARN.toString(), Level.ERROR.toString(), |
| Level.FATAL.toString(),Level.OFF.toString(), |
| INHERITED}; |
| private static TabularType _loggerLevelTabularType; |
| private static CompositeType _loggerLevelCompositeType; |
| |
| static |
| { |
| try |
| { |
| OpenType[] loggerLevelItemTypes = new OpenType[]{SimpleType.STRING, SimpleType.STRING}; |
| |
| _loggerLevelCompositeType = new CompositeType("LoggerLevelList", "Logger Level Data", |
| COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), |
| COMPOSITE_ITEM_DESCRIPTIONS.toArray(new String[COMPOSITE_ITEM_DESCRIPTIONS.size()]), |
| loggerLevelItemTypes); |
| |
| _loggerLevelTabularType = new TabularType("LoggerLevel", "List of loggers with levels", |
| _loggerLevelCompositeType, |
| TABULAR_UNIQUE_INDEX.toArray(new String[TABULAR_UNIQUE_INDEX.size()])); |
| } |
| catch (OpenDataException e) |
| { |
| _logger.error("Tabular data setup for viewing logger levels was incorrect."); |
| _loggerLevelTabularType = null; |
| } |
| } |
| |
| public LoggingManagementMBean(String log4jConfigFileName, int log4jLogWatchInterval) throws JMException |
| { |
| super(LoggingManagement.class, LoggingManagement.TYPE); |
| _log4jConfigFileName = log4jConfigFileName; |
| _log4jLogWatchInterval = log4jLogWatchInterval; |
| } |
| |
| public String getObjectInstanceName() |
| { |
| return LoggingManagement.TYPE; |
| } |
| |
| public Integer getLog4jLogWatchInterval() |
| { |
| return _log4jLogWatchInterval; |
| } |
| |
| public String[] getAvailableLoggerLevels() |
| { |
| return LEVELS; |
| } |
| @SuppressWarnings("unchecked") |
| public synchronized boolean setRuntimeLoggerLevel(String logger, String level) |
| { |
| //check specified level is valid |
| Level newLevel; |
| try |
| { |
| newLevel = getLevel(level); |
| } |
| catch (Exception e) |
| { |
| return false; |
| } |
| |
| //check specified logger exists |
| Enumeration loggers = LogManager.getCurrentLoggers(); |
| Boolean loggerExists = false; |
| |
| while(loggers.hasMoreElements()) |
| { |
| Logger log = (Logger) loggers.nextElement(); |
| if (log.getName().equals(logger)) |
| { |
| loggerExists = true; |
| break; |
| } |
| } |
| |
| if(!loggerExists) |
| { |
| return false; |
| } |
| |
| //set the logger to the new level |
| _logger.info("Setting level to " + level + " for logger: " + logger); |
| |
| Logger log = Logger.getLogger(logger); |
| log.setLevel(newLevel); |
| |
| return true; |
| } |
| |
| @SuppressWarnings("unchecked") |
| public synchronized TabularData viewEffectiveRuntimeLoggerLevels() |
| { |
| if (_loggerLevelTabularType == null) |
| { |
| _logger.warn("TabluarData type not set up correctly"); |
| return null; |
| } |
| |
| _logger.info("Getting levels for currently active log4j loggers"); |
| |
| Enumeration loggers = LogManager.getCurrentLoggers(); |
| |
| TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType); |
| |
| Logger logger; |
| String loggerName; |
| String level; |
| |
| try |
| { |
| while(loggers.hasMoreElements()){ |
| logger = (Logger) loggers.nextElement(); |
| |
| loggerName = logger.getName(); |
| level = logger.getEffectiveLevel().toString(); |
| |
| Object[] itemData = {loggerName, level}; |
| CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, |
| COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), itemData); |
| loggerLevelList.put(loggerData); |
| } |
| } |
| catch (OpenDataException e) |
| { |
| _logger.warn("Unable to create logger level list due to :" + e); |
| return null; |
| } |
| |
| return loggerLevelList; |
| |
| } |
| |
| public synchronized String getRuntimeRootLoggerLevel() |
| { |
| Logger rootLogger = Logger.getRootLogger(); |
| |
| return rootLogger.getLevel().toString(); |
| } |
| |
| public synchronized boolean setRuntimeRootLoggerLevel(String level) |
| { |
| Level newLevel; |
| try |
| { |
| newLevel = getLevel(level); |
| } |
| catch (Exception e) |
| { |
| return false; |
| } |
| |
| if(newLevel == null) |
| { |
| //A null Level reference implies inheritance. Setting the runtime RootLogger |
| //to null is catastrophic (and prevented by Log4J at startup and runtime anyway). |
| return false; |
| } |
| |
| _logger.info("Setting RootLogger level to " + level); |
| |
| Logger log = Logger.getRootLogger(); |
| log.setLevel(newLevel); |
| |
| return true; |
| } |
| |
| //method to convert from a string to a log4j Level, throws exception if the given value is invalid |
| private Level getLevel(String level) throws Exception |
| { |
| if("null".equalsIgnoreCase(level) || INHERITED.equalsIgnoreCase(level)) |
| { |
| //the string "null" or "inherited" signals to inherit from a parent logger, |
| //using a null Level reference for the logger. |
| return null; |
| } |
| |
| Level newLevel = Level.toLevel(level); |
| |
| //above Level.toLevel call returns a DEBUG Level if the request fails. Check the result. |
| if (newLevel.equals(Level.DEBUG) && !(level.equalsIgnoreCase("debug"))) |
| { |
| //received DEBUG but we did not ask for it, the Level request failed. |
| throw new Exception("Invalid level name"); |
| } |
| |
| return newLevel; |
| } |
| |
| //method to parse the XML configuration file, validating it in the process, and returning a DOM Document of the content. |
| private static synchronized Document parseConfigFile(String fileName) throws IOException |
| { |
| try |
| { |
| LOCK.lock(); |
| |
| //check file was specified, exists, and is readable |
| if(fileName == null) |
| { |
| _logger.warn("Provided log4j XML configuration filename is null"); |
| throw new IOException("Provided log4j XML configuration filename is null"); |
| } |
| |
| File configFile = new File(fileName); |
| |
| if (!configFile.exists()) |
| { |
| _logger.warn("The log4j XML configuration file could not be found: " + fileName); |
| throw new IOException("The log4j XML configuration file could not be found"); |
| } |
| else if (!configFile.canRead()) |
| { |
| _logger.warn("The log4j XML configuration file is not readable: " + fileName); |
| throw new IOException("The log4j XML configuration file is not readable"); |
| } |
| |
| //parse it |
| DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); |
| DocumentBuilder docBuilder; |
| Document doc; |
| |
| ErrorHandler errHandler = new QpidLog4JSaxErrorHandler(); |
| try |
| { |
| docFactory.setValidating(true); |
| docBuilder = docFactory.newDocumentBuilder(); |
| docBuilder.setErrorHandler(errHandler); |
| docBuilder.setEntityResolver(new Log4jEntityResolver()); |
| doc = docBuilder.parse(fileName); |
| } |
| catch (ParserConfigurationException e) |
| { |
| _logger.warn("Unable to parse the log4j XML file due to possible configuration error: " + e); |
| //recommended that MBeans should use java.* and javax.* exceptions only |
| throw new IOException("Unable to parse the log4j XML file due to possible configuration error: " + e.getMessage()); |
| } |
| catch (SAXException e) |
| { |
| _logger.warn("The specified log4j XML file is invalid: " + e); |
| //recommended that MBeans should use standard java.* and javax.* exceptions only |
| throw new IOException("The specified log4j XML file is invalid: " + e.getMessage()); |
| } |
| catch (IOException e) |
| { |
| _logger.warn("Unable to parse the specified log4j XML file" + e); |
| throw new IOException("Unable to parse the specified log4j XML file: " + e.getMessage()); |
| } |
| |
| return doc; |
| } |
| finally |
| { |
| LOCK.unlock(); |
| } |
| } |
| |
| |
| private static synchronized boolean writeUpdatedConfigFile(String log4jConfigFileName, Document doc) throws IOException |
| { |
| try |
| { |
| LOCK.lock(); |
| |
| File log4jConfigFile = new File(log4jConfigFileName); |
| |
| if (!log4jConfigFile.canWrite()) |
| { |
| _logger.warn("Specified log4j XML configuration file is not writable: " + log4jConfigFile); |
| throw new IOException("Specified log4j XML configuration file is not writable"); |
| } |
| |
| Transformer transformer = null; |
| try |
| { |
| transformer = TransformerFactory.newInstance().newTransformer(); |
| } |
| catch (Exception e) |
| { |
| _logger.warn("Could not create an XML transformer: " +e); |
| return false; |
| } |
| |
| transformer.setOutputProperty(OutputKeys.INDENT, "yes"); |
| transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "log4j.dtd"); |
| DOMSource source = new DOMSource(doc); |
| |
| File tmp; |
| Random r = new Random(); |
| do |
| { |
| tmp = new File(log4jConfigFile.getPath() + r.nextInt() + ".tmp"); |
| } |
| while(tmp.exists()); |
| |
| tmp.deleteOnExit(); |
| |
| try |
| { |
| StreamResult result = new StreamResult(tmp); |
| transformer.transform(source, result); |
| } |
| catch (TransformerException e) |
| { |
| _logger.warn("Could not transform the XML into new file: " +e); |
| throw new IOException("Could not transform the XML into new file: " +e); |
| } |
| |
| // Swap temp file in to replace existing configuration file. |
| File old = new File(log4jConfigFile.getAbsoluteFile() + ".old"); |
| if (old.exists()) |
| { |
| old.delete(); |
| } |
| |
| if(!log4jConfigFile.renameTo(old)) |
| { |
| //unable to rename the existing file to the backup name |
| _logger.error("Could not backup the existing log4j XML file"); |
| throw new IOException("Could not backup the existing log4j XML file"); |
| } |
| |
| if(!tmp.renameTo(log4jConfigFile)) |
| { |
| //failed to rename the new file to the required filename |
| |
| if(!old.renameTo(log4jConfigFile)) |
| { |
| //unable to return the backup to required filename |
| _logger.error("Could not rename the new log4j configuration file into place, and unable to restore original file"); |
| throw new IOException("Could not rename the new log4j configuration file into place, and unable to restore original file"); |
| } |
| |
| _logger.error("Could not rename the new log4j configuration file into place"); |
| throw new IOException("Could not rename the new log4j configuration file into place"); |
| } |
| |
| return true; |
| } |
| finally |
| { |
| LOCK.unlock(); |
| } |
| } |
| |
| |
| /* The log4j XML configuration file DTD defines three possible element |
| * combinations for specifying optional logger+level settings. |
| * Must account for the following: |
| * |
| * <category name="x"> <priority value="y"/> </category> OR |
| * <category name="x"> <level value="y"/> </category> OR |
| * <logger name="x"> <level value="y"/> </logger> |
| * |
| * Noting also that the level/priority child element is optional too, |
| * and not the only possible child element. |
| */ |
| |
| public static synchronized Map<String,String> retrieveConfigFileLoggersLevels(String fileName) throws IOException |
| { |
| try |
| { |
| LOCK.lock(); |
| |
| Document doc = parseConfigFile(fileName); |
| |
| HashMap<String,String> loggerLevelList = new HashMap<String,String>(); |
| |
| //retrieve the 'category' element nodes |
| NodeList categoryElements = doc.getElementsByTagName("category"); |
| |
| String categoryName; |
| String priority = null; |
| |
| for (int i = 0; i < categoryElements.getLength(); i++) |
| { |
| Element categoryElement = (Element) categoryElements.item(i); |
| categoryName = categoryElement.getAttribute("name"); |
| |
| //retrieve the category's mandatory 'priority' or 'level' element's value. |
| //It may not be the only child node, so request by tag name. |
| NodeList priorityElements = categoryElement.getElementsByTagName("priority"); |
| NodeList levelElements = categoryElement.getElementsByTagName("level"); |
| |
| if (priorityElements.getLength() != 0) |
| { |
| Element priorityElement = (Element) priorityElements.item(0); |
| priority = priorityElement.getAttribute("value"); |
| } |
| else if (levelElements.getLength() != 0) |
| { |
| Element levelElement = (Element) levelElements.item(0); |
| priority = levelElement.getAttribute("value"); |
| } |
| else |
| { |
| //there is no exiting priority or level to view, move onto next category/logger |
| continue; |
| } |
| |
| loggerLevelList.put(categoryName, priority); |
| } |
| |
| //retrieve the 'logger' element nodes |
| NodeList loggerElements = doc.getElementsByTagName("logger"); |
| |
| String loggerName; |
| String level; |
| |
| for (int i = 0; i < loggerElements.getLength(); i++) |
| { |
| Element loggerElement = (Element) loggerElements.item(i); |
| loggerName = loggerElement.getAttribute("name"); |
| |
| //retrieve the logger's mandatory 'level' element's value |
| //It may not be the only child node, so request by tag name. |
| NodeList levelElements = loggerElement.getElementsByTagName("level"); |
| |
| Element levelElement = (Element) levelElements.item(0); |
| level = levelElement.getAttribute("value"); |
| |
| loggerLevelList.put(loggerName, level); |
| } |
| |
| return loggerLevelList; |
| } |
| finally |
| { |
| LOCK.unlock(); |
| } |
| } |
| |
| public synchronized TabularData viewConfigFileLoggerLevels() throws IOException |
| { |
| try |
| { |
| LOCK.lock(); |
| |
| if (_loggerLevelTabularType == null) |
| { |
| _logger.warn("TabluarData type not set up correctly"); |
| return null; |
| } |
| |
| _logger.info("Getting logger levels from log4j configuration file"); |
| |
| TabularData loggerLevelList = new TabularDataSupport(_loggerLevelTabularType); |
| |
| Map<String,String> levels = retrieveConfigFileLoggersLevels(_log4jConfigFileName); |
| |
| for (Map.Entry<String,String> entry : levels.entrySet()) |
| { |
| String loggerName = entry.getKey(); |
| String level = entry.getValue(); |
| |
| try |
| { |
| Object[] itemData = {loggerName, level.toUpperCase()}; |
| CompositeData loggerData = new CompositeDataSupport(_loggerLevelCompositeType, |
| COMPOSITE_ITEM_NAMES.toArray(new String[COMPOSITE_ITEM_NAMES.size()]), itemData); |
| loggerLevelList.put(loggerData); |
| } |
| catch (OpenDataException e) |
| { |
| _logger.warn("Unable to create logger level list due to :" + e); |
| return null; |
| } |
| } |
| |
| return loggerLevelList; |
| } |
| finally |
| { |
| LOCK.unlock(); |
| } |
| } |
| |
| public synchronized boolean setConfigFileLoggerLevel(String logger, String level) throws IOException |
| { |
| try |
| { |
| LOCK.lock(); |
| |
| //check that the specified level is a valid log4j Level |
| try |
| { |
| getLevel(level); |
| } |
| catch (Exception e) |
| { |
| //it isnt a valid level |
| return false; |
| } |
| |
| _logger.info("Setting level to " + level + " for logger '" + logger |
| + "' in log4j xml configuration file: " + _log4jConfigFileName); |
| |
| Document doc = parseConfigFile(_log4jConfigFileName); |
| |
| //retrieve the 'category' and 'logger' element nodes |
| NodeList categoryElements = doc.getElementsByTagName("category"); |
| NodeList loggerElements = doc.getElementsByTagName("logger"); |
| |
| //collect them into a single elements list |
| List<Element> logElements = new ArrayList<Element>(); |
| |
| for (int i = 0; i < categoryElements.getLength(); i++) |
| { |
| logElements.add((Element) categoryElements.item(i)); |
| } |
| for (int i = 0; i < loggerElements.getLength(); i++) |
| { |
| logElements.add((Element) loggerElements.item(i)); |
| } |
| |
| //try to locate the specified logger/category in the elements retrieved |
| Element logElement = null; |
| for (Element e : logElements) |
| { |
| if (e.getAttribute("name").equals(logger)) |
| { |
| logElement = e; |
| break; |
| } |
| } |
| |
| if (logElement == null) |
| { |
| //no loggers/categories with given name found, does not exist to update |
| _logger.warn("Specified logger does not exist in the configuration file: " +logger); |
| return false; |
| } |
| |
| //retrieve the optional 'priority' or 'level' sub-element value. |
| //It may not be the only child node, so request by tag name. |
| NodeList priorityElements = logElement.getElementsByTagName("priority"); |
| NodeList levelElements = logElement.getElementsByTagName("level"); |
| |
| Element levelElement = null; |
| if (priorityElements.getLength() != 0) |
| { |
| levelElement = (Element) priorityElements.item(0); |
| } |
| else if (levelElements.getLength() != 0) |
| { |
| levelElement = (Element) levelElements.item(0); |
| } |
| else |
| { |
| //there is no exiting priority or level element to update |
| return false; |
| } |
| |
| //update the element with the new level/priority |
| levelElement.setAttribute("value", level.toLowerCase()); |
| |
| //output the new file |
| return writeUpdatedConfigFile(_log4jConfigFileName, doc); |
| } |
| finally |
| { |
| LOCK.unlock(); |
| } |
| } |
| |
| |
| /* The log4j XML configuration file DTD defines 2 possible element |
| * combinations for specifying the optional root logger level settings |
| * Must account for the following: |
| * |
| * <root> <priority value="y"/> </root> OR |
| * <root> <level value="y"/> </root> |
| * |
| * Noting also that the level/priority child element is optional too, |
| * and not the only possible child element. |
| */ |
| |
| public static synchronized String retrieveConfigFileRootLoggerLevel(String fileName) throws IOException |
| { |
| try |
| { |
| LOCK.lock(); |
| |
| Document doc = parseConfigFile(fileName); |
| |
| //retrieve the optional 'root' element node |
| NodeList rootElements = doc.getElementsByTagName("root"); |
| |
| if (rootElements.getLength() == 0) |
| { |
| //there is no root logger definition |
| return "N/A"; |
| } |
| |
| Element rootElement = (Element) rootElements.item(0); |
| |
| //retrieve the optional 'priority' or 'level' element value. |
| //It may not be the only child node, so request by tag name. |
| NodeList priorityElements = rootElement.getElementsByTagName("priority"); |
| NodeList levelElements = rootElement.getElementsByTagName("level"); |
| String priority = null; |
| |
| if (priorityElements.getLength() != 0) |
| { |
| Element priorityElement = (Element) priorityElements.item(0); |
| priority = priorityElement.getAttribute("value"); |
| } |
| else if(levelElements.getLength() != 0) |
| { |
| Element levelElement = (Element) levelElements.item(0); |
| priority = levelElement.getAttribute("value"); |
| } |
| |
| if(priority != null) |
| { |
| return priority; |
| } |
| else |
| { |
| return "N/A"; |
| } |
| } |
| finally |
| { |
| LOCK.unlock(); |
| } |
| } |
| |
| public synchronized String getConfigFileRootLoggerLevel() throws IOException |
| { |
| return retrieveConfigFileRootLoggerLevel(_log4jConfigFileName).toUpperCase(); |
| } |
| |
| public synchronized boolean setConfigFileRootLoggerLevel(String level) throws IOException |
| { |
| try |
| { |
| LOCK.lock(); |
| |
| //check that the specified level is a valid log4j Level |
| try |
| { |
| Level newLevel = getLevel(level); |
| if(newLevel == null) |
| { |
| //A null Level reference implies inheritance. Setting the config file RootLogger |
| //to "null" or "inherited" just ensures it defaults to DEBUG at startup as Log4J |
| //prevents this catastrophic situation at startup and runtime anyway. |
| return false; |
| } |
| } |
| catch (Exception e) |
| { |
| //it isnt a valid level |
| return false; |
| } |
| |
| _logger.info("Setting level to " + level + " for the Root logger in " + |
| "log4j xml configuration file: " + _log4jConfigFileName); |
| |
| Document doc = parseConfigFile(_log4jConfigFileName); |
| |
| //retrieve the optional 'root' element node |
| NodeList rootElements = doc.getElementsByTagName("root"); |
| |
| if (rootElements.getLength() == 0) |
| { |
| return false; |
| } |
| |
| Element rootElement = (Element) rootElements.item(0); |
| |
| //retrieve the optional 'priority' or 'level' sub-element value. |
| //It may not be the only child node, so request by tag name. |
| NodeList priorityElements = rootElement.getElementsByTagName("priority"); |
| NodeList levelElements = rootElement.getElementsByTagName("level"); |
| |
| Element levelElement = null; |
| if (priorityElements.getLength() != 0) |
| { |
| levelElement = (Element) priorityElements.item(0); |
| } |
| else if (levelElements.getLength() != 0) |
| { |
| levelElement = (Element) levelElements.item(0); |
| } |
| else |
| { |
| //there is no exiting priority/level to update |
| return false; |
| } |
| |
| //update the element with the new level/priority |
| levelElement.setAttribute("value", level); |
| |
| //output the new file |
| return writeUpdatedConfigFile(_log4jConfigFileName, doc); |
| } |
| finally |
| { |
| LOCK.unlock(); |
| } |
| } |
| |
| public synchronized void reloadConfigFile() throws IOException |
| { |
| try |
| { |
| LOCK.lock(); |
| |
| QpidLog4JConfigurator.configure(_log4jConfigFileName); |
| _logger.info("Applied log4j configuration from: " + _log4jConfigFileName); |
| } |
| catch (IllegalLoggerLevelException e) |
| { |
| _logger.warn("The log4j configuration reload request was aborted: " + e); |
| //recommended that MBeans should use standard java.* and javax.* exceptions only |
| throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage()); |
| } |
| catch (ParserConfigurationException e) |
| { |
| _logger.warn("The log4j configuration reload request was aborted: " + e); |
| throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage()); |
| } |
| catch (SAXException e) |
| { |
| _logger.warn("The log4j configuration reload request was aborted: " + e); |
| //recommended that MBeans should use standard java.* and javax.* exceptions only |
| throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage()); |
| } |
| catch (IOException e) |
| { |
| _logger.warn("The log4j configuration reload request was aborted: " + e); |
| throw new IOException("The log4j configuration reload request was aborted: " + e.getMessage()); |
| } |
| finally |
| { |
| LOCK.unlock(); |
| } |
| } |
| } |