java实现tail -f 日志实时输出到页面

java实现tail -f 日志实时输出到页面背景今天有点无聊,于是有了这个项目……解决了什么问题页面实时查看日志,省去了连接服务器再查找日志……效果talkischeap,showmethecodepom <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-sta…

大家好,又见面了,我是你们的朋友全栈君。

背景

    今天有点无聊,于是有了这个项目……

 

解决了什么问题

    页面实时查看日志,省去了连接服务器再查找日志……

 

效果

实时将后台日志文件内容输出~

java实现tail -f 日志实时输出到页面

talk is cheap, show me the code

pom

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>javax.websocket</groupId>
			<artifactId>javax.websocket-api</artifactId>
			<version>1.1</version>
			<scope>provided</scope>
		</dependency>

		<dependency>
			<groupId>org.jsoup</groupId>
			<artifactId>jsoup</artifactId>
			<version>1.13.1</version>
		</dependency>

		<dependency>
			<groupId>com.squareup.okhttp3</groupId>
			<artifactId>okhttp</artifactId>
			<version>4.9.0</version>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
    </dependencies>
LogWebSocketHandle

import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

@Component
@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 /opt/csdn.log");
            inputStream = process.getInputStream();

            // 一定要启动新的线程,防止InputStream阻塞处理WebSocket的线程
            new Thread(() -> {
                String line;
                try {
                    while ((line = new BufferedReader(new InputStreamReader(inputStream)).readLine()) != null) {
                        // 将实时日志通过WebSocket发送给客户端,给每一行添加一个HTML换行
                        session.getBasicRemote().sendText(line + "<br>");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).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();
    }
}
WebSocketConfig
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {

    /**
     * 服务器节点
     * <p>
     * 如果使用独立的servlet容器,而不是直接使用springboot的内置容器,就不要注入ServerEndpointExporter,因为它将由容器自己提供和管理
     *
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

index.html

注意⚠️:下面这句的IP换成服务器的工网IP

var websocket = new WebSocket(‘ws://127.0.0.1:8080/log’);

<!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: 700px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;">
		<div>
		</div>
	</div>
</body>
<script>
	$(document).ready(function() {
		// 指定websocket路径
		var websocket = new WebSocket('ws://127.0.0.1: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>

 

项目源码关注公众号《小马JAVA》回复: 实时日志 即可获取

java实现tail -f 日志实时输出到页面

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/140556.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • gdb调试命令的使用及总结_大锅安装调试指南

    gdb调试命令的使用及总结_大锅安装调试指南写这篇文档的目的是对前面GDB的知识做一次总览,本文为GDB调试指南,参考GDB调试手册,目前已有的篇目:启动调试断点设置查看源码单步调试查看变量前言GDB是Linux下非常好用且强大的调试工具。GDB可以调试C、C++、Go、java、objective-c、PHP等语言。对于一名Linux下工作的c/c++程序员,GDB是必不可少的工具,本篇以C语言来调试。GDB简介U…

    2025年8月7日
    3
  • I2C之知(六)–s3c2440用I2C接口访问EEPROM

    I2C之知(六)–s3c2440用I2C接口访问EEPROM在前面阅读理解了I2C的官方协议文档后,就拿s3c2440和EEPROM来验证一下.    本来是想用s3c2440的SDA和SCL管脚复用为GPIO来模拟的,但在没有示波器的情况下搞了一周,怎么都出不来,最后还是放弃了.甚至参考了linux下i2c-algo-bit.c和i2c-gpio.c,依然没调出来.如果有示波器,可能很快就能找到原因,现在完全不知道问题出在哪里.其实想用GPI

    2022年5月31日
    33
  • checkbox选中和不选中的值_设置checkbox选中状态

    checkbox选中和不选中的值_设置checkbox选中状态1.设置选中:$(“#hasApply”).prop(“checked”,true);设置不选中:$(“#hasApply”).prop(“checked”,false);或如下方法://$(“#ck”).attr(“checked”,true)//选中//$(“#ck”).attr(“checked”,false)//未选中2.获取选中的状态:varstatus…

    2022年4月20日
    976
  • flashfxp 5.4.0.3970 绿色汉化版注册码[通俗易懂]

    flashfxp 5.4.0.3970 绿色汉化版注册码[通俗易懂]FlashFXPRegistrationDataSTARTFLASHFXP0wC2kbML0wAAAADEW5MNJwTnsl790jgG5F4CTA4jUAdMi66HHqFbShaEpE

    2022年7月1日
    139
  • FRP内网穿透_内网穿透 无需公网ip

    FRP内网穿透_内网穿透 无需公网ip一、关于内网穿透内网穿透,也即NAT穿透,进行NAT穿透是为了使具有某一个特定源IP地址和源端口号的数据包不被NAT设备屏蔽而正确路由到内网主机。下面就相互通信的主机在网络中与NAT设备的相对位置介绍内网穿透方法。二、为什么要使用内网穿透为了外网要访问内网,因为当不在同一局域网内,ip和地址互相ping不同的话,最简单的方式是使用向日葵与teamview,但是用起来并不方便。三、使用frp进行内网穿透(1)关于frp的介绍frp是一个高性能的反向代理应用,可以帮助您轻

    2025年11月5日
    3
  • java解析xml文档并保存到数据库

    java解析xml文档并保存到数据库java解析xml文档并保存到数据库:sadf说明:用xml文档简单写一份新闻如下:洛阳未来一周将持续高温天气中国气象局洛阳未来一周将持续高温天气,局部地区温度高达39度!请大家做好防范高温,谨防中暑!河南科技大学跻身世界顶尖大学中国教育网据权威机构综合测评之后,河南科技大学全世界排名超前,成功跻身世界顶尖大学!洛阳牡丹甲天下中国旅游网洛阳牡丹甲不是

    2022年5月29日
    35

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号