使用接口读取服务端产生的日志,从末尾往上翻页读
想看服务端日志,运维比较忙,自己想办法;
!(生产环境不用用!)
!(控制访问频率,基于io)
两种方式
1、使用IO读取文件(从末尾开启往上,支持向上分页)
/**
* 从末尾向上读取日志文件
* @param logFilePath 文件地址
* @param readLines 读取行数- 20~100
* @param page 第几页 - 1~5
* @return list-每行日志
* @throws FileNotFoundException
*/
private List<String> readLogAccess(String logFilePath, int readLines, int page) throws FileNotFoundException {
RandomAccessFile file = new RandomAccessFile(logFilePath, "r");
List<String> logList = new ArrayList<>();
page = page > 5 ? 5 : (Math.max(page, 1));
readLines = readLines > 100 ? 100 : (Math.max(readLines, 20));
// page 向上翻页
int statLine = readLines * (page-1);
try {
long readIndex = file.length() - 1;
file.seek(readIndex);
int lineCount = 0;
while (readLines >= 0) {
int c = file.read();
if (c == '\n' || c == '\r') {
lineCount++;
if (lineCount > statLine) {
String line = file.readLine();
if (line != null) {
readLines--;
logList.add(new String(line.getBytes("ISO-8859-1"), "UTF-8"));
}
}
readIndex--;
}
readIndex--;
file.seek(readIndex);
}
Collections.reverse(logList);
return logList;
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
file.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
2、想用linux的tail命令或者less命令直接读取
优点
:
系统级响应,减少程序资源压力
缺点
:
需要有脚本权限,不安全
实现方式
写一个sh脚本执行linux命令,用java把命令获取的信息返回给页面;
首先tail和less的区别介绍下
tail
:tail 是一个简单的命令行工具,通常被用来 实时查看 文件的内容。它的主要功能是在文件的末尾显示指定数量的行。tail 命令可以通过 -n 选项来指定要显示的行数;例如tail -n 10 file.txt # 将显示文件 file.txt 的末尾 10 行内容。
less
:less 是一个功能更加强大的文件查看器,它允许用户在文件中进行搜索和导航。与 tail 不同,less 显示的不是文件的末尾,而是整个文件的内容。用户可以使用 less 命令来查看大文件的内容,而且 less 可以像编辑器一样滚动、搜索、翻页和回到文件的顶部等。例如:less file.txt # 这将打开文件预览输入以下命令: b:向上翻页 f:向下翻页 / 要搜索的内容:从上向下搜索,n搜索下一个;Shift-n 搜索上一个 ? 要搜索的内容:从下向上搜索,n搜索下一个;Shift-n 搜索上一个
了解了上述指令后,写脚本执行:
#!/bin/bash
# 获取要读取的文件路径
filePath="../logs/api.log"
# 获取要读取的行数范围
startLine=$1
endLine=$((startLine + $2 - 1))
# 使用 tail 命令读取指定范围的行,并输出到控制台
# tail -n +$startLine "$filePath" | head -n $2
tail -n $startLine "$filePath"
最后使用java执行sh脚本
String scriptPath = "../readlogs.sh";
// 构造命令行参数
String[] command = {"/bin/sh", "-c", scriptPath + " " + line};
// 执行命令并读取输出
ProcessBuilder pb = new ProcessBuilder(command);
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder sb = new StringBuilder();
String txt;
while ((txt = reader.readLine()) != null) {
sb.append(txt).append("\n");
}
Map<String, String> result = new HashMap<>();
result.put("errorInfo", StrUtil.isBlank(sb.toString()) ? "No Error message" : sb.toString());