服务器日志分析工具(识别,提取,合并,统计异常信息)

2022-07-27,,,,

需求: 今天需要查看昨天的日志,并关注其中的异常,以便处理其中的某些问题。
人工阅读花费的时间会很长,一般一天的日志文件有十几个,不可能一个一个去看,并且大量的日志信息都是info信息,不需要关注。所以实现了一个小工具自动读取所有的日志文件,提取其中的异常信息,对于业务异常相同的合并在一起,这样只需要查看生成的异常信息文件即可,大大节约了时间。以下是代码实现:

import com.google.common.collect.Maps;
import org.springframework.util.CollectionUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author visy.wang
 * @desc 日志读取
 * @date 2020/11/25 10:39
 */
public class LogReader {

    //提取异常信息的关键字
	private static final String[] KEY_WORDS = {"xception", "at "};
	//保存业务异常的统计次数
	private static Map<String, Integer> errMap = Maps.newHashMap();

	/**
	 * 读取异常信息
	 * @param folder 文件夹路径
	 * @param ignores 忽略的关键字(含有其中发关键字则跳过)
	 */
	private static void readException(String folder, String... ignores) throws Exception{

		File dir = new File(folder);
		File[] fileArr = dir.listFiles();
		if(fileArr==null || fileArr.length==0){
			System.out.println("文件夹为空");
			return;
		}

		//过滤&排序
		List<File> files = Arrays.stream(fileArr).filter(f -> {
			String name = f.getName();
			//只处理debug.*.log文件,可修改
			return !f.isDirectory() && name.startsWith("debug") && name.endsWith(".log");
		}).sorted(Comparator.comparing(f->{
		    //文件排序, 无需排序可删除这部分代码,或者修改别的排序规则
		    //名称示例:debug.2020-11-24.1.log,提取数字1用于排序
			String name = f.getName();
			int secondIndex = name.indexOf(".",name.indexOf(".")+1);
			String index = name.substring(secondIndex+1, name.lastIndexOf("."));
			return Integer.parseInt(index);
		})).collect(Collectors.toList());

		if(CollectionUtils.isEmpty(files)){
			System.out.println("未找到日志文件");
			return;
		}

		//创建输出文件
		String yesterday = LocalDate.now().minusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
		String outputFileName = "exceptions."+ yesterday +".log";
		File outputFile = new File(folder+"\\"+outputFileName);
		if(!outputFile.exists()){
			if(!outputFile.createNewFile()){
				System.out.println(outputFileName+"创建失败!!!");
			}
		}
		FileWriter writer = new FileWriter(outputFile);

		for(File file: files){
			String fileName = file.getName();
			System.out.println("正在读取:"+fileName+" ...");

			writer.write("LOG_FILE_NAME-------------------->"+ fileName+"\n");

			String tempStr;
			BufferedReader reader = new BufferedReader(new FileReader(file));
			boolean flag = false;
			while ((tempStr = reader.readLine()) != null) {
				if(isIncludes(tempStr, KEY_WORDS) && !isIncludes(tempStr, ignores)){
					//控制业务异常只打印一遍(合并)
					//ServiceException是我项目的自定义的业务异常名,可根据自己的名称修改
					if(tempStr.contains("ServiceException:")){
						String errMsg = tempStr.substring(tempStr.indexOf(":")+1).trim();
						Integer count;
						if((count=errMap.get(errMsg))==null){
							errMap.put(errMsg, 1);
							flag = false;
						}else{
							errMap.put(errMsg, count+1);
							flag = true;
							continue;
						}
					}else{
						if(tempStr.contains("at ")){
							if(flag){
								continue;
							}
						}else{
							flag = false;
						}
					}
					writer.write(tempStr+"\n");
				}
			}
			reader.close();
		}

		writer.write("\n\n--------------业务异常统计信息-------------------\n");
		for(String k : errMap.keySet()){
			writer.write(k+": "+ errMap.get(k)+"次\n");
		}

		writer.close();

		System.out.println("异常文件生成完毕!!!");

	}

	//是否查找到关键字
	private static boolean isIncludes(String tempStr, String[] keyWords){
		for(String keyWord: keyWords){
			if(tempStr.contains(keyWord)){
				return true;
			}
		}
		return false;
	}

	public static void main(String[] args) throws Exception{
		//把要分析的日志文件全部放到桌面logs文件夹下,文件须是解压后的.log文件
		//分析完毕后会在logs文件夹下生成exceptions.yyyy-MM-dd.log文件,查看即可
		//所有业务异常只会打印一遍异常信息,在文件末尾有各异常发生的次数
		readException("C:\\Users\\admin\\Desktop\\logs", "aaa", "bbb");
	}
}

本文地址:https://blog.csdn.net/xhom_w/article/details/110234225

《服务器日志分析工具(识别,提取,合并,统计异常信息).doc》

下载本文的Word格式文档,以方便收藏与打印。