最近在写往公司产品里添加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. C#导出Excel那些事

    Excel导出 Excel导出的意义 因为在项目中有些报表数据客户需要导出功能,那么导出为Excel就十分有必要了,可是有些客户的机器上并没有安装Excel或者安装的版本参差不一.那么我们在这样的情况 ...

  2. 高德携手阿里云发布“LBS云”,账户打通只是第一步

    位置.游戏.视频,是公认的基于云计算的三大移动端应用方向.而今,LBS云有了更多进展,在高价值应用与云平台之间实现了资源打通和融合,高德迈出了实质性的一步. 高德地图副总裁郄建军(左)与阿里云业务总经 ...

  3. 项目中初试PHP单元测试

    只能叫初试,前面虽然做了一些PHPUnit与团队所用框架的整合,但在整个团队还没有人可以主动推动这个事情,而作为Leader最重要的一种能力应该是"让正确的事情发生",所以今天开始 ...

  4. Verilog学习笔记简单功能实现(八)...............异步FIFO

    基本原理:       1.读写指针的工作原理 写指针:总是指向下一个将要被写入的单元,复位时,指向第1个单元(编号为0). 读指针:总是指向当前要被读出的数据,复位时,指向第1个单元(编号为0). ...

  5. 通俗易懂地讲解TCP建立连接的三次握手和释放连接的四次挥手

    TCP建立连接时,为什么要进行三次挥手? 每一次TCP连接都需要三个阶段:连接建立.数据传送和连接释放.三次握手就发生在连接建立阶段. 在谢希仁著<计算机网络>第四版中讲三次握手的目的是为 ...

  6. 操作系统与c语言

      以下是根据看书后的理解做的总结:   最早,unix是使用汇编编写,但是非常简单.后来觉得汇编,换种机器又得重新用另外一种机器汇编重写,太麻烦.于是想设计一种通用的语言,到各种机器上都能运行 当时 ...

  7. 利用FileStream实现多媒体文件复制

        利用FileStream实现多媒体文件复制的主要思路在于利用两个FileStream对象,一个读取字节,另一个对象写入字节既可.     涉及知识点: 1.通常我们操作的File类,FileS ...

  8. Java的主要数据类型(Primitive)

    有一系列类需特别对待:可将它们想象成"基本"."主要"或者"主"(Primitive)类型,进行程序设计时要频繁用到它们.之所以要特别对待, ...

  9. Web 开发人员必备的12款 Chrome 扩展程序

    之前已经分享过一些帮助 Web 开发人员和设计师的 Chrome 扩展,这次我们继续展示一组很有用的 Chrome 应用程序.这些免费的 Chrome 应用程序可以简化您的工作流程,为了加快您的工作流 ...

  10. 推荐几个jQuery插件

    jQuery仿京东无限级菜单HoverTree http://www.cnblogs.com/jihua/p/hvtree.html 多级弹出菜单jQuery插件ZoneMenu http://www ...