Java用WebSocket + tail命令實現Web實時日志
在Linux操作系統中,經常需要查看日志文件的實時輸出內容,通常會使用tail -f或者taif命令。查看實時日志可能會需要首先SSH連上Linux主機,步驟很麻煩不說,如果是生產環境的服務器,可能還會控制各種權限。基于Web的實時日志可以解決這個問題。
由于傳統的HTTP協議是請求/響應模式,而實時日志需要不定時的持續的輸出,由服務器主動推送給客戶端瀏覽器。所以這里使用的是HTML5的WebSocket協議。
按照慣例,先上圖:

Java后臺
JSR 356是Java實現WebSocket的一套規范,所以需要一個支持JSR 356的服務器,例如Tomcat、Jetty的最新版本。
JSR 356提供了注解@ServerEndpoint,并需要指定一個路徑,用于處理客戶端WebSocket請求。
import java.io.IOException; import java.io.InputStream; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; @ServerEndpoint("/log") public class LogWebSocketHandle { private Process process; private InputStream inputStream; /**
- 新的WebSocket請求開啟 */ @OnOpen public void onOpen(Session session) { try { // 執行tail -f命令 process = Runtime.getRuntime().exec("tail -f /var/log/syslog"); inputStream = process.getInputStream(); // 一定要啟動新的線程,防止InputStream阻塞處理WebSocket的線程 TailLogThread thread = new TailLogThread(inputStream, session); thread.start(); } catch (IOException e) { e.printStackTrace(); } } /**
- WebSocket請求關閉
*/
@OnClose
public void onClose() {
try {
if(inputStream != null)
inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
if(process != null)
process.destroy();
}
@OnError
public void onError(Throwable thr) {
thr.printStackTrace();
}
}</pre>
由于針對每個WebSocket連接都會創建一個新的LogWebSocketHandle實例,所以可以不用像Servlet一樣考慮線程安全問題。由于tail -f命令的輸入流會阻塞當前線程,所以一定要創建一個新的線程來讀取tail -f命令的返回結果。import 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(); } } }
由于用到tail命令,Java服務端需要部署在Linux系統上。
Web前端
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>tail log</title> <script src="http://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>
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!