Log file receiver configurations can now be loaded from both log4j.xml and log4j.properties configuration fileappender entries
Also reordered the receiver config panel entries and made loading events from a log4j config file the default option, reworded radio button text Project: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/repo Commit: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/commit/cf258edd Tree: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/tree/cf258edd Diff: http://git-wip-us.apache.org/repos/asf/logging-chainsaw/diff/cf258edd Branch: refs/heads/master Commit: cf258eddaaf3813e91e39cbce1fbcf442ef7d354 Parents: 910dc45 Author: Scott Deboy <[email protected]> Authored: Sat Nov 6 18:47:24 2010 +0000 Committer: Scott Deboy <[email protected]> Committed: Sat Nov 6 18:47:24 2010 +0000 ---------------------------------------------------------------------- .../chainsaw/LogFilePatternLayoutBuilder.java | 149 ++++++++++++++----- .../java/org/apache/log4j/chainsaw/LogUI.java | 4 - .../chainsaw/ReceiverConfigurationPanel.java | 18 +-- .../log4j/chainsaw/help/release-notes.html | 4 + 4 files changed, 126 insertions(+), 49 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/cf258edd/src/main/java/org/apache/log4j/chainsaw/LogFilePatternLayoutBuilder.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/chainsaw/LogFilePatternLayoutBuilder.java b/src/main/java/org/apache/log4j/chainsaw/LogFilePatternLayoutBuilder.java index 1249863..1b6c518 100644 --- a/src/main/java/org/apache/log4j/chainsaw/LogFilePatternLayoutBuilder.java +++ b/src/main/java/org/apache/log4j/chainsaw/LogFilePatternLayoutBuilder.java @@ -17,19 +17,21 @@ package org.apache.log4j.chainsaw; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Properties; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import org.apache.log4j.FileAppender; import org.apache.log4j.helpers.OptionConverter; import org.apache.log4j.pattern.ClassNamePatternConverter; import org.apache.log4j.pattern.DatePatternConverter; @@ -145,7 +147,85 @@ public class LogFilePatternLayoutBuilder return buffer.toString(); } - public static Map getAppenderConfiguration(File file) throws IOException, ParserConfigurationException, SAXException { + public static Map getAppenderConfiguration(File file) { + try { + return getXMLFileAppenderConfiguration(file); + } catch (IOException e) { + //ignore + } catch (ParserConfigurationException e) { + //ignore + } catch (SAXException e) { + //ignore + } + try { + return getPropertiesFileAppenderConfiguration(file); + } catch (Exception e) { + //ignore + } + //don't return null + return new HashMap(); + } + + public static Map getPropertiesFileAppenderConfiguration(File propertyFile) throws IOException, ParserConfigurationException, SAXException { + Map result = new HashMap(); + String appenderPrefix = "log4j.appender"; + Properties props = new Properties(); + FileInputStream inputStream = null; + try { + inputStream = new FileInputStream(propertyFile); + props.load(inputStream); + Enumeration propertyNames = props.propertyNames(); + Map appenders = new HashMap(); + while (propertyNames.hasMoreElements()) { + String propertyName = propertyNames.nextElement().toString(); + if (propertyName.startsWith(appenderPrefix)) { + String value = propertyName.substring(appenderPrefix.length() + 1); + if (value.indexOf(".") == -1) { + //no sub-values - this entry is the appender name & class + appenders.put(value, props.getProperty(propertyName).trim()); + } + } + } + for (Iterator iter = appenders.entrySet().iterator();iter.hasNext();) { + Map.Entry appenderEntry = (Map.Entry)iter.next(); + String appenderName = appenderEntry.getKey().toString(); + String appenderClassName = appenderEntry.getValue().toString(); + if (appenderClassName.toLowerCase().endsWith("fileappender")) { + String layout = props.getProperty(appenderPrefix + "." + appenderName + ".layout"); + if (layout != null && layout.trim().equals("org.apache.log4j.PatternLayout")) { + String conversion = props.getProperty(appenderPrefix + "." + appenderName + ".layout.ConversionPattern"); + String file = props.getProperty(appenderPrefix + "." + appenderName + ".File"); + if (conversion != null && file != null) { + Map entry = new HashMap(); + entry.put("file", file.trim()); + entry.put("conversion", conversion.trim()); + result.put(appenderName, entry); + } + } + } + } + /* + example: + log4j.appender.R=org.apache.log4j.RollingFileAppender + log4j.appender.R.File=${catalina.base}/logs/tomcat.log + log4j.appender.R.MaxFileSize=10MB + log4j.appender.R.MaxBackupIndex=10 + log4j.appender.R.layout=org.apache.log4j.PatternLayout + log4j.appender.R.layout.ConversionPattern=%d - %p %t %c - %m%n + */ + } + catch (IOException ioe) { + } + finally { + if (inputStream != null) { + inputStream.close(); + } + } + //don't return null + return result; + } + + private static Map getXMLFileAppenderConfiguration(File file) throws IOException, ParserConfigurationException, SAXException { InputStream stream = file.toURI().toURL().openStream(); Map result = new HashMap(); try { @@ -163,50 +243,47 @@ public class LogFilePatternLayoutBuilder NamedNodeMap appenderAttributes = appender.getAttributes(); // Class appenderClass = Class.forName(map.getNamedItem("class").getNodeValue()); Node appenderClass = appenderAttributes.getNamedItem("class"); - try { - if (appenderAttributes.getNamedItem("name") != null && appenderClass != null && appenderClass.getNodeValue() != null) { - //load the class or try to support custom subclasses that we don't have available in the classpath but end in 'FileAppender' - if (appenderClass.getNodeValue().toLowerCase().endsWith("fileappender") || FileAppender.class.isAssignableFrom(Class.forName(appenderClass.getNodeValue()))) { - String appenderName = appenderAttributes.getNamedItem("name").getNodeValue(); - //subclass of FileAppender - add it - Map entry = new HashMap(); - NodeList appenderChildren = appender.getChildNodes(); - for (int j = 0; j < appenderChildren.getLength(); j++) { - Node appenderChild = appenderChildren.item(j); - if (appenderChild.getNodeName().equals("param") && appenderChild.hasAttributes()) { - Node fileNameNode = appenderChild.getAttributes().getNamedItem("name"); - if (fileNameNode != null && fileNameNode.getNodeValue().equals("file")) { - Node fileValueNode = appenderChild.getAttributes().getNamedItem("value"); - if (fileValueNode != null) { - entry.put("file", fileValueNode.getNodeValue()); - } + if (appenderAttributes.getNamedItem("name") != null && appenderClass != null && appenderClass.getNodeValue() != null) { + //all log4j fileappenders end in fileappender..if a custom fileappender also ends in fileappender and uses the same dom nodes to be loaded, + //try to parse the nodes as well + if (appenderClass.getNodeValue().toLowerCase().endsWith("fileappender")) { + String appenderName = appenderAttributes.getNamedItem("name").getNodeValue(); + //subclass of FileAppender - add it + Map entry = new HashMap(); + NodeList appenderChildren = appender.getChildNodes(); + for (int j = 0; j < appenderChildren.getLength(); j++) { + Node appenderChild = appenderChildren.item(j); + if (appenderChild.getNodeName().equals("param") && appenderChild.hasAttributes()) { + Node fileNameNode = appenderChild.getAttributes().getNamedItem("name"); + if (fileNameNode != null && fileNameNode.getNodeValue().equals("file")) { + Node fileValueNode = appenderChild.getAttributes().getNamedItem("value"); + if (fileValueNode != null) { + entry.put("file", fileValueNode.getNodeValue()); } } - if (appenderChild.getNodeName().equals("layout") && appenderChild.hasAttributes()) { - NamedNodeMap layoutAttributes = appenderChild.getAttributes(); - Node layoutNode = layoutAttributes.getNamedItem("class"); - if (layoutNode != null && layoutNode.getNodeValue() != null && layoutNode.getNodeValue().equals("org.apache.log4j.PatternLayout")) { - NodeList layoutChildren = appenderChild.getChildNodes(); - for (int k = 0; k < layoutChildren.getLength(); k++) { - Node layoutChild = layoutChildren.item(k); - if (layoutChild.getNodeName().equals("param") && layoutChild.hasAttributes()) { - Node layoutName = layoutChild.getAttributes().getNamedItem("name"); - if (layoutName != null && layoutName.getNodeValue() != null && layoutName.getNodeValue().equals("ConversionPattern")) { - Node conversionValue = layoutChild.getAttributes().getNamedItem("value"); - if (conversionValue != null) { - entry.put("conversion", conversionValue.getNodeValue()); - } + } + if (appenderChild.getNodeName().equals("layout") && appenderChild.hasAttributes()) { + NamedNodeMap layoutAttributes = appenderChild.getAttributes(); + Node layoutNode = layoutAttributes.getNamedItem("class"); + if (layoutNode != null && layoutNode.getNodeValue() != null && layoutNode.getNodeValue().equals("org.apache.log4j.PatternLayout")) { + NodeList layoutChildren = appenderChild.getChildNodes(); + for (int k = 0; k < layoutChildren.getLength(); k++) { + Node layoutChild = layoutChildren.item(k); + if (layoutChild.getNodeName().equals("param") && layoutChild.hasAttributes()) { + Node layoutName = layoutChild.getAttributes().getNamedItem("name"); + if (layoutName != null && layoutName.getNodeValue() != null && layoutName.getNodeValue().equals("ConversionPattern")) { + Node conversionValue = layoutChild.getAttributes().getNamedItem("value"); + if (conversionValue != null) { + entry.put("conversion", conversionValue.getNodeValue()); } } } } } } - result.put(appenderName, entry); } + result.put(appenderName, entry); } - } catch (Exception e) { - e.printStackTrace(); } } } finally { http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/cf258edd/src/main/java/org/apache/log4j/chainsaw/LogUI.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/chainsaw/LogUI.java b/src/main/java/org/apache/log4j/chainsaw/LogUI.java index e8bf684..61e9bf3 100644 --- a/src/main/java/org/apache/log4j/chainsaw/LogUI.java +++ b/src/main/java/org/apache/log4j/chainsaw/LogUI.java @@ -1496,10 +1496,6 @@ public class LogUI extends JFrame implements ChainsawViewer, SettingsListener { } } catch (IOException e1) { e1.printStackTrace(); - } catch (ParserConfigurationException e1) { - e1.printStackTrace(); - } catch (SAXException e1) { - e1.printStackTrace(); } } } else if (receiverConfigurationPanel.getModel().isLoadConfig()) { http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/cf258edd/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java b/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java index a6c3715..c755963 100644 --- a/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java +++ b/src/main/java/org/apache/log4j/chainsaw/ReceiverConfigurationPanel.java @@ -139,17 +139,17 @@ class ReceiverConfigurationPanel extends JPanel { c.gridx = 0; c.gridy = yPos++; c.fill = GridBagConstraints.HORIZONTAL; - logFileReceiverRadioButton = new JRadioButton(" Load and tail events from a regular text log file "); - buttonGroup.add(logFileReceiverRadioButton); - add(logFileReceiverRadioButton, c); + log4jConfigReceiverRadioButton = new JRadioButton(" Use fileappender entries from a log4j config file "); + buttonGroup.add(log4jConfigReceiverRadioButton); + add(log4jConfigReceiverRadioButton, c); c = new GridBagConstraints(); c.gridx = 0; c.gridy = yPos++; c.fill = GridBagConstraints.HORIZONTAL; - log4jConfigReceiverRadioButton = new JRadioButton(" Use log4j.xml fileappender configuration "); - buttonGroup.add(log4jConfigReceiverRadioButton); - add(log4jConfigReceiverRadioButton, c); + logFileReceiverRadioButton = new JRadioButton(" Process a log file "); + buttonGroup.add(logFileReceiverRadioButton); + add(logFileReceiverRadioButton, c); c = new GridBagConstraints(); c.gridx = 0; @@ -163,7 +163,7 @@ class ReceiverConfigurationPanel extends JPanel { c.gridx = 0; c.gridy = yPos++; c.fill = GridBagConstraints.HORIZONTAL; - useExistingConfigurationRadioButton = new JRadioButton(" Use an existing Chainsaw configuration file "); + useExistingConfigurationRadioButton = new JRadioButton(" Use a Chainsaw config file "); buttonGroup.add(useExistingConfigurationRadioButton); add(useExistingConfigurationRadioButton, c); @@ -204,8 +204,8 @@ class ReceiverConfigurationPanel extends JPanel { networkReceiverRadioButton.addActionListener(al); useExistingConfigurationRadioButton.addActionListener(al); - buttonGroup.setSelected(logFileReceiverRadioButton.getModel(), true); - updateEnabledState(logFileReceiverRadioButton); + buttonGroup.setSelected(log4jConfigReceiverRadioButton.getModel(), true); + updateEnabledState(log4jConfigReceiverRadioButton); } private JPanel buildDontWarnAndOKPanel() { http://git-wip-us.apache.org/repos/asf/logging-chainsaw/blob/cf258edd/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html ---------------------------------------------------------------------- diff --git a/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html b/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html index f267cea..59a0fb5 100644 --- a/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html +++ b/src/main/resources/org/apache/log4j/chainsaw/help/release-notes.html @@ -10,6 +10,10 @@ <b>NOTE:</b> The mechanism and format used to persist settings in Chainsaw is subject to change. If you are experiencing problems displaying events in Chainsaw, please delete everything in the $user.dir/.chainsaw directory and restart Chainsaw. <br> <h1>2.1</h1> +<h2>6 Nov 2010</h2> +<ul> +<li>Log file receiver configurations can now be loaded from both log4j.xml and log4j.properties configuration fileappender entries</li> +</ul> <h2>5 Nov 2010</h2> <ul> <li>Added ability to create log file receiver configurations from log4j xml configuration fileappender entries</li>
