绝大多数情况下项目出问题了,第一时间就会打开服务器,cd… tail … 一套连招查看到底除了什么错误日志,虽然这种方法直达问题本质,但好像有些不太优雅,毕竟打开Xshell等也需要耗费时间,看时间只能输入命令和上下查看,针对这个就设计了一个接口,解决这个问题。
解决这个问题主要核心问题只有2个:
- 一个是根据选择的时间生成脚本,获取对应时间区间的日志。
- 以文本或其他形式导出日志。
生成脚本,针对日志Linux下有sed
命令筛选:
sed '/2020-09-01 00:16:23,390/,/2020-09-01 01:16:23,390/p' error.log > error.txt
意思是选择区间内的时间,将当前目录下error.log
里的对应日志截取,导出到error.txt
当中。
筛选日志
设计了工具类供使用
package cn.seczone.iast.server.report.util;
import java.io.*;
/**
* @author WangWei
* @date 2020/9/1
*/
public class ShellUtil {
//创建shell
public static void createShell(String path, String... strs) throws Exception {
if (strs == null) {
return;
}
File sh = new File(path);
if (sh.exists()) {
sh.delete();
}
sh.createNewFile();
sh.setExecutable(true);
FileWriter fw = new FileWriter(sh);
BufferedWriter bf = new BufferedWriter(fw);
for (int i = 0; i < strs.length; i++) {
bf.write(strs[i]);
if (i < strs.length - 1) {
bf.newLine();
}
}
bf.flush();
bf.close();
}
//执行shell
public static String runShell(String shpath) throws Exception {
if (shpath == null || shpath.equals("")) {
return "shpath is empty";
}
Process ps = Runtime.getRuntime().exec(shpath);
ps.waitFor();
BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
String result = sb.toString();
return result;
}
}
使用方式:
public String CreateErrorLog(String startTime, String endTime) throws IOException {
String catalinaBase = System.getProperty("catalina.base");
Path path = Paths.get(catalinaBase + "/logs/iast/log/error.txt");
File file = new File(String.valueOf(path));
if(file.exists()){
FileUtils.forceDelete(file);
}
file.createNewFile();
String[] strs = {"sed '/"+startTime+"/,/"+endTime+ "/p' "+catalinaBase + "/logs/error.log > "+catalinaBase + "/logs/error.txt"};
String shellDir = catalinaBase + "/logs/reportlog.sh";
try {
ShellUtil.createShell(shellDir, strs);
ShellUtil.runShell(shellDir);
} catch (Exception e) {
e.printStackTrace();
}
return String.valueOf(path);
}
这里也就是创建生成对应的错误日志,接下来的任务就比较简单了,读取下载错误日志即可。
下载日志
name
是生成的日志文本名,指定了response
的格式方便前端作处理。
public void DownLoadLog(String path, HttpServletResponse response) {
try {
FileInputStream is = new FileInputStream(Paths.get(path).toFile());
response.setContentType("application/txt");
String name = "error_log.txt";
response.setHeader("Content-Disposition", "attachment; filename=\"" + name + "\"");
OutputStream os = response.getOutputStream();
os.write(IOUtils.toByteArray(is));
is.close();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}