通过java程序抽取日志中的sql语句

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 今天在翻看以前的笔记时,发现自己在很早之前写过一个java程序,能够解析日志中的sql语句。 当时使用的环境是weblogic,日志目录下总是有几十上百个日志文件,有时候排查问题的时候只需要找到对应的DML语句即可。

今天在翻看以前的笔记时,发现自己在很早之前写过一个java程序,能够解析日志中的sql语句。
当时使用的环境是weblogic,日志目录下总是有几十上百个日志文件,有时候排查问题的时候只需要找到对应的DML语句即可。
使用linux命令固然也可以,但是解析的时候还是比较被动,不能够正确地解析出sql语句来。比如日志中出现insert的字样可能只是日志中的一段信息,不是insert语句。
这些通过linux命令来完成还是有一定的难度,记得当时问题比较多,自己也饱受这种困扰。于是写了一个java程序来。
代码如下:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class LogToSqlMain {
 private static String SELECT = "SELECT";
 private static String UPDATE = "UPDATE";
 private static String DELETE = "DELETE";
 private static String INSERT = "INSERT";
 private static String ALL = "ALL";

 public static void main(String[] args) {
  new LogToSqlMain().parse(args);
 }

 public void test(File logFile) {
  // get file
  // initialized io
  // parse log to sql

  // format sql
  // generate sql file
  // invoke jdbc
 }

 public void parse(String[] args) {
  String args0 = null;
  String args1 = null;
  if (args == null) {
   return;
  }
  if (args != null && args.length == 1) {
   args0 = args[0];
  }
  if (args != null && args.length == 2) {
   args0 = args[0];
   args1 = args[1];
   if (!args1.equalsIgnoreCase(ALL) && !args1.equalsIgnoreCase(SELECT)
     && !args1.equalsIgnoreCase(UPDATE) && !args1.equalsIgnoreCase(DELETE)
     && !args1.equalsIgnoreCase(INSERT)) {
    return;
   }
  }

  BufferedReader buffer_reader = null;
  String sql_type = null;
  try {
   File file = new File(args0);
   File[] filesOfDirs = file.listFiles();
   if (!file.isDirectory() || filesOfDirs.length == 0) {
    System.out.println("invalid path or io error");
    return;
   }
   String temp_read = null;
   String strTemp = null;
   String strTimeStamp = null;
   Long log_Line_Num = null;
   for (int i = 0; i     if (getSqlMode(args1, filesOfDirs[i].getName())) {
     File tmp_File = filesOfDirs[i].getAbsoluteFile();
     sql_type = getSQLType(tmp_File);
     buffer_reader = new BufferedReader(new FileReader(tmp_File));
     temp_read = buffer_reader.readLine();
     while (temp_read != null) {
      char sep_str = ':';
      // validate every line should be SQL
      if (validateFileLine(temp_read, sql_type)) {
       log_Line_Num = Long.parseLong(temp_read.substring(
         0, temp_read.indexOf(sep_str)));
       strTemp = temp_read.substring(temp_read
         .indexOf(':') + 1);
       strTimeStamp = strTemp.substring(
         strTemp.indexOf('[') + 1,
         strTemp.indexOf(']'));
       strTemp = strTemp
         .substring(strTemp.indexOf(']') + 1);
       String temp_Sql = strTemp.substring(strTemp
         .indexOf(sql_type + " "));
       System.out.println(sql_type + log_Line_Num + ","
         + strTimeStamp + "," + temp_Sql);
      }
      temp_read = buffer_reader.readLine();
     }
     buffer_reader.close();
    }
   }
  } catch (NumberFormatException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } finally {
   if (buffer_reader != null) {
    try {
     buffer_reader.close();
    } catch (IOException e) {
     e.printStackTrace();
    }
   }
  }

 }

 private boolean validateFileLine(String str_Line, String sql_type) {
  if (sql_type.equals(INSERT)) {
   if (str_Line.toUpperCase().contains("INTO")
     && str_Line.toUpperCase().contains("VALUES"))
    return true;
  } else if (sql_type.equals(SELECT)) {
   if (str_Line.toUpperCase().contains("FROM")
     && str_Line.toUpperCase().contains("WHERE")) {
    return true;
   }
  } else if (sql_type.equals(UPDATE)) {
   if (str_Line.toUpperCase().contains("SET")
     && str_Line.toUpperCase().contains("WHERE")) {
    return true;
   }
  } else if (sql_type.equals(DELETE)) {
   if (str_Line.toUpperCase().contains("WHERE")) {
    return true;
   }
  }
  return false;
 }

 private String getSQLType(File file) {
  if (file.getName().toUpperCase().contains(SELECT)) {
   return SELECT;
  } else if (file.getName().toUpperCase().contains(UPDATE)) {
   return UPDATE;
  } else if (file.getName().toUpperCase().contains(DELETE)) {
   return DELETE;
  } else if (file.getName().toUpperCase().contains(INSERT)) {
   return INSERT;
  }
  return null;
 }

 public boolean getSqlMode(String args, String fileName) {
  if (args == null || ALL.equalsIgnoreCase(args))
   return (fileName.startsWith(INSERT) || fileName.startsWith(DELETE)
     || fileName.startsWith(UPDATE) || fileName
      .startsWith(SELECT));
  if ((SELECT).equalsIgnoreCase(args)) {
   return (fileName.startsWith(SELECT));
  } else if ((UPDATE).equalsIgnoreCase(args)) {
   return (fileName.startsWith(UPDATE));
  } else if ((INSERT).equalsIgnoreCase(args)) {
   return (fileName.startsWith(INSERT));
  } else if ((DELETE).equalsIgnoreCase(args)) {
   return (fileName.startsWith(DELETE));
  }
  return false;
 }
}

