In the Linux operating system, it is often necessary to view the real-time output of log files, usually using tail -f
or tailf
commanding. Viewing real-time logs may require SSH to connect to a Linux host first, the steps are cumbersome, and if you are a production environment server, you may also be able to control various permissions. Real-time web-based logs can solve this problem.
Because the traditional HTTP protocol is the request/response mode, and the real-time log needs constant output, the server is actively pushed to the client browser. So here's the HTML5 websocket protocol.
By convention, first:
Java background
JSR 356 is a set of specifications for Java implementation WebSocket, so you need a server that supports JSR 356, such as Tomcat, the latest version of jetty.
JSR 356 provides annotations and @ServerEndpoint
needs to specify a path to handle client WebSocket requests.
ImportJava.io.IOException;ImportJava.io.InputStream;ImportJavax.websocket.OnClose;ImportJavax.websocket.OnError;ImportJavax.websocket.OnOpen;ImportJavax.websocket.Session;ImportJavax.websocket.server.ServerEndpoint;@ServerEndpoint("/log") Public class logwebsockethandle { PrivateProcess process;PrivateInputStream InputStream;/** * New WebSocket Request Open */ @OnOpen Public void OnOpen(Session session) {Try{//Execute tail-f commandProcess = Runtime.getruntime (). EXEC ("Tail-f/var/log/syslog"); InputStream = Process.getinputstream ();//Be sure to start a new thread to prevent InputStream from blocking processing WebSocket threadsTaillogthread thread =NewTaillogthread (InputStream, session); Thread.Start (); }Catch(IOException e) {E.printstacktrace (); } }/** * WebSocket Request Close */ @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 (); }}
Because a new Logwebsockethandle instance is created for each websocket connection, there is no need to consider thread safety issues like servlets. Because tail -f
the input stream of the command blocks the current thread, be sure to create a new thread to read tail -f
the command's return result:
ImportJava.io.BufferedReader;ImportJava.io.IOException;ImportJava.io.InputStream;ImportJava.io.InputStreamReader;ImportJavax.websocket.Session; Public class taillogthread extends Thread { PrivateBufferedReader reader;PrivateSession session; Public Taillogthread(InputStream in, session session) { This. Reader =NewBufferedReader (NewInputStreamReader (in)); This. session = Session; }@Override Public void Run() {String line;Try{ while(line = Reader.readline ())! =NULL) {//Send real-time logs to the client via WebSocket and add an HTML wrap to each lineSession.getbasicremote (). SendText (line +"<br>"); } }Catch(IOException e) {E.printstacktrace (); } }}
Web Front End
The web front end needs to connect to the server via WebSocket, receiving the latest log content in real time and displaying it on the page.
<! 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 () { //specify WebSocket path var websocket = new websocket ( ' Ws://localhost:8080/log ' ); Websocket.onmessage = function { //receive real-time logs from the server and add them to the HTML page $ ( "#lo G-container Div "). Append (Event.data); //scroll bar to the lowest part $ ( "#log-container" ). ScrollTop ($ ( "#log-container div" ). Height ()-$ ( "#log-container" ). Height ()); }; });</script></body></html>
Once the encoding is complete, you can deploy it. Because of the tail
command, the project needs to be deployed on a Linux system.
Finally, the students who need the code can leave their email in the comments.
Demo on Github:https://github.com/wucao/websocket-tail-demo
Java implements web real-time log with WebSocket + tail command