透過java程式抽取日誌中的sql語句

dbhelper發表於2015-01-17

今天在翻看以前的筆記時,發現自己在很早之前寫過一個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 < filesOfDirs.length; 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

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8494287/viewspace-1405506/,如需轉載,請註明出處,否則將追究法律責任。

相關文章