View Javadoc
1   package net.sf.logdistiller;
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.IOException;
18  import java.io.Reader;
19  import java.util.*;
20  
21  import net.sf.logdistiller.Attributes.Extension;
22  import net.sf.logdistiller.util.FormatUtil;
23  
24  /**
25   * Base class for log type implementation. A log type identifies the log format, which can be customized depending on
26   * parameter's values. When defining a new log type, {@link #newDescription newDescription(Map params)} method has to be
27   * implemented to define and handle log type's parameters.
28   *
29   * @see LogType.Basic
30   * @see LogType.Description
31   * @see LogTypes
32   */
33  public abstract class LogType
34  {
35      private final String id;
36  
37      protected LogType( String id )
38      {
39          this.id = id;
40      }
41  
42      /**
43       * Create a new log description customized with parameters.
44       *
45       * @param params the parameters to customize the log type definition
46       */
47      public abstract Description newDescription( Map<String, String> params );
48  
49      public String getId()
50      {
51          return id;
52      }
53  
54      /**
55       * Basic logtype definition that does not provide any parameters for customization. It always returns the same
56       * Description instance, which must have been set by calling {@link #setDescription}.
57       */
58      public static class Basic
59          extends LogType
60      {
61          private Description description;
62  
63          public Basic( String id )
64          {
65              super( id );
66          }
67  
68          public void setDescription( Description description )
69          {
70              this.description = description;
71          }
72  
73          public Description newDescription( Map<String, String> params )
74          {
75              if ( description == null )
76              {
77                  throw new IllegalStateException( "description must be set before basic logtype use" );
78              }
79              return description;
80          }
81      }
82  
83      /**
84       * Description of a log format corresponding to a log type. It must be subclassed for every log type to implement
85       * specialized {@link #newFactory(Reader, String)} method.
86       */
87      public static abstract class Description
88      {
89          private final LogType logtype;
90  
91          private final List<String> attributeNames;
92  
93          /**
94           * Extensions of the log type attributes. Each extension can define multiple extension attributes.
95           * @since 1.1
96           */
97          private Attributes.Extension[] extensions = Attributes.NO_EXTENSIONS;
98  
99          /**
100          * Attributes defined by extensions, with corresponding extension index position.
101          * @since 1.1
102          */
103         private Map<String, Integer> extendedAttributes = new HashMap<String, Integer>();
104 
105         /**
106          * Create a new LogType description. By convention, the first attribute should be <code>logSource</code> and the
107          * second should be the timestamp (if this notion is relevant for the log type).
108          *
109          * @param logtype
110          * @param attributeNames
111          * @see #getTimestampAttribute()
112          * @see LogEvent#getTimestamp()
113          */
114         public Description( LogType logtype, String[] attributeNames )
115         {
116             this.logtype = logtype;
117             this.attributeNames = Collections.unmodifiableList( Arrays.asList( attributeNames ) );
118         }
119 
120         public LogType getLogType()
121         {
122             return logtype;
123         }
124 
125         public List<String> getAttributeNames()
126         {
127             return attributeNames;
128         }
129 
130         public int getAttributesCount()
131         {
132             return attributeNames.size();
133         }
134 
135         public String getAttributeName( int pos )
136         {
137             return attributeNames.get( pos );
138         }
139 
140         /** @since 1.1 */
141         public void setExtensions( Attributes.Extension[] extensions )
142         {
143             this.extensions = extensions;
144             for ( int i = extensions.length - 1; i >= 0; i-- )
145             {
146                 Attributes.Extension extension = extensions[i];
147                 for ( String attribute : extension.getProvides() )
148                 {
149                     extendedAttributes.put( attribute, new Integer( i ) );
150                 }
151             }
152         }
153 
154         /** @since 1.1 */
155         public Attributes.Extension[] getExtensions()
156         {
157             return extensions;
158         }
159 
160         /**
161          * Gets the extension index position which defines corresponding attribute.
162          *
163          * @return the extension index, or -1 if not found
164          * @since 1.1
165          */
166         public int getExtensionIndex( String attribute )
167         {
168             Integer index = extendedAttributes.get( attribute );
169             return ( index == null ) ? -1 : index.intValue();
170         }
171 
172         /**
173          * Get the attribute that represents the timestamp.
174          *
175          * @return the attribute count, or <code>-1</code> if this logtype does not have a timestamp
176          */
177         public int getTimestampAttribute()
178         {
179             return 1;
180         }
181 
182         /**
183          * Get the group definitions specific to this log type that will be added to the generated rules configuration
184          * generated by the GUI.
185          *
186          * @return an XML fragment containing group definitions
187          */
188         public String getDefaultSpecificGroups()
189         {
190             return "";
191         }
192 
193         /**
194          * Get the attributes that can be used as a sorting key to get useful event sampling in the last "unknown" group
195          * (separated with a quote when multiple attributes). They will be used as a default sampling rule
196          * configuration.
197          *
198          * @return "attr1[,attr2[,...]]"
199          */
200         public String getDefaultSamplingAttributes()
201         {
202             return "";
203         }
204 
205         /**
206          * Find the attribute index corresponding to an attribute name (provided attributes only).
207          *
208          * @param name String the attribute name to search for
209          * @return int the index of the attribute, or -1 if not found
210          * @see #getExtensionIndex(String) to find an extension attribute index
211          */
212         public int getAttributeIndex( String name )
213         {
214             return attributeNames.indexOf( name );
215         }
216 
217         public AttributeInfo getAttributeInfo( String name )
218         {
219             int index = getAttributeIndex( name );
220             if ( index > -1 )
221             {
222                 return new AttributeInfo( index );
223             }
224             index = getExtensionIndex( name );
225             if ( index < 0 )
226             {
227                 throw new IllegalArgumentException( "unknown attribute '" + name + "'. "
228                     + "Provided attributes are: " + FormatUtil.join( ", ", getAttributeNames() )
229                     + ", extended attributes are: " + FormatUtil.join( ", ", extendedAttributes.keySet() ) + "." );
230             }
231             Extension extension = extensions[index];
232             return new AttributeInfo( index, extension.getProvides().indexOf( name ) );
233         }
234 
235         /**
236          * Create a new LogEvent factory for a log stream corresponding to this log description.
237          *
238          * @param reader the stream containing to parse
239          * @param logSource a textual description of the stream's source (useful when LogDistiller works on multiple
240          *            simultaneous log sources)
241          */
242         public abstract LogEvent.Factory newFactory( Reader reader, String logSource )
243             throws IOException;
244     }
245 
246     public static class AttributeInfo
247     {
248         public final boolean extended;
249 
250         public final int index;
251 
252         public final int regexpGroup;
253 
254         AttributeInfo( int index )
255         {
256             extended = false;
257             this.index = index;
258             regexpGroup = -1;
259         }
260 
261         AttributeInfo( int index, int regexpGroup )
262         {
263             extended = true;
264             this.index = index;
265             this.regexpGroup = regexpGroup;
266         }
267     }
268 }