自定义日志阅读器——包括了一个load取Tomcat日志的分析器

9/6/2015来源:Java教程人气:682

自定义日志阅读器——包括了一个load取Tomcat日志的分析器

最近在写往公司产品里添加Tomcat适配器,以支持Tomcat。有一些功能需要摘取到Tomcat的部分日志。没有合适的工具,也不想去网上找了,就自己写了一个。

简单的画了一下设计方案:

下面直接上代码了:

日志阅读器:

  1 package com.fjn.tools.log.reader;  2   3 import java.io.File;  4 import java.util.LinkedList;  5 import java.util.List;  6 import java.util.Scanner;  7   8 import com.fjn.tools.log.reader.parser.CatalinaSimpleFormatterParser;  9  10 public class LogReader { 11     PRivate String logFile; 12     private List<LogFilter> logFilterChain = new LinkedList<LogFilter>(); 13     private final ContinueRead continueRead = new ContinueRead(); 14     private LogParser parser; 15     private final boolean doFilter(LogRecord record) { 16         for (LogFilter filter : logFilterChain) { 17             if (!filter.accept(record)) { 18                 return false; 19             } 20         } 21         return true; 22     } 23  24     public void addFilter(LogFilter filter) { 25         if(filter!=null){ 26             logFilterChain.add(filter); 27         } 28     } 29  30     public final String readLogRecords(String startTime, String endTime) { 31         if (parser == null) { 32             return null; 33         } 34         StringBuilder buff = new StringBuilder(); 35         Scanner scanner = null; 36          37         try { 38             scanner = new Scanner(new File(logFile)); 39              40  41             NewLine newLine = null; 42             if (startTime != null) { 43                 StartTimeFilter filter = new StartTimeFilter(); 44                 filter.startTime = startTime; 45                 addFilter(filter); 46             } 47             if (endTime != null) { 48                 EndTimeFilter filter = new EndTimeFilter(); 49                 filter.endTime = endTime; 50                 filter.continueRead = this.continueRead; 51                 addFilter(filter); 52             } 53             while (scanner.hasNextLine() && continueRead.value) { 54                 LogRecord record = null; 55                 if (newLine == null) { 56                     newLine = new NewLine(); 57                 } 58                 if (!newLine.hasGetNewLine) { 59                     newLine.line = scanner.nextLine(); 60                     newLine.hasGetNewLine = true; 61                 } 62                 record = parser.getLogRecord(scanner, newLine, continueRead); 63                 if (record != null) { 64                     if (doFilter(record)) { 65                         buff.append(record.toString()); 66                     } 67                 } 68             } 69         } catch (Exception ex) { 70             // Ignore it 71         } finally { 72             if (scanner != null) { 73                 scanner.close(); 74             } 75         } 76         return buff.toString(); 77     } 78  79     public static interface LogParser { 80         public LogRecord getLogRecord(Scanner scanner, NewLine newLine, 81                 ContinueRead continueRead); 82     } 83  84     public static interface LogFilter { 85         public boolean accept(LogRecord record); 86     } 87  88     public static abstract class LogRecord { 89         public String prefix; 90         public String message; 91         public String threadStack; 92         public String datetime; 93     } 94  95     public static class NewLine { 96         public boolean hasGetNewLine = false; 97         public String line = ""; 98     } 99 100     public static class ContinueRead {101         public boolean value = true;102     }103 104     private class StartTimeFilter implements LogFilter {105         private String startTime;106 107         @Override108         public boolean accept(LogRecord record) {109             if (startTime == null) {110                 return true;111             }112 113             if (startTime.compareTo(record.datetime) <= 0) {114                 return true;115             }116             return false;117         }118     }119 120     private class EndTimeFilter implements LogFilter {121         private String endTime = "";122         private ContinueRead continueRead;123 124         @Override125         public boolean accept(LogRecord record) {126             if (endTime == null || endTime.isEmpty()) {127                 return true;128             }129             if (endTime.compareTo(record.datetime) < 0) {130                 if (continueRead.value) {131                     continueRead.value = false;132                 }133                 return false;134             }135             return true;136         }137     }138     139     140     public String getLogFile() {141         return logFile;142     }143 144     public void setLogFile(String logFile) {145         this.logFile = logFile;146     }147     148 149     public LogParser getParser() {150         return parser;151     }152 153     public void setParser(LogParser parser) {154         this.parser = parser;155     }156 157     public static void main(String[] args) {158         LogReader logReader=new LogReader();159         logReader.setLogFile("E:\\Program Files\\apache/tomcat/apache-tomcat-6.0.41/logs/catalina.2015-05-12.log");160         logReader.setParser(new CatalinaSimpleFormatterParser());161         System.out.println(logReader.readLogRecords("2015-10-12 01:53:10", null));162     }163 }
LogReader

接下来是一个Tomcat日志分析器:

package com.fjn.tools.log.reader.parser;import java.util.LinkedList;import java.util.List;import java.util.Scanner;import java.util.StringTokenizer;import com.fjn.tools.log.reader.LogReader.ContinueRead;import com.fjn.tools.log.reader.LogReader.LogParser;import com.fjn.tools.log.reader.LogReader.LogRecord;import com.fjn.tools.log.reader.LogReader.NewLine;public class CatalinaSimpleFormatterParser implements LogParser {    @Override    public LogRecord getLogRecord(Scanner scanner, NewLine newLine,            ContinueRead continueRead) {        String line1 = newLine.line;        if (!line1.matches(SimpleFormatterLogRecord.prefixPattern)) {            newLine.hasGetNewLine = false;            return null;        }        boolean toNextRecord = false;        String nextLine = null;        List<String> messageLines = new LinkedList<String>();        while (!toNextRecord) {            if (scanner.hasNextLine()) {                nextLine = scanner.nextLine();                if (!nextLine.matches(SimpleFormatterLogRecord.prefixPattern)) {                    messageLines.add(nextLine);                } else {                    toNextRecord = true;                    newLine.hasGetNewLine = true;                    newLine.line = nextLine;                    break;                }            } else {                break;            }        }        SimpleFormatterLogRecord record = new SimpleFormatterLogRecord();        record.prefix = line1 + "\n";        StringBuilder messageBuilder = new StringBuilder();        StringBuilder threadStackBuilder = new StringBuilder();        boolean toThreadStack = false;        for (String lineN : messageLines) {            if (!toThreadStack                    && lineN.matches(SimpleFormatterLogRecord.threadStackStartPattern)) {                toThreadStack = true;            }            if (toThreadStack) {                threadStackBuilder.append(lineN).append("\n");            } else {                messageBuilder.append(lineN).append("\n");            }        }        record.message = messageBuilder.toString();        record.threadStack = threadStackBuilder.toString();        StringTokenizer stk = new StringTokenizer(record.prefix);        String date = stk.nextToken();        String time = stk.nextToken();        record.datetime = dateTimeFormat(date + " " + time);                return record;    }    private class SimpleFormatterLogRecord extends LogRecord {        private static final String prefixPattern = "^(\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2} ).*";        private static final String threadStackStartPattern = "^((\\w+\\.)*\\w*Exception: ).*";        public String toString() {            return this.prefix + this.message + this.threadStack;        }    }        private static String dateTimeFormat(String datetime){        StringTokenizer stk = new StringTokenizer(datetime, "- :");        int i = 0;        StringBuilder dateTimeBuilder = new StringBuilder();        while (stk.hasMoreTokens()) {            i++;            String token = stk.nextToken();            if (i < 7 && token.length() < 2) {                token = "0" + token;            }            if (i < 3) {                token += "-";            } else if (i < 4) {                token += " ";            } else if (i < 6) {                token += ":";            }            dateTimeBuilder.append(token);        }        return dateTimeBuilder.toString();    }    public static void main(String[] args) {        System.out.println(dateTimeFormat("2015-5-12 1:53:10 "));    }}
CatalinaSimpleFormatterLogParser

1) 如果想要分析其它格式的日志,只需要做相应的扩展LogParser就行了。

2) 如果想要只找包含某些关键字的日志,只需要扩展LogFilter就可以了。

3) 如果想要取得某个时间段的日志,只需要指定相应的startTime,endTime参数就可以了。