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

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

下面直接上代码了:

日志阅读器:

 package com.fjn.tools.log.reader;

 import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner; import com.fjn.tools.log.reader.parser.CatalinaSimpleFormatterParser; public class LogReader {
private String logFile;
private List<LogFilter> logFilterChain = new LinkedList<LogFilter>();
private final ContinueRead continueRead = new ContinueRead();
private LogParser parser;
private final boolean doFilter(LogRecord record) {
for (LogFilter filter : logFilterChain) {
if (!filter.accept(record)) {
return false;
}
}
return true;
} public void addFilter(LogFilter filter) {
if(filter!=null){
logFilterChain.add(filter);
}
} public final String readLogRecords(String startTime, String endTime) {
if (parser == null) {
return null;
}
StringBuilder buff = new StringBuilder();
Scanner scanner = null; try {
scanner = new Scanner(new File(logFile)); NewLine newLine = null;
if (startTime != null) {
StartTimeFilter filter = new StartTimeFilter();
filter.startTime = startTime;
addFilter(filter);
}
if (endTime != null) {
EndTimeFilter filter = new EndTimeFilter();
filter.endTime = endTime;
filter.continueRead = this.continueRead;
addFilter(filter);
}
while (scanner.hasNextLine() && continueRead.value) {
LogRecord record = null;
if (newLine == null) {
newLine = new NewLine();
}
if (!newLine.hasGetNewLine) {
newLine.line = scanner.nextLine();
newLine.hasGetNewLine = true;
}
record = parser.getLogRecord(scanner, newLine, continueRead);
if (record != null) {
if (doFilter(record)) {
buff.append(record.toString());
}
}
}
} catch (Exception ex) {
// Ignore it
} finally {
if (scanner != null) {
scanner.close();
}
}
return buff.toString();
} public static interface LogParser {
public LogRecord getLogRecord(Scanner scanner, NewLine newLine,
ContinueRead continueRead);
} public static interface LogFilter {
public boolean accept(LogRecord record);
} public static abstract class LogRecord {
public String prefix;
public String message;
public String threadStack;
public String datetime;
} public static class NewLine {
public boolean hasGetNewLine = false;
public String line = "";
} public static class ContinueRead {
public boolean value = true;
} private class StartTimeFilter implements LogFilter {
private String startTime; @Override
public boolean accept(LogRecord record) {
if (startTime == null) {
return true;
} if (startTime.compareTo(record.datetime) <= 0) {
return true;
}
return false;
}
} private class EndTimeFilter implements LogFilter {
private String endTime = "";
private ContinueRead continueRead; @Override
public boolean accept(LogRecord record) {
if (endTime == null || endTime.isEmpty()) {
return true;
}
if (endTime.compareTo(record.datetime) < 0) {
if (continueRead.value) {
continueRead.value = false;
}
return false;
}
return true;
}
} public String getLogFile() {
return logFile;
} public void setLogFile(String logFile) {
this.logFile = logFile;
} public LogParser getParser() {
return parser;
} public void setParser(LogParser parser) {
this.parser = parser;
} public static void main(String[] args) {
LogReader logReader=new LogReader();
logReader.setLogFile("E:\\Program Files\\apache/tomcat/apache-tomcat-6.0.41/logs/catalina.2015-05-12.log");
logReader.setParser(new CatalinaSimpleFormatterParser());
System.out.println(logReader.readLogRecords("2015-10-12 01:53:10", null));
}
}

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参数就可以了。

