思路
第一个想法,是 java 接收 tail 命令返回,然后通过 websocket 推送给前端。也搜到了有人利用此方法实现了。
但是个人觉得日志数据量较大,此方法效率偏低。巧的是,Apache Commons 包里已经帮忙实现了这个方法。
要注意的是,2.4 之前不支持中文。Commons 包较为常见,一开始我没有考虑版本,拿着 2.4 的包用,结果乱码,且没有相关参数指定编码,一度打算舍弃它。
实现
Apache Commons 包中的 Tailer 类实现了这个,一旦了解了这个类,实现起来就简单了。直接贴代码了。
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
import org.apache.commons.io.input.Tailer;
import org.apache.commons.io.input.TailerListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.File;
import java.util.concurrent.atomic.AtomicInteger;
/**
* websocket
*/
@ServerEndpoint("/websocket/log/{sid}")
@Component
public class WebSocketServerLog {
private static Logger LOG = LoggerFactory.getLogger(WebSocketServerLog.class);
private static AtomicInteger onlineCount = new AtomicInteger(0);
private Tailer tailer;
//接收sid
private String sid="";
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("sid") String sid) {
addOnlineCount();
this.sid = sid;
//tail listen
TailerListener listener = new MyTailerListener(session);
tailer = Tailer.create(new File("C:\\Users\\lenovo\\Desktop\\" + sid), listener, 1000, true);
LOG.info("sid " + sid + " on open and online count " + getOnlineCount());
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
subOnlineCount();
tailer.stop();
LOG.info("sid " + sid + " on close and online count " + getOnlineCount());
}
@OnError
public void onError(Throwable error) {
LOG.error("sid {} error: {}", sid, error.getMessage());
}
public static int getOnlineCount() {
return onlineCount.get();
}
public static void addOnlineCount() {
onlineCount.incrementAndGet();
}
public static synchronized void subOnlineCount() {
onlineCount.decrementAndGet();
}
}
|
继承 Tailer
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
31
32
|
import org.apache.commons.io.input.TailerListenerAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.websocket.Session;
import java.io.IOException;
/**
* 继承 TailerListenerAdapter
*/
public class MyTailerListener extends TailerListenerAdapter {
private static Logger LOG = LoggerFactory.getLogger(MyTailerListener.class);
private Session session;
public MyTailerListener(Session session) {
this.session = session;
}
@Override
public void handle(String line) {
try {
LOG.info(line);
if (session.isOpen()){
session.getBasicRemote().sendText(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
|
参考
Java WebSocket + tail命令实现Web实时日志|叉叉哥的BLOG