KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > server > logging > logviewer > backend > LogFile


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.server.logging.logviewer.backend;
24 import java.io.*;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Date JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29 import java.text.ParseException JavaDoc;
30 import java.util.Properties JavaDoc;
31 import java.util.Iterator JavaDoc;
32 import java.text.SimpleDateFormat JavaDoc;
33
34
35 /**
36  * <P>This class encapsulates the log file so that its details are not
37  * exposed. "getLongEntries" returns an unfiltered List of LogEntry objects
38  * from the requested record number. It will always search forward.
39  * getIndexSize() returns the number of records between each index.
40  * getLastIndexNumber returns the last index.</P>
41  *
42  * @AUTHOR: Hemanth Puttaswamy and Ken Paulsen
43  *
44  * <P>This class also contains an inner class for storing LogEntry
45  * objects.</P>
46  */

47 public class LogFile implements java.io.Serializable JavaDoc {
48
49     private static SimpleDateFormat JavaDoc SIMPLE_DATE_FORMAT =
50         new SimpleDateFormat JavaDoc("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
51
52     /**
53      * Constructor
54      */

55     public LogFile(String JavaDoc name) {
56     _recordIdx.add(new Long JavaDoc(0));
57     setLogFileName(name);
58     buildLogFileIndex();
59     }
60
61
62     /**
63      * This method returns up to _indexSize records starting with the given
64      * record number.
65      *
66      * @param startingRecord The starting point to search for LogEntries
67      */

68     public List JavaDoc getLogEntries(long startingRecord) {
69     return getLogEntries(startingRecord, getIndexSize());
70     }
71
72
73
74     /**
75      * This method returns up to _indexSize records starting with the given
76      * record number. It will return up to "maxRecords" records.
77      *
78      * @param startingRecord The starting point to search for LogEntries
79      * @param masRecords The maximum number of records to return
80      */

81     public List JavaDoc getLogEntries(long startingRecord, long maxRecords) {
82     if (startingRecord < 0) {
83         return null;
84     }
85
86         // Open the file at the desired starting Record
87
BufferedReader reader = getFilePosition(startingRecord);
88     List JavaDoc results = new ArrayList JavaDoc();
89     try {
90         while (results.size()<maxRecords) {
91             // Get a line from the log file
92
String JavaDoc line = reader.readLine();
93         if (line == null) {
94             break;
95         }
96         if (!line.startsWith(RECORD_BEGIN_MARKER)) {
97             continue;
98         }
99
100         // Read the whole record
101
while (!line.endsWith(RECORD_END_MARKER)) {
102             line += "\n" + reader.readLine();
103         }
104
105         // Read the LogEntry
106
try {
107             results.add(new LogEntry(line,
108                         startingRecord+results.size()));
109         } catch (IllegalArgumentException JavaDoc ex) {
110             ex.printStackTrace();
111         }
112         }
113     } catch (Exception JavaDoc ex) {
114         throw new RuntimeException JavaDoc(ex);
115     } finally {
116         if (reader != null) {
117         try {
118             reader.close();
119         } catch (IOException ex) {
120         }
121         }
122     }
123
124     // Return the results
125
return results;
126     }
127
128
129     /**
130      * This method builds the file index in the beginning. The index is for
131      * the beginning of every record after the size specified by '_indexSize'
132      * variable.
133      */

134     protected synchronized void buildLogFileIndex() {
135     int cnt, idx;
136         // NOTE: This should be -1 for indexing at the right intervals
137
long recordCount = -1;
138     char recordBeginMarker[] = RECORD_BEGIN_MARKER.toCharArray();
139     int recordBeginMarkerLen = recordBeginMarker.length;
140
141     // Open the file and skip to the where we left off
142
long charPos = ((Long JavaDoc)_recordIdx.get(_recordIdx.size()-1)).longValue();
143     BufferedReader reader = getLogFileReader(charPos);
144         long localIndexSize = getIndexSize();
145     try {
146         while (true) {
147         try {
148             cnt = reader.read();
149             if (cnt == -1) {
150             break;
151             }
152             charPos++;
153
154             // Compare to RECORD_BEGIN_MARKER
155
for (idx=0; idx<recordBeginMarkerLen; idx++) {
156             if (cnt != recordBeginMarker[idx]) {
157                 break;
158             }
159             cnt = reader.read();
160             charPos++;
161             }
162             if (idx == recordBeginMarkerLen) {
163             // Begining of a new record
164
recordCount++;
165             if (recordCount == localIndexSize) {
166                 // Now we have traversed the records equal
167
// to index size. Time to add a new entry
168
// into the index.
169
recordCount = 0;
170                 _recordIdx.add(
171                 new Long JavaDoc(charPos - (recordBeginMarkerLen+1)));
172             }
173             }
174         } catch (EOFException ex) {
175             break;
176         } catch (Exception JavaDoc ex) {
177             ex.printStackTrace();
178                     break;
179         }
180         }
181     } catch (Exception JavaDoc ex) {
182         ex.printStackTrace();
183     } finally {
184         if (reader != null) {
185         try {
186             reader.close();
187         } catch (IOException ex) {
188         }
189         }
190     }
191     }
192
193
194     /**
195      * This method returns the file position given the record number.
196      *
197      * @param recordNumber The Record Number
198      *
199      * @return The file position.
200      */

201     protected BufferedReader getFilePosition(long recordNumber) {
202     // The index is stored from the second slot. i.e., if there
203
// are 100 records and the index will be on 20, 40, 60, 80, 100
204
// if the _indexSize is 20. We don't store '0' hence we subtract
205
// from 1 to get the right index
206
int index = (int)(recordNumber / getIndexSize());
207     if (_recordIdx.size() <= index) {
208         // We have not indexed enough
209
buildLogFileIndex();
210         if (_recordIdx.size() <= index) {
211         // Hmm... something's not right
212
throw new IllegalArgumentException JavaDoc(
213             "Attempting to access Log entries that don't exist! ");
214         }
215     }
216         return getRecordPosition(index,
217             (int) (recordNumber % getIndexSize()));
218     }
219
220
221     /**
222      * Gets the precise record position from the specified FilePosition.
223      */

224     private BufferedReader getRecordPosition(int index, int recordsToAdvance) {
225     // Get the indexed file position
226
long filePosition = ((Long JavaDoc)_recordIdx.get(index)).longValue();
227         BufferedReader reader = getLogFileReader(filePosition) ;
228
229     char recordBeginMarker[] = RECORD_BEGIN_MARKER.toCharArray();
230     int recordBeginMarkerLen = recordBeginMarker.length;
231         int ch;
232         int idx;
233         while (recordsToAdvance > 0) {
234         try {
235         // If we read past the end, throw exception
236
ch = reader.read();
237         filePosition++;
238
239         // Compare to RECORD_BEGIN_MARKER
240
for (idx=0; idx<recordBeginMarkerLen; idx++) {
241             if (ch != recordBeginMarker[idx]) {
242             break;
243             }
244             ch = reader.read();
245             filePosition++;
246         }
247         if (idx == recordBeginMarkerLen) {
248             // Begining of a new record
249
recordsToAdvance--;
250         }
251         } catch (Exception JavaDoc ex) {
252                 throw new RuntimeException JavaDoc(ex);
253             }
254         }
255
256     // Return the reader
257
return reader;
258     }
259
260
261
262     /**
263      * This method opens the server.log file and moves the stream to
264      * the specified filePosition.
265      */

266     protected BufferedReader getLogFileReader(long fromFilePosition) {
267     try {
268         FileInputStream file = new FileInputStream(getLogFileName());
269         file.skip(fromFilePosition);
270         BufferedReader reader =
271         new BufferedReader(new InputStreamReader(file));
272         return reader;
273     } catch (Exception JavaDoc ex) {
274         System.err.println("Exception in openFile..." + ex);
275         ex.printStackTrace();
276     }
277     return null;
278     }
279
280
281     /**
282      *
283      */

284     public String JavaDoc getLogFileName() {
285     return _logFileName;
286     }
287
288
289     /**
290      *
291      */

292     public void setLogFileName(String JavaDoc filename) {
293     if (filename.equals(getLogFileName())) {
294         return;
295     }
296     _logFileName = filename;
297     _recordIdx = new ArrayList JavaDoc();
298     _recordIdx.add(new Long JavaDoc(0));
299     }
300
301
302     /**
303      * The log records are indexed, this method returns the last index. It
304      * will ensure that the indexes are up-to-date.
305      */

306     public long getLastIndexNumber() {
307         // Ensure the file is fully indexed for this call
308
buildLogFileIndex();
309     return _recordIdx.size()-1;
310     }
311
312
313     /**
314      *
315      */

316     public long getIndexSize() {
317     return _indexSize;
318     }
319
320
321     /**
322      * The number of records between indexes. This is also used as the max
323      * number of records returned from getLogEntries(long).
324      */

325     public void setIndexSize(long indexSize) {
326     _indexSize = indexSize;
327     }
328
329
330     /**
331      * Class to manage LogEntry information
332      */

333     public class LogEntry implements java.io.Serializable JavaDoc {
334     public LogEntry(String JavaDoc line, long recordNumber) {
335         if (!line.startsWith(RECORD_BEGIN_MARKER)) {
336         throw new IllegalArgumentException JavaDoc(
337             "Log Entries must start with: '"+RECORD_BEGIN_MARKER+
338             "': '"+line+"'.");
339         }
340
341         StringTokenizer JavaDoc tokenizer =
342         new StringTokenizer JavaDoc(line, FIELD_SEPARATOR);
343
344         // We expect atleast the following tokens to be in the first line
345
// [#, DateTime, log level, Product Name, Logger Name, Name Value
346
// Pairs.
347
// If we don't have them here. Then it's a wrong message.
348
if (!(tokenizer.countTokens() > 5)) {
349         throw new IllegalArgumentException JavaDoc(
350             "Log Entry does not contain all required fields: '"+
351             line+"'.");
352         }
353
354         // The first token is the Record Begin Marker
355
tokenizer.nextToken();
356             try {
357             setLoggedDateTime(
358                     SIMPLE_DATE_FORMAT.parse(tokenizer.nextToken()));
359             setLoggedLevel(tokenizer.nextToken());
360             setLoggedProduct(tokenizer.nextToken());
361             setLoggedLoggerName(tokenizer.nextToken());
362             setLoggedNameValuePairs(tokenizer.nextToken());
363                 String JavaDoc messageIdandMessage = tokenizer.nextToken();
364                 if( messageIdandMessage != null ) {
365                     int index = messageIdandMessage.indexOf( ":" );
366                     if( index != -1 ) {
367                         setMessageId( messageIdandMessage.substring(0,index ) );
368                         setLoggedMessage(
369                             messageIdandMessage.substring(index+1));
370                     } else {
371                         setLoggedMessage(messageIdandMessage);
372                     }
373                 }
374             setRecordNumber(recordNumber);
375             } catch( Exception JavaDoc e ) {
376                 RuntimeException JavaDoc t =
377                     new RuntimeException JavaDoc( "Error in building Log Entry " );
378                 t.initCause( e );
379                 throw t;
380             }
381     }
382
383
384     /**
385      *
386      */

387     public Date JavaDoc getLoggedDateTime() {
388         return this.loggedDateTime;
389     }
390
391
392     /**
393      *
394      */

395     public void setLoggedDateTime(Date JavaDoc loggedDateTime) {
396         this.loggedDateTime = loggedDateTime;
397     }
398
399
400     /**
401      *
402      */

403     public String JavaDoc getLoggedLevel() {
404         return loggedLevel;
405     }
406
407
408     /**
409      *
410      */

411     public void setLoggedLevel(String JavaDoc loggedLevel) {
412         this.loggedLevel = loggedLevel;
413     }
414
415
416     /**
417      *
418      */

419     public String JavaDoc getLoggedProduct() {
420         return loggedProduct;
421     }
422
423
424     /**
425      *
426      */

427     public void setLoggedProduct(String JavaDoc loggedProduct) {
428         this.loggedProduct = loggedProduct;
429     }
430
431
432     /**
433      *
434      */

435     public String JavaDoc getLoggedLoggerName() {
436         return loggedLoggerName;
437     }
438
439
440     /**
441      *
442      */

443     public void setLoggedLoggerName(String JavaDoc loggedLoggerName) {
444         this.loggedLoggerName = loggedLoggerName;
445     }
446
447
448     /**
449      *
450      */

451     public String JavaDoc getLoggedNameValuePairs() {
452         return loggedNameValuePairs;
453     }
454
455
456     /**
457      *
458      */

459     public void setLoggedNameValuePairs(String JavaDoc loggedNameValuePairs) {
460         this.loggedNameValuePairs = loggedNameValuePairs;
461     }
462
463
464
465     /**
466      *
467      */

468     public void setLoggedMessage(String JavaDoc message) {
469         this.loggedMessage = message;
470     }
471
472     public void appendLoggedMessage(String JavaDoc message) {
473         loggedMessage += message;
474     }
475
476
477     /**
478      *
479      */

480     public String JavaDoc getLoggedMessage() {
481         return loggedMessage;
482     }
483
484         public String JavaDoc getMessageId( ) {
485             return messageId;
486         }
487
488         public void setMessageId( String JavaDoc messageId ) {
489             this.messageId = messageId;
490         }
491
492     /**
493      *
494      */

495     public long getRecordNumber() {
496         return recordNumber;
497     }
498
499
500
501
502     /**
503      *
504      */

505     public void setRecordNumber(long recordNumber) {
506         this.recordNumber = recordNumber;
507     }
508
509     public String JavaDoc toString() {
510         return ""+getRecordNumber();
511     }
512
513
514     private long recordNumber = -1;
515     private Date JavaDoc loggedDateTime = null;
516     private String JavaDoc loggedLevel = null;
517     private String JavaDoc loggedProduct = null;
518     private String JavaDoc loggedLoggerName = null;
519     private String JavaDoc loggedNameValuePairs = null;
520     private String JavaDoc loggedMessage = null;
521     private String JavaDoc messageId = "";
522     }
523
524
525
526     public static final String JavaDoc RECORD_BEGIN_MARKER = "[#|";
527     public static final String JavaDoc RECORD_END_MARKER = "|#]";
528     public static final String JavaDoc FIELD_SEPARATOR = "|";
529
530
531     private long _indexSize = 10;
532     private String JavaDoc _logFileName = null;
533     private List JavaDoc _recordIdx = new ArrayList JavaDoc();
534 }
535
Popular Tags