001 package net.sf.logdistiller.logtypes; 002 003 /* 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017 import java.io.*; 018 import java.text.ParseException; 019 020 import net.sf.logdistiller.LogEvent; 021 import net.sf.logdistiller.LogType; 022 import net.sf.logdistiller.util.StringCutter; 023 024 /** 025 * Log event for Unix syslog facility. By default, the classification rules generated by the GUI for this type of logs 026 * will sort events based on the following attributes: <code>host</code>, then <code>program</code>. 027 */ 028 public class SyslogLogEvent 029 extends LogEvent 030 { 031 public final static String ID = "syslog"; 032 033 // see http://logreport.org/doc/gen/os/ 034 public final String timestamp; 035 036 public final String host; 037 038 public final String program; 039 040 public final String pid; 041 042 public final String message; 043 044 public final static LogType LOGTYPE = new LogType.Basic( ID ); 045 046 private final static String[] ATTRIBUTE_NAMES = { "logSource", "timestamp", "host", "program", "pid", "message" }; 047 048 public final static LogType.Description DESCRIPTION = new Description( (LogType.Basic) LOGTYPE, ATTRIBUTE_NAMES ); 049 050 public SyslogLogEvent( Factory factory, String rawLog ) 051 throws ParseException 052 { 053 super( factory, rawLog ); 054 timestamp = rawLog.substring( 0, 15 ); 055 StringCutter sc = new StringCutter( rawLog, 16 ); 056 host = sc.parseTo( " " ); 057 String remaining = sc.getRemaining(); 058 if ( remaining.indexOf( ": " ) < 0 ) 059 { 060 program = ""; 061 pid = ""; 062 message = remaining; 063 } 064 else 065 { 066 // <program>[<pid>]: <message> 067 String programPid = sc.parseTo( ": " ); 068 message = sc.getRemaining(); 069 070 int index = programPid.indexOf( '[' ); 071 if ( ( index >= 0 ) && programPid.endsWith( "]" ) ) 072 { 073 program = programPid.substring( 0, index ); 074 pid = programPid.substring( index + 1, programPid.length() - 1 ); 075 } 076 else 077 { 078 program = programPid; 079 pid = ""; 080 } 081 } 082 setAttributes( new String[] { factory.getLogSource(), timestamp, host, program, pid, message } ); 083 } 084 085 private static class Description 086 extends LogType.Description 087 { 088 public Description( LogType.Basic logtype, String[] attributeNames ) 089 { 090 super( logtype, attributeNames ); 091 logtype.setDescription( this ); 092 } 093 094 public LogEvent.Factory newFactory( Reader reader, String logSource ) 095 throws IOException 096 { 097 return new Factory( this, reader, logSource ); 098 } 099 100 public String getDefaultSamplingAttributes() 101 { 102 return "host,program"; 103 } 104 } 105 106 private static class Factory 107 extends LogEvent.Factory 108 { 109 private final LineNumberReader reader; 110 111 public Factory( Description description, Reader reader, String logSource ) 112 throws FileNotFoundException 113 { 114 super( description, logSource ); 115 this.reader = new LineNumberReader( reader ); 116 } 117 118 protected LogEvent readNextEvent() 119 throws IOException, ParseException 120 { 121 String curLine = reader.readLine(); 122 if ( curLine == null ) 123 { 124 // EOF 125 return null; 126 } 127 try 128 { 129 return new SyslogLogEvent( this, curLine ); 130 } 131 catch ( RuntimeException re ) 132 { 133 throw new RuntimeException( "error while parsing line '" + curLine + "'", re ); 134 } 135 } 136 } 137 }