自定义日志阅读器——包括了一个load取Tomcat日志的分析器的更多相关文章

  1. 使用chrome控制台作为日志查看器

    很多时候,我们需要查看日志的实时输出,这个时候往往只能选择控制台.我这里的日志框架是serilog,它有一个好处是控制台输出时可以高亮的形式显示其参数结构信息,如下图所示 但也存在许多不方便的地方: ...

  2. Python日志产生器

    Python日志产生器 写在前面 有的时候,可能就是我们做实时数据收集的时候,会有一个头疼的问题就是,你会发现,你可能一下子,没有日志的数据源.所以,我们可以简单使用python脚本来实现产生实时的数 ...

  3. 10.AutoMapper 之自定义值解析器(Custom Value Resolvers)

    https://www.jianshu.com/p/3e7cf1d1f17d 自定义值解析器(Custom Value Resolvers) 虽然AutoMapper涵盖了相当多的目标成员映射方案,但 ...

  4. Foxit Reader(福昕PDF阅读器) v4.3.1.218 绿色专业版

    软件名称:Foxit Reader(福昕PDF阅读器) v4.3.1.218 绿色专业版 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 4.40MB 图片 ...

  5. android rss阅读器开发一点小技巧

    这几天一直在学习开发Rss阅读器,遇到一个很坑的问题,InputSource这里总是出错.弄了好久,终于让我找到一个解决方法----看代码: new Thread(){ @Override publi ...

  6. rsyslog日志收集器

    rsyslog详解(思维导图) 1. 日志收集概述 1.1 日志记录 时间 事件 1.2 日志收集器 syslog rsyslog elk stack 1.3 日志文件 文件记录的日志格式 其他日志文 ...

  7. Tomcat日志文件的输出在Linux和Windows下的差异

    前言 最近老大发现Tomcat的日志文件catalina.out里存在着大量的和公司项目相关的log信息,因为一般都是会使用日志框架并另外将log信息输出到另外的文件里的,catalina.out文件 ...

  8. 4:ELK分析tomcat日志

    五.ELK分析tomcat日志 1.配置FIlebeat搜集tomcat日志 2.配置Logstash从filebeat输入tomcat日志 3.查看索引 4.创建索引

  9. 提示29. 怎样避免延迟加载或Load()阅读器问题

    提示29. 怎样避免延迟加载或Load()阅读器问题 如果你有如下这样的代码: 1 var results = from c in ctx.Customers 2 where c.SalesPerso ...

随机推荐

  1. iOS 阶段学习第十天笔记(字符串操作)

    iOS学习(C语言)知识点整理 一.字符串的操作 1)字符串的存储,字符数组,在堆里面申请内存空间. 实例代码: #include <stdlib.h> #include <stri ...

  2. 为什么很多APP要有启动页面

    我们启动APP时,一般都会是一张含有LOGO的图片.这张图片叫做启动页面. 这个启动页面是必须.一定需要的吗?有什么作用?   这是苹果官方对于iOS启动页的设计说明:   为了增强应用程序启动时的用 ...

  3. autofac 使用

    var builder = new ContainerBuilder();var container = builder.Build(); var assemblies = new Directory ...

  4. LeetCode5:Longest Palindromic Substring

    题目: Given a string S, find the longest palindromic substring in S. You may assume that the maximum l ...

  5. $("").click与onclick的区别示例介绍

    Html代码: <script type="text/javascript"> $(function(){ $("#btn4").click(fun ...

  6. java输出MYSQL数据库里面的数据最简单的实例

    import java.sql.*; public class JDBCExample { static final String JDBC_DRIVER = "com.mysql.jdbc ...

  7. 我整理的PHP 7.0主要新特性

    原文:http://php.net/manual/en/migration70.new-features.php 1.标量参数类型声明 现在支持字符串(string).整型(int).浮点数(floa ...

  8. Java基础复习笔记系列 二

    1.Java中Static的相关用法总结?(静态方法:静态变量:静态代码块) public static void main(String args[])执行的关键,在于有static.有了stati ...

  9. 使用Apache的Base64类实现Base64加解密

    包名称:org.apache.commons.codec.binary 类名称:org.apache.commons.codec.binary.Base64 1.Base64加密 public sta ...

  10. jQuery Wookmark Load 瀑布流布局实例演示

    瀑布流布局非常适合大量图片的展示,一改过去裁剪图片尺寸统一的排版,每张图片都能完全展示,并错落有致,让人眼前一亮. 版本: jQuery v1.4.3+ jQuery Wookmark Load v1 ...