• Java用WebSocket + tail命令实现Web实时日志


    原文:http://blog.csdn.net/xiao__gui/article/details/50041673

    在Linux操作系统中,经常需要查看日志文件的实时输出内容,通常会使用tail -f或者tailf命令。查看实时日志可能会需要首先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();
        }
    }

    由于针对每个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();
            }
        }
    }

    Web前端

    Web前端需要通过WebSocket连接到服务端,实时接收最新的日志内容并展示到页面上。

    <!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/wucao/websocket-tail-demo

  • 相关阅读:
    消除左递归
    DFA最小化
    非确定的自动机NFA确定化为DFA
    正规式到正规文法与自动机
    正规文法与正规式
    词法分析程序的设计与实现
    4.文法和语言总结与梳理
    语法树,短语,直接短语,句柄
    语法
    第一次作业 编译原理概述
  • 原文地址:https://www.cnblogs.com/shihaiming/p/6201678.html
Copyright © 2020-2023  润新知