1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.log4j.chainsaw;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.util.ArrayList;
24 import java.util.Enumeration;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
28 import java.util.Locale;
29 import java.util.Map;
30 import java.util.Properties;
31
32 import javax.xml.parsers.DocumentBuilder;
33 import javax.xml.parsers.DocumentBuilderFactory;
34 import javax.xml.parsers.ParserConfigurationException;
35
36 import org.apache.log4j.chainsaw.messages.MessageCenter;
37 import org.apache.log4j.helpers.OptionConverter;
38 import org.apache.log4j.pattern.ClassNamePatternConverter;
39 import org.apache.log4j.pattern.DatePatternConverter;
40 import org.apache.log4j.pattern.FileLocationPatternConverter;
41 import org.apache.log4j.pattern.FullLocationPatternConverter;
42 import org.apache.log4j.pattern.LevelPatternConverter;
43 import org.apache.log4j.pattern.LineLocationPatternConverter;
44 import org.apache.log4j.pattern.LineSeparatorPatternConverter;
45 import org.apache.log4j.pattern.LiteralPatternConverter;
46 import org.apache.log4j.pattern.LoggerPatternConverter;
47 import org.apache.log4j.pattern.LoggingEventPatternConverter;
48 import org.apache.log4j.pattern.MessagePatternConverter;
49 import org.apache.log4j.pattern.MethodLocationPatternConverter;
50 import org.apache.log4j.pattern.NDCPatternConverter;
51 import org.apache.log4j.pattern.PatternParser;
52 import org.apache.log4j.pattern.PropertiesPatternConverter;
53 import org.apache.log4j.pattern.RelativeTimePatternConverter;
54 import org.apache.log4j.pattern.SequenceNumberPatternConverter;
55 import org.apache.log4j.pattern.ThreadPatternConverter;
56 import org.apache.log4j.xml.Log4jEntityResolver;
57 import org.apache.log4j.xml.SAXErrorHandler;
58 import org.w3c.dom.Document;
59 import org.w3c.dom.NamedNodeMap;
60 import org.w3c.dom.Node;
61 import org.w3c.dom.NodeList;
62 import org.xml.sax.InputSource;
63 import org.xml.sax.SAXException;
64
65 public class LogFilePatternLayoutBuilder
66 {
67 public static String getLogFormatFromPatternLayout(String patternLayout) {
68 String input = OptionConverter.convertSpecialChars(patternLayout);
69 List converters = new ArrayList();
70 List fields = new ArrayList();
71 Map converterRegistry = null;
72
73 PatternParser.parse(input, converters, fields, converterRegistry, PatternParser.getPatternLayoutRules());
74 return getFormatFromConverters(converters);
75 }
76
77 public static String getTimeStampFormat(String patternLayout) {
78 int basicIndex = patternLayout.indexOf("%d");
79 if (basicIndex < 0) {
80 return null;
81 }
82
83 int index = patternLayout.indexOf("%d{");
84
85 if (index < 0) {
86 return "yyyy-MM-dd HH:mm:ss,SSS";
87 }
88
89 int length = patternLayout.substring(index).indexOf("}");
90 String timestampFormat = patternLayout.substring(index + "%d{".length(), index + length);
91 if (timestampFormat.equals("ABSOLUTE")) {
92 return "HH:mm:ss,SSS";
93 }
94 if (timestampFormat.equals("ISO8601")) {
95 return "yyyy-MM-dd HH:mm:ss,SSS";
96 }
97 if (timestampFormat.equals("DATE")) {
98 return "dd MMM yyyy HH:mm:ss,SSS";
99 }
100 return timestampFormat;
101 }
102
103 private static String getFormatFromConverters(List converters) {
104 StringBuffer buffer = new StringBuffer();
105 for (Iterator iter = converters.iterator();iter.hasNext();) {
106 LoggingEventPatternConverter converter = (LoggingEventPatternConverter)iter.next();
107 if (converter instanceof DatePatternConverter) {
108 buffer.append("TIMESTAMP");
109 } else if (converter instanceof MessagePatternConverter) {
110 buffer.append("MESSAGE");
111 } else if (converter instanceof LoggerPatternConverter) {
112 buffer.append("LOGGER");
113 } else if (converter instanceof ClassNamePatternConverter) {
114 buffer.append("CLASS");
115 } else if (converter instanceof RelativeTimePatternConverter) {
116 buffer.append("PROP(RELATIVETIME)");
117 } else if (converter instanceof ThreadPatternConverter) {
118 buffer.append("THREAD");
119 } else if (converter instanceof NDCPatternConverter) {
120 buffer.append("NDC");
121 } else if (converter instanceof LiteralPatternConverter) {
122 LiteralPatternConverter literal = (LiteralPatternConverter)converter;
123
124 literal.format(null, buffer);
125 } else if (converter instanceof SequenceNumberPatternConverter) {
126 buffer.append("PROP(log4jid)");
127 } else if (converter instanceof LevelPatternConverter) {
128 buffer.append("LEVEL");
129 } else if (converter instanceof MethodLocationPatternConverter) {
130 buffer.append("METHOD");
131 } else if (converter instanceof FullLocationPatternConverter) {
132 buffer.append("PROP(locationInfo)");
133 } else if (converter instanceof LineLocationPatternConverter) {
134 buffer.append("LINE");
135 } else if (converter instanceof FileLocationPatternConverter) {
136 buffer.append("FILE");
137 } else if (converter instanceof PropertiesPatternConverter) {
138
139
140
141
142
143 buffer.append("PROP(PROPERTIES)");
144
145 } else if (converter instanceof LineSeparatorPatternConverter) {
146
147 }
148 }
149 return buffer.toString();
150 }
151
152 public static Map getAppenderConfiguration(File file) {
153 try {
154 return getXMLFileAppenderConfiguration(file);
155 } catch (IOException e) {
156
157 } catch (ParserConfigurationException e) {
158
159 } catch (SAXException e) {
160
161 }
162 try {
163 return getPropertiesFileAppenderConfiguration(file);
164 } catch (Exception e) {
165
166 }
167
168 return new HashMap();
169 }
170
171 public static Map getPropertiesFileAppenderConfiguration(File propertyFile) throws IOException, ParserConfigurationException, SAXException {
172 Map result = new HashMap();
173 String appenderPrefix = "log4j.appender";
174 Properties props = new Properties();
175 FileInputStream inputStream = null;
176 try {
177 inputStream = new FileInputStream(propertyFile);
178 props.load(inputStream);
179 Enumeration propertyNames = props.propertyNames();
180 Map appenders = new HashMap();
181 while (propertyNames.hasMoreElements()) {
182 String propertyName = propertyNames.nextElement().toString();
183 if (propertyName.startsWith(appenderPrefix)) {
184 String value = propertyName.substring(appenderPrefix.length() + 1);
185 if (value.indexOf(".") == -1) {
186
187 appenders.put(value, props.getProperty(propertyName).trim());
188 }
189 }
190 }
191 for (Iterator iter = appenders.entrySet().iterator();iter.hasNext();) {
192 Map.Entry appenderEntry = (Map.Entry)iter.next();
193 String appenderName = appenderEntry.getKey().toString();
194 String appenderClassName = appenderEntry.getValue().toString();
195 if (appenderClassName.toLowerCase(Locale.ENGLISH).endsWith("fileappender")) {
196 String layout = props.getProperty(appenderPrefix + "." + appenderName + ".layout");
197 if (layout != null && layout.trim().equals("org.apache.log4j.PatternLayout")) {
198 String conversion = props.getProperty(appenderPrefix + "." + appenderName + ".layout.ConversionPattern");
199 String file = props.getProperty(appenderPrefix + "." + appenderName + ".File");
200 if (conversion != null && file != null) {
201 Map entry = new HashMap();
202 entry.put("file", file.trim());
203 entry.put("conversion", conversion.trim());
204 result.put(appenderName, entry);
205 }
206 }
207 }
208 }
209
210
211
212
213
214
215
216
217
218 }
219 catch (IOException ioe) {
220 }
221 finally {
222 if (inputStream != null) {
223 inputStream.close();
224 }
225 }
226
227 return result;
228 }
229
230 private static Map getXMLFileAppenderConfiguration(File file) throws IOException, ParserConfigurationException, SAXException {
231 InputStream stream = file.toURI().toURL().openStream();
232 Map result = new HashMap();
233 try {
234 InputSource src = new InputSource(stream);
235 src.setSystemId(file.toURI().toURL().toString());
236 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
237 DocumentBuilder docBuilder = dbf.newDocumentBuilder();
238
239 docBuilder.setErrorHandler(new SAXErrorHandler());
240 docBuilder.setEntityResolver(new Log4jEntityResolver());
241 Document doc = docBuilder.parse(src);
242 NodeList appenders = doc.getElementsByTagName("appender");
243 for (int i = 0; i < appenders.getLength(); i++) {
244 Node appender = appenders.item(i);
245 NamedNodeMap appenderAttributes = appender.getAttributes();
246
247 Node appenderClass = appenderAttributes.getNamedItem("class");
248 if (appenderAttributes.getNamedItem("name") != null && appenderClass != null && appenderClass.getNodeValue() != null) {
249
250
251 if (appenderClass.getNodeValue().toLowerCase(Locale.ENGLISH).endsWith("fileappender")) {
252 String appenderName = appenderAttributes.getNamedItem("name").getNodeValue();
253
254 Map entry = new HashMap();
255 NodeList appenderChildren = appender.getChildNodes();
256 for (int j = 0; j < appenderChildren.getLength(); j++) {
257 Node appenderChild = appenderChildren.item(j);
258 if (appenderChild.getNodeName().equals("param") && appenderChild.hasAttributes()) {
259 Node fileNameNode = appenderChild.getAttributes().getNamedItem("name");
260 if (fileNameNode != null && fileNameNode.getNodeValue().equalsIgnoreCase("file")) {
261 Node fileValueNode = appenderChild.getAttributes().getNamedItem("value");
262 if (fileValueNode != null) {
263 entry.put("file", fileValueNode.getNodeValue());
264 }
265 }
266 }
267 if (appenderChild.getNodeName().equalsIgnoreCase("layout") && appenderChild.hasAttributes()) {
268 NamedNodeMap layoutAttributes = appenderChild.getAttributes();
269 Node layoutNode = layoutAttributes.getNamedItem("class");
270 if (layoutNode != null && layoutNode.getNodeValue() != null && layoutNode.getNodeValue().equalsIgnoreCase("org.apache.log4j.PatternLayout")) {
271 NodeList layoutChildren = appenderChild.getChildNodes();
272 for (int k = 0; k < layoutChildren.getLength(); k++) {
273 Node layoutChild = layoutChildren.item(k);
274 if (layoutChild.getNodeName().equals("param") && layoutChild.hasAttributes()) {
275 Node layoutName = layoutChild.getAttributes().getNamedItem("name");
276 if (layoutName != null && layoutName.getNodeValue() != null && layoutName.getNodeValue().equalsIgnoreCase("conversionpattern")) {
277 Node conversionValue = layoutChild.getAttributes().getNamedItem("value");
278 if (conversionValue != null) {
279 entry.put("conversion", conversionValue.getNodeValue());
280 }
281 }
282 }
283 }
284 }
285 }
286 }
287 result.put(appenderName, entry);
288 }
289 }
290 }
291 } finally {
292 stream.close();
293 }
294 MessageCenter.getInstance().getLogger().info("getXMLFileAppenderConfiguration for file: " + file + ", result: " + result);
295 return result;
296 }
297 }