View Javadoc

1   package net.sf.logdistiller.logtypes;
2   
3   /*
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  import java.io.*;
18  import java.text.SimpleDateFormat;
19  import java.text.DateFormat;
20  import java.text.ParseException;
21  import java.util.Date;
22  import java.util.Locale;
23  import java.util.regex.Pattern;
24  
25  import net.sf.logdistiller.LogEvent;
26  import net.sf.logdistiller.LogType;
27  
28  /**
29   * Oracle Database's <code>alert.log</code> file parser. A typical rule configuration with such log files is:
30   *
31   * <pre>
32   * &lt;group id=&quot;ORA&quot;&gt;
33   *  &lt;description&gt;ORA-* messages&lt;/description&gt;
34   *  &lt;condition&gt;
35   *    &lt;match attribute=&quot;message&quot; type=&quot;contains&quot;&gt;ORA-&lt;/match&gt;
36   *  &lt;/condition&gt;
37   *  &lt;plugin type=&quot;sampling&quot;&gt;
38   *    &lt;param name=&quot;attribute&quot;&gt;message&lt;/param&gt;
39   *    &lt;param name=&quot;regexp&quot;&gt;(ORA-\d+)&lt;/param&gt;
40   *  &lt;/plugin&gt;
41   * lt;/group&gt;
42   * </pre>
43   *
44   * By default, the classification rules generated by the GUI for this type of logs:
45   * <ol>
46   * <li>will contain a such "ORA" group for events with an ORA- id</li>
47   * <li>but won't be able to sort other events, as the log event structure is too generic (the message has no specific
48   * format).</li>
49   * </ol>
50   *
51   * @since 0.9
52   */
53  public class OracleAlertLogEvent
54      extends LogEvent
55      implements Comparable
56  {
57      public final static String ID = "oracle-alert";
58  
59      public final String timestamp;
60  
61      public final Date date;
62  
63      public final String message;
64  
65      public final static LogType LOGTYPE = new LogType.Basic( ID );
66  
67      private final static DateFormat DATE_FORMAT = new SimpleDateFormat( "EEE MMM dd HH:mm:ss yyyy", Locale.US );
68  
69      private final static String[] ATTRIBUTE_NAMES =
70          { "logSource", "timestamp", "timestamp.day", "timestamp.time", "message" };
71  
72      public final static LogType.Description DESCRIPTION = new Description( (LogType.Basic) LOGTYPE, ATTRIBUTE_NAMES );
73  
74      public OracleAlertLogEvent( Factory factory, String firstLine, String message )
75          throws ParseException
76      {
77          super( factory, firstLine + Factory.NEWLINE + message );
78          timestamp = firstLine;
79          date = DATE_FORMAT.parse( timestamp );
80          this.message = message;
81          setAttributes( new String[] { factory.getLogSource(), timestamp,
82              timestamp.substring( 0, 10 ) + timestamp.substring( 19, 24 ), timestamp.substring( 11, 19 ), message } );
83      }
84  
85      public int compareTo( Object o )
86      {
87          return date.compareTo( ( (OracleAlertLogEvent) o ).date );
88      }
89  
90      private static class Description
91          extends LogType.Description
92      {
93          public Description( LogType.Basic logtype, String[] attributeNames )
94          {
95              super( logtype, attributeNames );
96              logtype.setDescription( this );
97          }
98  
99          public LogEvent.Factory newFactory( Reader reader, String logSource )
100             throws IOException
101         {
102             return new Factory( this, reader, logSource );
103         }
104 
105         public String getDefaultSpecificGroups()
106         {
107             return "  <group id=\"ORA\">\n"
108                 + "    <description>ORA-* messages</description>\n"
109                 + "    <condition>\n"
110                 + "      <match attribute=\"message\" type=\"contains\">ORA-</match>\n"
111                 + "    </condition>\n"
112                 + "    <report publisher=\"file\"/>\n"
113                 + "    <plugin type=\"sampling\">\n"
114                 + "      <param name=\"attribute\">message</param>\n"
115                 + "      <param name=\"regexp\">(ORA-\\d+)</param>\n"
116                 + "    </plugin>\n"
117                 + "  </group>";
118         }
119     }
120 
121     private static class Factory
122         extends LogEvent.Factory
123     {
124         private final LineNumberReader reader;
125 
126         private String curLine;
127 
128         private final static Pattern DATE_PATTERN =
129             Pattern.compile( "\\w{3} \\w{3} \\d{2} \\d{2}:\\d{2}:\\d{2} \\d{4}" );
130 
131         public Factory( Description description, Reader reader, String logSource )
132             throws FileNotFoundException
133         {
134             super( description, logSource );
135             this.reader = new LineNumberReader( reader );
136         }
137 
138         /**
139          * Detect the start of a new log event
140          */
141         protected boolean detectLogEventStart( String line )
142         {
143             return DATE_PATTERN.matcher( line ).matches();
144         }
145 
146         protected LogEvent readNextEvent()
147             throws IOException, ParseException
148         {
149             if ( curLine == null )
150             {
151                 curLine = reader.readLine();
152                 if ( curLine == null )
153                 {
154                     // EOF
155                     return null;
156                 }
157                 // beginning of log file does not start with a complete log event with timestamp
158                 while ( !detectLogEventStart( curLine ) )
159                 {
160                     curLine = reader.readLine();
161                     if ( curLine == null )
162                     {
163                         // EOF
164                         return null;
165                     }
166                 }
167             }
168             String firstLine = curLine;
169             StringBuffer buffer = new StringBuffer();
170             while ( ( ( curLine = reader.readLine() ) != null ) && ( !detectLogEventStart( curLine ) ) )
171             {
172                 if ( buffer.length() > 0 )
173                 {
174                     buffer.append( NEWLINE );
175                 }
176                 buffer.append( curLine );
177             }
178             return new OracleAlertLogEvent( this, firstLine, buffer.toString() );
179         }
180     }
181 }