`
ccxw1983
  • 浏览: 26556 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

文本日志中解析数据库表名,以及表名的自动名称映射

阅读更多
工具的开发背景:
crm系统以ework为基础改造而来,以前简单起见和ework混合了代码和表的,现在需要分析,就需要重新分析,哪些是共用的,哪些是私有的。
通过日志中打印的表名,可以分析出哪些表是crm独有的。
通过pdm文件表的创建记录确定哪些表是新表,新的表少,再除去crm独有的,所以方便人工检查哪些是crm专有的。

另外分析了us系统那边用到的表(那边用到的就肯定不能公用),
cas、权限、用户、组织单位、数据字典的肯定是公用的。
另外考虑以前开发中折中,偷懒,有些方法混合了ework、crm一方使用无需用到的表,目前一时没法剥离,需要确定备忘。

总体思路:
日志(或初始化sql脚本)或pdm中分析出来的表名列表结果分别存到集合包里面,通过里面的CollectionTool.java做集合的运算、打印(打印表名、编码、pdm中所属包方便人工判断)、保存。

工具编写匆忙,可能有少量bug和注释不统一的地方,不懂的请研究代码,恕不做技术支持。

工具一共分3部分,这是 日志(或初始化sql脚本) 解析表名的部分。
package chenxiaowen.tool.logs;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeMap;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.MatchResult;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.PatternMatcherInput;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;

import chenxiaowen.tool.collections.CollectionTool;

/**
 * 解析日志文件,打印表名<br>
 * 表名统一小写
 * 
 * @author 陈小稳 33881270@qq.com
 * 
 */
public class TablesInLogAnalysis {
	public TreeMap<String, Integer> tableTimes = new TreeMap<String, Integer>();
	public String encoding = "UTF-8";

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws Exception {
		TablesInLogAnalysis tool = new TablesInLogAnalysis();
		File baseLogFile = new File("D:\\tomcat\\logs");
		// File baseLogFile = new File("D:\\tomcat\\logs\\test.log");
		tool.analysisAndSaveResultToCollectionFile(baseLogFile, "c.crm.txt");
	}

	/**
	 * 解析日志文件所在目录的日志或单个日志文件,把表名写入集合文件<br>
	 * 如果文件很大导致内存溢出,请配置运行的vm参数,如:-Xms400m -Xmx1024m
	 * 
	 * @param logFile 支持单文件也支持目录
	 * @param recFileName
	 * @throws Exception
	 */
	public void analysisAndSaveResultToCollectionFile(File logFile,
			String recFileName) throws Exception {
		tableTimes.clear();
		analysisTablesInLogDir(logFile);
		StringBuffer b = new StringBuffer();
		for (Iterator iterator = tableTimes.keySet().iterator(); iterator
				.hasNext();) {
			String tbcode = (String) iterator.next();
			b.append(tbcode);
			b.append(",");
		}
		File recFile = new File(CollectionTool.getCollectionDir(), "c.ami.txt");
		if (recFile.exists()) {
			System.out.println("删除已存在日志文件 " + recFile.getAbsolutePath());
			recFile.delete();
		}
		System.out.println("保存日志文件 " + recFile.getAbsolutePath());
		System.out.println("表:");
		System.out.println(b.toString());
		FileUtils.writeStringToFile(recFile, b.toString(), encoding);
	}

	/**
	 * 打印解析的表名
	 * 
	 * @throws IOException
	 */
	public void printTables() throws IOException {
		for (Iterator iterator = tableTimes.keySet().iterator(); iterator
				.hasNext();) {
			String tbcode = (String) iterator.next();
			System.out.println(tbcode + ",");
		}
	}

	/**
	 * 解析目录
	 * 
	 * @param f
	 * @throws IOException
	 */
	public void analysisTablesInLogDir(File f) throws Exception {
		if (f.isDirectory()) {
			File[] fs = f.listFiles();
			for (int i = 0; i < fs.length; i++) {
				analysisTablesInLogDir(fs[i]);
			}
		} else {
			System.out.println("读取解析 " + f.getAbsolutePath());
			String txt = getTextFormFile(f);
			addTableByAnalysis(txt);
		}
	}

	public String getTextFormFile(File f) throws IOException {
		String txt = FileUtils.readFileToString(f, encoding);
		return txt;
	}

	/**
	 * getTextFormFile("test.log")
	 * 
	 * @param filename
	 * @return
	 * @throws IOException
	 */
	public String getTextFormFile(String filename) throws IOException {
		InputStream in = TablesInLogAnalysis.class
				.getResourceAsStream(filename);
		String txt = IOUtils.toString(in, encoding);
		return txt;
	}

	/**
	 * 分析文本内容,添加表到记录
	 * 
	 * @param txt
	 * @throws IOException
	 */
	public void addTableByAnalysis(String txt) throws Exception {
		String regx = "(^|[\\s,])" // 表名前面的间隔符:\s指的空格,可能直接以表名开头,可能是逗号
				+ "((t_|rpt_|dic_)[a-z0-9_]+)"// 表名(pdm叫code)
				+ ""// 后面的不管了
		;
		int[] groupidxs = new int[] { 2 };
		ArrayList<String[]> findstrs = findAllWithGroup(txt, regx, groupidxs);
		for (String[] strs : findstrs) {
			String tbcode = strs[0].toLowerCase();// 统一小写
			tbcode = TableNameProxy.getTranslateTableName(tbcode);// 表名编码映射,如t_a_12
			// 映射t_a_01
			Integer times = tableTimes.get(tbcode);
			if (times == null) {
				tableTimes.put(tbcode, 1);
			} else {
				times++;
				tableTimes.put(tbcode, times);
			}
		}
	}

	/**
	 * 从文件中用正则表达式查找出所有匹配的内容,匹配成功后返回指定组的字符串
	 * 
	 * @param txt
	 * @param regx
	 * @param groupidxs
	 * @return
	 * @throws IOException
	 */
	public static ArrayList<String[]> findAllWithGroup(String txt, String regx,
			int[] groupidxs) throws IOException {
		PatternCompiler compiler = new Perl5Compiler();
		Pattern pattern = null;
		ArrayList<String[]> findstrs = new ArrayList<String[]>();
		try {
			pattern = compiler.compile(regx,
					Perl5Compiler.CASE_INSENSITIVE_MASK);// 大小写不敏感
			PatternMatcher matcher = new Perl5Matcher();
			PatternMatcherInput input = new PatternMatcherInput(txt);
			while (matcher.contains(input, pattern)) {
				MatchResult result = matcher.getMatch();
				String[] rst = new String[groupidxs.length];
				for (int i = 0; i < groupidxs.length; i++) {
					rst[i] = result.group(groupidxs[i]);
				}
				findstrs.add(rst);
			}
		} catch (MalformedPatternException e) {
			e.printStackTrace();
		}

		return findstrs;
	}
}


package chenxiaowen.tool.logs;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;

import org.apache.oro.text.regex.MalformedPatternException;
import org.apache.oro.text.regex.Pattern;
import org.apache.oro.text.regex.PatternCompiler;
import org.apache.oro.text.regex.PatternMatcher;
import org.apache.oro.text.regex.Perl5Compiler;
import org.apache.oro.text.regex.Perl5Matcher;

/**
 * 特殊的表名的映射
 * @author 陈小稳 33881270@qq.com
 *
 */
public class TableNameProxy {

	public static ArrayList<String[]> tableSpecialTranslate = new ArrayList<String[]>();
	// <regx,Pattern>
	public static HashMap<String, Pattern> patternsMap = new HashMap<String, Pattern>();
	// 正规表达式比较批配对象
	public static PatternMatcher matcher = new Perl5Matcher();

	static {
		//TODO 设置这里
		tableSpecialTranslate.add(new String[] { "^T_SET_LOG_\\d\\d$", "t_set_log_01,t_set_log_02" });
		tableSpecialTranslate.add(new String[] { "^T_SET_LOG_MM$", "t_set_log_01,t_set_log_02" });
		
		// 用于定义正规表达式对象模板类型
		PatternCompiler compiler = new Perl5Compiler();
		for (Iterator iterator = tableSpecialTranslate.iterator(); iterator
				.hasNext();) {
			String[] setting = (String[]) iterator.next();
			String regstr = setting[0];
			try {
				// 实例大小写不敏感的正规表达式模板
				Pattern pattern = compiler.compile(regstr,
						Perl5Compiler.CASE_INSENSITIVE_MASK/* 去掉这个参数则敏感 */);
				patternsMap.put(regstr, pattern);
			} catch (MalformedPatternException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * @param args
	 * @throws MalformedPatternException
	 */
	public static void main(String[] args) throws MalformedPatternException {
		String tbstr = "t_1,t_1,t_set_log_02,t_set_log_01,t_set_log_03";
		String[] tbs = tbstr.split(",");
		HashSet<String> distinct = new HashSet<String>();
		
		for (int i = 0; i < tbs.length; i++) {
			String tb = tbs[i];
			tb = getTranslateTableName(tb);
			if(!distinct.contains(tb)){
				distinct.add(tb);
			}
		}

		for (Iterator iterator = distinct.iterator(); iterator.hasNext();) {
			String tb = (String) iterator.next();
			System.out.println(tb);
		}		
	}

	/**
	 * 表名匹配翻译
	 * @param tableName
	 * @return
	 * @throws MalformedPatternException
	 */
	public static String getTranslateTableName(String tableName)
			throws MalformedPatternException {
		for (Iterator iterator = tableSpecialTranslate.iterator(); iterator
				.hasNext();) {
			String[] setting = (String[]) iterator.next();
			String regstr = setting[0];
			Pattern pattern = patternsMap.get(regstr);
			if (matcher.contains(tableName, pattern)) {
				return setting[1].toLowerCase();
			}
		}

		return tableName;
	}

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics