1 package net.sf.logdistiller.logtypes;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 import java.io.*;
18 import java.text.DateFormat;
19 import java.text.ParseException;
20 import java.text.SimpleDateFormat;
21 import java.util.Date;
22 import java.util.Locale;
23 import java.util.Map;
24
25 import net.sf.logdistiller.LogEvent;
26 import net.sf.logdistiller.LogType;
27 import net.sf.logdistiller.util.FormatUtil;
28 import net.sf.logdistiller.util.LogEventBuilder;
29 import net.sf.logdistiller.util.StringCutter;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 public class WeblogicLogEvent
52 extends LogEvent
53 implements Comparable<WeblogicLogEvent>
54 {
55 public final static String ID = "weblogic";
56
57 public final Date date;
58
59 public final String timestamp;
60
61 public final String severity;
62
63 public final String subsystem;
64
65 public final String machine;
66
67 public final String server;
68
69 public final String thread_id;
70
71 public final String transaction_id;
72
73 public final String user_id;
74
75 public final String message_id;
76
77 public final String message_text;
78
79 public final String stacktrace;
80
81 public final static LogType LOGTYPE = new WlLogType();
82
83 private final static String LOGEVENT_START = "####<";
84
85 private final static String[] ATTRIBUTE_NAMES =
86 { "logSource", "timestamp", "severity", "subsystem", "machine", "server", "thread_id", "transaction_id",
87 "user_id", "message_id", "message_text", "stacktrace" };
88
89 public WeblogicLogEvent( Factory factory, String rawLog )
90 throws ParseException
91 {
92 super( factory, rawLog );
93 StringCutter cutter = new StringCutter( rawLog );
94 cutter.parseTo( LOGEVENT_START );
95 timestamp = cutter.parseTo( "> <" );
96 date = factory.parseDate( timestamp );
97 severity = cutter.parseTo( "> <" );
98 subsystem = cutter.parseTo( "> <" );
99 machine = cutter.parseTo( "> <" );
100 server = cutter.parseTo( "> <" );
101 thread_id = cutter.parseTo( "> <" );
102 transaction_id = cutter.parseTo( "> <" );
103 user_id = cutter.parseTo( "> <" );
104 message_id = cutter.parseTo( "> <" );
105 message_text = cutter.parseTo( "> " );
106 String remaining = cutter.getRemaining();
107 stacktrace = ( "".equals( remaining ) ) ? "" : remaining.substring( LogEvent.Factory.NEWLINE.length() );
108 setAttributes( new String[] { factory.getLogSource(), timestamp, severity, subsystem, machine, server,
109 thread_id, transaction_id, user_id, message_id, message_text, stacktrace } );
110 }
111
112 public int compareTo( WeblogicLogEvent o )
113 {
114 return date.compareTo( o.date );
115 }
116
117
118
119
120
121
122
123
124 private static class WlLogType
125 extends LogType
126 {
127 private final static String DEFAULT_DATE_FORMAT = "MMM d, yyyy K:mm:ss a zz";
128
129 public WlLogType()
130 {
131 super( WeblogicLogEvent.ID );
132 }
133
134 public LogType.Description newDescription( Map<String, String> params )
135 {
136 String dateFormat = params.get( "date.format" );
137 dateFormat = ( dateFormat == null ) ? DEFAULT_DATE_FORMAT : dateFormat;
138 String locale = params.get( "date.locale" );
139 Locale lcle = ( locale == null ) ? Locale.US : FormatUtil.parseLocale( locale );
140 return new WeblogicLogEvent.Description( this, WeblogicLogEvent.ATTRIBUTE_NAMES, dateFormat, lcle );
141 }
142 }
143
144 private static class Description
145 extends LogType.Description
146 {
147
148 private final String format;
149
150
151 private final Locale locale;
152
153
154 private final DateFormat df;
155
156 public Description( LogType logtype, String[] attributeNames, String format, Locale locale )
157 {
158 super( logtype, attributeNames );
159 this.format = format;
160 this.locale = locale;
161 this.df = new SimpleDateFormat( format, locale );
162 }
163
164 public LogEvent.Factory newFactory( Reader reader, String logSource )
165 throws IOException
166 {
167 return new Factory( this, reader, logSource );
168 }
169
170
171 public DateFormat getDateFormat()
172 {
173 return df;
174 }
175
176
177 public Locale getLocale()
178 {
179 return locale;
180 }
181
182
183 public String getFormat()
184 {
185 return format;
186 }
187
188 public String getDefaultSpecificGroups()
189 {
190 return " <group id=\"warning\">\n"
191 + " <description>Warning events</description>\n"
192 + " <condition>\n"
193 + " <match attribute=\"severity\" type=\"equals\">Warning</match>\n"
194 + " </condition>\n"
195 + " <report publisher=\"file\"/>\n"
196 + " <plugin type=\"sampling\">\n"
197 + " <param name=\"attributes\">subsystem,message_id</param>\n"
198 + " </plugin>\n"
199 + " </group>\n"
200 + "\n"
201 + " <group id=\"error\">\n"
202 + " <description>Error events</description>\n"
203 + " <condition>\n"
204 + " <match attribute=\"severity\" type=\"equals\">Error</match>\n"
205 + " </condition>\n"
206 + " <report publisher=\"file\"/>\n"
207 + " <plugin type=\"sampling\">\n"
208 + " <param name=\"attributes\">subsystem,message_id</param>\n"
209 + " </plugin>\n"
210 + " </group>";
211 }
212
213 public String getDefaultSamplingAttributes()
214 {
215 return "severity,subsystem,message_id";
216 }
217 }
218
219 private static class Factory
220 extends LogEvent.Factory
221 {
222 private final DateFormat df;
223
224 private final LineNumberReader reader;
225
226 private String curLine;
227
228 public Factory( Description description, Reader reader, String logSource )
229 throws FileNotFoundException
230 {
231 super( description, logSource );
232 this.reader = new LineNumberReader( reader );
233 this.df = description.getDateFormat();
234 }
235
236 protected boolean detectLogEventStart( String line )
237 {
238 return line.startsWith( LOGEVENT_START );
239 }
240
241 protected LogEvent readNextEvent()
242 throws IOException, ParseException
243 {
244 if ( curLine == null )
245 {
246 curLine = reader.readLine();
247 if ( curLine == null )
248 {
249
250 return null;
251 }
252 }
253
254 int lineNumber = reader.getLineNumber();
255
256 if ( !detectLogEventStart( curLine ) )
257 {
258 if ( curLine.length() > 15 )
259 {
260 curLine = curLine.substring( 0, 15 ) + "... (line " + lineNumber + ")";
261 }
262 String msg = " should start with '" + LOGEVENT_START + "' but found '" + curLine + "'";
263 if ( reader.getLineNumber() == 1 )
264 {
265 throw new ParseException( "bad log format: is it really a Weblogic log file? It" + msg, 0 );
266 }
267 throw new ParseException( "bad log format, line " + reader.getLineNumber() + msg, 0 );
268 }
269
270 StringBuffer buffer = new StringBuffer( curLine );
271 while ( ( ( curLine = reader.readLine() ) != null ) && ( !detectLogEventStart( curLine ) ) )
272 {
273 buffer.append( NEWLINE );
274 buffer.append( curLine );
275 }
276
277 return BUILDER.buildLogEvent( this, lineNumber, buffer.toString() );
278 }
279
280 private final static LogEventBuilder BUILDER = new LogEventBuilder()
281 {
282 protected LogEvent newEvent( LogEvent.Factory factory, String curLine, Object... objects )
283 throws ParseException
284 {
285 return new WeblogicLogEvent( (Factory)factory, curLine );
286 }
287 };
288
289 public Date parseDate( String date )
290 throws ParseException
291 {
292 try
293 {
294 return df.parse( date );
295 }
296 catch ( ParseException pe )
297 {
298 Description desc = (Description) description;
299 throw new ParseException( pe.getMessage() + ", expected format: " + desc.getFormat()
300 + ", expected locale: " + desc.getLocale(), pe.getErrorOffset() );
301 }
302 }
303 }
304 }