如果需要得到a.log中的sql语句,
就可以这样调用java程序 java LogToSqlMain a.log INSET
如果想得到所有的sql语句 java LogToSqlMain a.log ALL

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
目录
相关文章
|
10天前
|
SQL 传感器 人工智能
生成更智能,调试更轻松,SLS SQL Copilot 焕新登场!
本文是阿里云日志服务(SLS)首次对外系统性地揭秘 SLS SQL Copilot 背后的产品理念、架构设计与核心技术积淀。我们将带你深入了解,这一智能分析助手如何从用户真实需求出发,融合前沿 AI 能力与 SLS 十余年日志分析最佳实践,打造出面向未来的智能化日志分析体验。
|
10天前
|
SQL 传感器 人工智能
生成更智能,调试更轻松,SLS SQL Copilot 焕新登场!
阿里云日志服务(SLS)推出智能分析助手 SLS SQL Copilot,融合 AI 技术与日志分析最佳实践,将自然语言转换为 SQL 查询,降低使用门槛,提升查询效率。其具备原生集成、智能语义理解与高效执行能力,助力用户快速洞察日志数据价值,实现智能化日志分析新体验。
|
6月前
|
SQL druid Oracle
【YashanDB知识库】yasdb jdbc驱动集成druid连接池,业务(java)日志中有token IDENTIFIER start异常
客户Java日志中出现异常,影响Druid的merge SQL功能(将SQL字面量替换为绑定变量以统计性能),但不影响正常业务流程。原因是Druid在merge SQL时传入null作为dbType,导致无法解析递归查询中的`start`关键字。
|
7月前
|
XML JSON Java
Java中Log级别和解析
日志级别定义了日志信息的重要程度,从低到高依次为:TRACE(详细调试)、DEBUG(开发调试)、INFO(一般信息)、WARN(潜在问题)、ERROR(错误信息)和FATAL(严重错误)。开发人员可根据需要设置不同的日志级别,以控制日志输出量,避免影响性能或干扰问题排查。日志框架如Log4j 2由Logger、Appender和Layout组成,通过配置文件指定日志级别、输出目标和格式。
|
9月前
|
Java Maven
java项目中jar启动执行日志报错:no main manifest attribute, in /www/wwwroot/snow-server/z-server.jar-jar打包的大小明显小于正常大小如何解决
在Java项目中,启动jar包时遇到“no main manifest attribute”错误,且打包大小明显偏小。常见原因包括:1) Maven配置中跳过主程序打包;2) 缺少Manifest文件或Main-Class属性。解决方案如下:
2297 8
java项目中jar启动执行日志报错:no main manifest attribute, in /www/wwwroot/snow-server/z-server.jar-jar打包的大小明显小于正常大小如何解决
|
9月前
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
11月前
|
人工智能 Oracle Java
解决 Java 打印日志吞异常堆栈的问题
前几天有同学找我查一个空指针问题,Java 打印日志时,异常堆栈信息被吞了,导致定位不到出问题的地方。
216 2
|
11月前
|
SQL 数据库
为什么 SQL 日志文件很大,我应该如何处理?
为什么 SQL 日志文件很大,我应该如何处理?
|
10天前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案