package at.sprinternet.apache; /** * @author Christoph Haas * * Parse an Apache log file with Regular Expressions * * output is configurable * * @version 1.0 */ import java.io.BufferedReader; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.regex.*; /** * Parse an Apache log file with Regular Expressions */ public class LogFileParser{ private static final int NUM_FIELDS = 9; private static final String FIELD_SPACE = "# #"; private static final int[] DEFAULT_FIELDS = new int[] {1,3,4,5,6,7,8,9}; private static final String logEntryPattern = "^([\\d.]+) (\\S+) (\\S+) \\[([\\w:/]+\\s[+\\-]\\d{4})\\] \"(.+?)\" (\\d{3}) (\\d+) \"([^\"]+)\" \"([^\"]+)\""; private static boolean showDebugOutput = false; private static String logFilePath = ""; private static String parsedFilePath = ""; private static String filter = ""; private static int[] filterFields = DEFAULT_FIELDS; private static File logFile; private static Pattern pattern = Pattern.compile(logEntryPattern); private static String[] parseLine(String line) { String[] returnString = new String[filterFields.length]; Matcher matcher = pattern.matcher(line); if (!matcher.matches() || NUM_FIELDS != matcher.groupCount()) { System.err.println("Bad log entry (or problem with RE?):"); System.err.println(line); } else { for(int i = 0; i < filterFields.length; i++) { returnString[i] = matcher.group(filterFields[i]); } if(showDebugOutput) { System.out.println("IP Address: " + matcher.group(1)); System.out.println("User: " + matcher.group(3)); System.out.println("Date&Time: " + matcher.group(4)); System.out.println("Request: " + matcher.group(5)); System.out.println("Response: " + matcher.group(6)); System.out.println("Bytes Sent: " + matcher.group(7)); if (!matcher.group(8).equals("-")) System.out.println("Referer: " + matcher.group(8)); System.out.println("Browser: " + matcher.group(9)); } } return returnString; } private static void parseFilter() { if(filter != null && filter != "" && filter != " ") { String[] split = filter.split(" "); filterFields = new int[split.length]; for(int i = 0; i < split.length; i++) { int id = 2; // default id... should alwasy be - if(split[i].equals("ip")) id = 1; else if(split[i].equals("user")) id = 3; else if(split[i].equals("datetime")) id = 4; else if(split[i].equals("request")) id = 5; else if(split[i].equals("response")) id = 6; else if(split[i].equals("size")) id = 7; else if(split[i].equals("referer")) id = 8; else if(split[i].equals("browser")) id = 9; filterFields[i] = id; } } } public static void main(String argv[]) throws IOException { if(argv.length < 1) { System.err.println("Invalid argument count!"); System.err.println("Usage: "); System.err.println("java LogFileParser [options]"); System.err.println("Options: "); System.err.println("-o "); System.err.println("-f "); System.err.println("Filter: (seperated by space)"); System.err.println("ip, user, request, response, datetime, size, referer, browser"); System.exit(1); } else { logFilePath = argv[0]; logFile = new File(logFilePath); if(logFile.canRead()) { if(showDebugOutput) { System.out.println("Using Logfile: " + logFilePath); } } else { System.err.println("Cannot read logfile: " + logFilePath); System.exit(1); } // we have options =) if(argv.length > 1) { int options = argv.length -1; String option = ""; boolean isOption = false; for(int i=1; i <= options; i++) { // we have a optionstartpoint... if(argv[i].contains("-") && !isOption) { isOption = true; option = argv[i].substring(1); } else if(isOption) { if(option.equals("o")) { if(argv[i].startsWith("-")) { System.err.println("Option -o needs more arguments!"); System.exit(1); } else { parsedFilePath = argv[i]; isOption = false; } } else if(option.equals("f")) { if(argv[i].startsWith("-")) { isOption = false; i--; // reuse this option! } else { filter = filter + argv[i] + " "; } } else { System.err.println("Incorrect option " + option); System.exit(1); } } parseFilter(); } } } // Read the logfile line by line FileInputStream fileStream = new FileInputStream(logFile); DataInputStream in = new DataInputStream(fileStream); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); String line; if(parsedFilePath != null && parsedFilePath != "") { String parsedLine = ""; File parsedFile = new File(parsedFilePath); if(!parsedFile.canWrite() && !parsedFile.createNewFile()) { System.err.println("Cannot write output file: " + parsedFilePath + "!!!"); System.exit(1); } FileOutputStream fileOut = new FileOutputStream(parsedFile); while((line = bufferedReader.readLine()) != null){ String[] pLine = parseLine(line); for(int i = 0; i < filterFields.length; i++) { if(i != 0) { parsedLine += FIELD_SPACE; } parsedLine += pLine[i]; } parsedLine += "\n"; fileOut.write(parsedLine.getBytes()); parsedLine = ""; } System.out.println("Output written to file: " + parsedFilePath); } else { String parsedLine = ""; while((line = bufferedReader.readLine()) != null){ String[] pLine = parseLine(line); for(int i = 0; i < filterFields.length; i++) { if(i != 0) { parsedLine += FIELD_SPACE; } parsedLine += pLine[i]; } System.out.println(parsedLine); parsedLine = ""; } } } }