java将tomcat的日志显示在web端
后台代码
public class SocketManager{
    // 用来记录当前在线链接数
    private static volatile int onlineCount = 0;
    // 标记文件已读行数
    private static volatile long lines = 0L;
    // 判断是不是第一次加载
    private static volatile boolean isFirstRunning = true;
    // concurrent包的线程安全Set,用来存放每一个客户端对应的MyWebSocket对象
    // 若要实现服务端与单一客户端通讯的话,能够使用Map来存放,其中Key能够为用户标识
    public static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
    // 开启监听
    public static synchronized void startListening(String rootDir) {
        File file = new File(rootDir+java.io.File.separator+"catalina.out");
        if(file.exists()){
            int lineNumber = getLineNumber(file);
            System.out.println("Total number of lines : " + lineNumber);
            List<String> readLines = readLastLine(file,3000);
            for(int i=readLines.size()-1;i>=0;i--){
                sendMsgToAll(readLines.get(i));
            }
            if(lineNumber>=3000){
                lines = lineNumber-3000;
            }
        }
        if (!isFirstRunning) {
            System.err.println("监听服务已经启动!");
            return;
        }
        // 监控目录
        // 轮询间隔 1 秒
        long interval = TimeUnit.SECONDS.toMillis(1);
        // 建立一个文件观察器用于处理文件的格式
        FileAlterationObserver observer = new FileAlterationObserver(
                rootDir,
                FileFilterUtils.and(
                        FileFilterUtils.fileFileFilter(),
                        FileFilterUtils.suffixFileFilter(".out"),
                        FileFilterUtils.prefixFileFilter("catalina")),  //过滤文件格式
                null);
        observer.addListener(new LogListener());
        // 建立文件变化监听器
        FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
        // 开始监控
        try {
            monitor.start();
            isFirstRunning = false;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
    public static synchronized void addOnlineCount() {
        onlineCount++;
    }
    public static synchronized void subOnlineCount() {
        onlineCount--;
    }
    private static class LogListener extends FileAlterationListenerAdaptor {
        @Override
        public void onFileChange(File file) {
            BufferedReader br;
            try {
                InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
                br = new BufferedReader(isr);
                if (br.ready()) {
                    lines += br.lines()
                            .skip(lines <= 0L ? 0L : lines)
                            .peek(LogListener::sendMsgToAll)
                            .count();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        private static void sendMsgToAll(String msg) {
            webSocketSet.forEach(item -> {
                try {
                    item.getSession().getBasicRemote().sendText(msg);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            });
        }
        
    }
    //发送消息
    private static void sendMsgToAll(String msg) {
        webSocketSet.forEach(item -> {
            try {
                item.getSession().getBasicRemote().sendText(msg);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        });
    }
    //从最后一行开始读取日志
    private static List<String> readLastLine(File file, int numLastLineToRead) { 
        List<String> result = new ArrayList<String>();
        try (ReversedLinesFileReader reader = new ReversedLinesFileReader(file)) {
            String line = "";
            while ((line = reader.readLine()) != null && result.size() < numLastLineToRead) {
                result.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
    //获取日志的行数
    private static int getLineNumber(File file) {
        int lineNumber = 0;
        try {
            long fileLength = file.length();
            LineNumberReader lineNumberReader = new LineNumberReader(new FileReader(file));
            lineNumberReader.skip(fileLength);
            lineNumber = lineNumberReader.getLineNumber();
            lineNumberReader.close();
        }catch (IOException ex) {
            ex.printStackTrace();
        }
        return lineNumber;
    }
@ServerEndpoint("/webSocket")
public class MyWebSocket{
    // 与某个客户端的链接会话,须要经过它来给客户端发送数据
    private Session session;
    public MyWebSocket() {
        String classesPath = this.getClass().getResource("/").getPath();
        String logRootPath = new java.io.File(classesPath)
                .getParentFile().getParentFile().getParentFile().getParentFile()
                .getPath() + java.io.File.separator + "logs";
        System.out.println(logRootPath);
        SocketManager.startListening(logRootPath);
    }
    public Session getSession() {
        return session;
    }
    /** * 链接创建成功调用的方法 * @param session 可选的参数。session为与某个客户端的链接会话,须要经过它来给客户端发送数据 */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        SocketManager.webSocketSet.add(this);     // 加入set中
        SocketManager.addOnlineCount();           // 在线数加1
        System.out.println("有新链接加入!当前在线人数为" + SocketManager.getOnlineCount());
    }
    /** * 链接关闭调用的方法 */
    @OnClose
    public void onClose() {
        SocketManager.webSocketSet.remove(this);  // 从set中删除
        SocketManager.subOnlineCount();           // 在线数减1
        System.out.println("有一链接关闭!当前在线人数为" + SocketManager.getOnlineCount());
    }
    /** * 收到客户端消息后调用的方法 * @param message 客户端发送过来的消息 * @param session 可选的参数 */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("来自客户端" + session.getId() + "的消息:" + message);
    }
    /** * 发生错误时调用 */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("onError");
        System.out.println(session.getId() + "发生错误");
        error.printStackTrace();
    }
前台代码:
<!DOCTYPE html>
<html>
<head>
    <title>catalina.out</title>
    <meta charset="UTF-8">
    <style type="text/css"> html, body { background: #000; margin: 0; padding: 0; } #message { color: #0F0; font-size: 12px; padding: 3px; } </style>
</head>
<body>
    <div id="message"></div>
</body>
<script type="text/javascript">
    function getWebsocketUrlPrefix(){
        var domainPort = window.location.host;
        var url = window.location.pathname;
        var webApp = url.split('/')[1];
        var urlPrefix = "";
        if (webApp == "pages") {
            urlPrefix = domainPort;
        } else {
            urlPrefix = domainPort + "/" + webApp
        }
        return urlPrefix;
    }
    var websocket = null; 
    // 判断当前浏览器是否支持WebSocket 
    if ('WebSocket' in window) {
        var webSocketUrl = getWebsocketUrlPrefix();
        websocket =  new WebSocket('ws://'+webSocketUrl+'/webSocket'); 
    } else {
        alert('当前浏览器不支持WebSocket') 
    } 
    // 链接发生错误的回调方法 
    websocket.onerror = function () {
        setMessageInnerHTML("WebSocket链接发生错误"); 
    }; 
    // 链接成功创建的回调方法 
    websocket.onopen = function () {
        setMessageInnerHTML("WebSocket链接成功"); 
    } 
    // 接收到消息的回调方法 
    websocket.onmessage = function (event) {
        setMessageInnerHTML(event.data); 
    } 
    // 链接关闭的回调方法
    websocket.onclose = function () { 
        setMessageInnerHTML("WebSocket链接关闭"); 
    } 
    // 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket链接,防止链接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function () { 
        closeWebSocket(); 
    } 
    // 将消息显示在网页上 
    function setMessageInnerHTML(text) { 
        document.getElementById('message').innerText += text ; 
        document.getElementById('message').innerHTML += '<br/>' 
    } 
    // 关闭WebSocket链接 
    function closeWebSocket() { 
        websocket.close(); 
    } 
</script>
</html>
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号