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

页面导航:首页 > 软件编程 > Java编程 > Java用WebSocket + tail命令实现Web实时日志

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

来源: 作者: 时间:2016-01-21 09:39 【

在Linux操作系统中,经常需要查看日志文件的实时输出内容,通常会使用tail -f或者taif命令。查看实时日志可能会需要首先SSH连上Linux主机,步骤很麻烦不说,如果是生产环境的服务器,

在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();
    }
}

由于针对每个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 + "
"); } } catch (IOException e) { e.printStackTrace(); } } }

由于用到tail命令,Java服务端需要部署在Linux系统上。

Web前端





tail log
<script src="//cdn.bootcss.com/jquery/2.1.4/jquery.js"></script>


    
<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>
Tags:

文章评论

最 近 更 新
热 点 排 行
Js与CSS工具
代码转换工具

<