Java WebSocket + tail命令实现Web实时日志
在Linux操作系统中,经常需要查看日志文件的实时输出内容,通常会使用tail -f或者tailf命令。查看实时日志可能会需要首先SSH连上Linux主机,步骤很麻烦不说,如果是生产环境的服务器,可能还会控制各种权限。此时可以考虑基于Web显示实时日志。
由于传统的HTTP协议是请求/响应模式,而实时日志需要不定时的持续的输出,有新的日志内容时需要由服务器主动推送给客户端浏览器。所以这里使用的是HTML5的WebSocket协议。
按照惯例,先下图:
Java后台
JSR 356是Java实现WebSocket的一套规范,所以首先需要准备一个支持JSR 356的服务器,例如Tomcat、Jetty的最新版本。
JSR 356提供了注解
@ServerEndpoint
,并需要指定一个路径,用于处理客户端WebSocket请求。1 | import java.io.IOException; |
由于针对每个WebSocket连接都会创建一个新的LogWebSocketHandle实例,所以可以不用像Servlet一样考虑线程安全问题。由于tail -f命令的输入流会阻塞当前线程,所以一定要创建一个新的线程来读取tail -f命令的返回结果:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import javax.websocket.Session;
public class TailLogThread extends Thread {
private BufferedReader reader;
private Session session;
public TailLogThread(InputStream in, Session session) {
this.reader = new BufferedReader(new InputStreamReader(in));
this.session = session;
}
@Override
public void run() {
String line;
try {
while((line = reader.readLine()) != null) {
// 将实时日志通过WebSocket发送给客户端,给每一行添加一个HTML换行
session.getBasicRemote().sendText(line + "<br>");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Web前端
Web前端需要通过WebSocket连接到服务端,实时接收最新的日志内容并展示到页面上。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>tail log</title>
<script src="//cdn.bootcss.com/jquery/2.1.4/jquery.js"></script>
</head>
<body>
<div id="log-container" style="height: 450px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;">
<div>
</div>
</div>
</body>
<script>
$(document).ready(function() {
// 指定websocket路径
var websocket = new WebSocket('ws://localhost:8080/log');
websocket.onmessage = function(event) {
// 接收服务端的实时日志并添加到HTML页面中
$("#log-container div").append(event.data);
// 滚动条滚动到最低部
$("#log-container").scrollTop($("#log-container div").height() - $("#log-container").height());
};
});
</script>
</body>
</html>
完成编码后,就可以部署了。由于用到tail命令,该项目需要部署在Linux系统上。
Demo on GitHub: https://github.com/BlackCoffee2016/websockettail