1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.log4j.lf5.util;
18
19 import org.apache.log4j.lf5.Log4JLogRecord;
20 import org.apache.log4j.lf5.LogLevel;
21 import org.apache.log4j.lf5.LogLevelFormatException;
22 import org.apache.log4j.lf5.LogRecord;
23 import org.apache.log4j.lf5.viewer.LogBrokerMonitor;
24 import org.apache.log4j.lf5.viewer.LogFactor5ErrorDialog;
25 import org.apache.log4j.lf5.viewer.LogFactor5LoadingDialog;
26
27 import javax.swing.*;
28 import java.io.*;
29 import java.text.ParseException;
30 import java.text.SimpleDateFormat;
31 import java.util.Date;
32
33 /***
34 * Provides utility methods for input and output streams.
35 *
36 * @author Brad Marlborough
37 * @author Richard Hurst
38 */
39
40
41
42 public class LogFileParser implements Runnable {
43
44
45
46 public static final String RECORD_DELIMITER = "[slf5s.start]";
47 public static final String ATTRIBUTE_DELIMITER = "[slf5s.";
48 public static final String DATE_DELIMITER = ATTRIBUTE_DELIMITER + "DATE]";
49 public static final String THREAD_DELIMITER = ATTRIBUTE_DELIMITER + "THREAD]";
50 public static final String CATEGORY_DELIMITER = ATTRIBUTE_DELIMITER + "CATEGORY]";
51 public static final String LOCATION_DELIMITER = ATTRIBUTE_DELIMITER + "LOCATION]";
52 public static final String MESSAGE_DELIMITER = ATTRIBUTE_DELIMITER + "MESSAGE]";
53 public static final String PRIORITY_DELIMITER = ATTRIBUTE_DELIMITER + "PRIORITY]";
54 public static final String NDC_DELIMITER = ATTRIBUTE_DELIMITER + "NDC]";
55
56
57
58
59
60
61
62
63 private static SimpleDateFormat _sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss,S");
64 private LogBrokerMonitor _monitor;
65 LogFactor5LoadingDialog _loadDialog;
66 private InputStream _in = null;
67
68
69
70
71 public LogFileParser(File file) throws IOException,
72 FileNotFoundException {
73 this(new FileInputStream(file));
74 }
75
76 public LogFileParser(InputStream stream) throws IOException {
77 _in = stream;
78 }
79
80
81
82
83 /***
84 * Starts a new thread to parse the log file and create a LogRecord.
85 * See run().
86 * @param monitor LogBrokerMonitor
87 */
88 public void parse(LogBrokerMonitor monitor) throws RuntimeException {
89 _monitor = monitor;
90 Thread t = new Thread(this);
91 t.start();
92 }
93
94 /***
95 * Parses the file and creates new log records and adds the record
96 * to the monitor.
97 */
98 public void run() {
99
100 int index = 0;
101 int counter = 0;
102 LogRecord temp;
103 boolean isLogFile = false;
104
105 _loadDialog = new LogFactor5LoadingDialog(
106 _monitor.getBaseFrame(), "Loading file...");
107
108
109 try {
110 String logRecords = loadLogFile(_in);
111
112 while ((counter = logRecords.indexOf(RECORD_DELIMITER, index)) != -1) {
113 temp = createLogRecord(logRecords.substring(index, counter));
114 isLogFile = true;
115
116 if (temp != null) {
117 _monitor.addMessage(temp);
118 }
119
120 index = counter + RECORD_DELIMITER.length();
121 }
122
123 if (index < logRecords.length() && isLogFile) {
124 temp = createLogRecord(logRecords.substring(index));
125
126 if (temp != null) {
127 _monitor.addMessage(temp);
128 }
129 }
130
131 if (isLogFile == false) {
132 throw new RuntimeException("Invalid log file format");
133 }
134 SwingUtilities.invokeLater(new Runnable() {
135 public void run() {
136 destroyDialog();
137 }
138 });
139
140 } catch (RuntimeException e) {
141 destroyDialog();
142 displayError("Error - Invalid log file format.\nPlease see documentation"
143 + " on how to load log files.");
144 } catch (IOException e) {
145 destroyDialog();
146 displayError("Error - Unable to load log file!");
147 }
148
149 _in = null;
150 }
151
152
153
154
155 protected void displayError(String message) {
156 LogFactor5ErrorDialog error = new LogFactor5ErrorDialog(
157 _monitor.getBaseFrame(), message);
158
159 }
160
161
162
163
164 private void destroyDialog() {
165 _loadDialog.hide();
166 _loadDialog.dispose();
167 }
168
169 /***
170 * Loads a log file from a web server into the LogFactor5 GUI.
171 */
172 private String loadLogFile(InputStream stream) throws IOException {
173 BufferedInputStream br = new BufferedInputStream(stream);
174
175 int count = 0;
176 int size = br.available();
177
178 StringBuffer sb = null;
179 if (size > 0) {
180 sb = new StringBuffer(size);
181 } else {
182 sb = new StringBuffer(1024);
183 }
184
185 while ((count = br.read()) != -1) {
186 sb.append((char) count);
187 }
188
189 br.close();
190 br = null;
191 return sb.toString();
192
193 }
194
195 private String parseAttribute(String name, String record) {
196
197 int index = record.indexOf(name);
198
199 if (index == -1) {
200 return null;
201 }
202
203 return getAttribute(index, record);
204 }
205
206 private long parseDate(String record) {
207 try {
208 String s = parseAttribute(DATE_DELIMITER, record);
209
210 if (s == null) {
211 return 0;
212 }
213
214 Date d = _sdf.parse(s);
215
216 return d.getTime();
217 } catch (ParseException e) {
218 return 0;
219 }
220 }
221
222 private LogLevel parsePriority(String record) {
223 String temp = parseAttribute(PRIORITY_DELIMITER, record);
224
225 if (temp != null) {
226 try {
227 return LogLevel.valueOf(temp);
228 } catch (LogLevelFormatException e) {
229 return LogLevel.DEBUG;
230 }
231
232 }
233
234 return LogLevel.DEBUG;
235 }
236
237 private String parseThread(String record) {
238 return parseAttribute(THREAD_DELIMITER, record);
239 }
240
241 private String parseCategory(String record) {
242 return parseAttribute(CATEGORY_DELIMITER, record);
243 }
244
245 private String parseLocation(String record) {
246 return parseAttribute(LOCATION_DELIMITER, record);
247 }
248
249 private String parseMessage(String record) {
250 return parseAttribute(MESSAGE_DELIMITER, record);
251 }
252
253 private String parseNDC(String record) {
254 return parseAttribute(NDC_DELIMITER, record);
255 }
256
257 private String parseThrowable(String record) {
258 return getAttribute(record.length(), record);
259 }
260
261 private LogRecord createLogRecord(String record) {
262 if (record == null || record.trim().length() == 0) {
263 return null;
264 }
265
266 LogRecord lr = new Log4JLogRecord();
267 lr.setMillis(parseDate(record));
268 lr.setLevel(parsePriority(record));
269 lr.setCategory(parseCategory(record));
270 lr.setLocation(parseLocation(record));
271 lr.setThreadDescription(parseThread(record));
272 lr.setNDC(parseNDC(record));
273 lr.setMessage(parseMessage(record));
274 lr.setThrownStackTrace(parseThrowable(record));
275
276 return lr;
277 }
278
279
280 private String getAttribute(int index, String record) {
281 int start = record.lastIndexOf(ATTRIBUTE_DELIMITER, index - 1);
282
283 if (start == -1) {
284 return record.substring(0, index);
285 }
286
287 start = record.indexOf("]", start);
288
289 return record.substring(start + 1, index).trim();
290 }
291
292
293
294
295 }