作者 朱兆平

启用websockt在线查看日志文件

@@ -30,6 +30,15 @@ @@ -30,6 +30,15 @@
30 <artifactId>mybatis-spring-boot-starter</artifactId> 30 <artifactId>mybatis-spring-boot-starter</artifactId>
31 <version>1.3.2</version> 31 <version>1.3.2</version>
32 </dependency> 32 </dependency>
  33 + <!--有WEBSOCKET包 包含了spring-boot-starter-web 和spring-boot-starter包 有这个包不要引入这俩包-->
  34 + <dependency>
  35 + <groupId>org.springframework.boot</groupId>
  36 + <artifactId>spring-boot-starter-websocket</artifactId>
  37 + </dependency>
  38 + <dependency>
  39 + <groupId>org.springframework.boot</groupId>
  40 + <artifactId>spring-boot-starter-thymeleaf</artifactId>
  41 + </dependency>
33 <dependency> 42 <dependency>
34 <groupId>org.springframework.cloud</groupId> 43 <groupId>org.springframework.cloud</groupId>
35 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> 44 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
@@ -40,16 +49,16 @@ @@ -40,16 +49,16 @@
40 <artifactId>spring-boot-starter-test</artifactId> 49 <artifactId>spring-boot-starter-test</artifactId>
41 <scope>test</scope> 50 <scope>test</scope>
42 </dependency> 51 </dependency>
43 - <dependency>  
44 - <groupId>org.springframework.boot</groupId>  
45 - <artifactId>spring-boot-starter-web</artifactId> 52 + <!--<dependency>-->
  53 + <!--<groupId>org.springframework.boot</groupId>-->
  54 + <!--<artifactId>spring-boot-starter-web</artifactId>-->
46 <!--<exclusions>--> 55 <!--<exclusions>-->
47 <!--<exclusion>--> 56 <!--<exclusion>-->
48 <!--<groupId>ch.qos.logback</groupId>--> 57 <!--<groupId>ch.qos.logback</groupId>-->
49 <!--<artifactId>logback-classic</artifactId>--> 58 <!--<artifactId>logback-classic</artifactId>-->
50 <!--</exclusion>--> 59 <!--</exclusion>-->
51 <!--</exclusions>--> 60 <!--</exclusions>-->
52 - </dependency> 61 + <!--</dependency>-->
53 <!--spring boot--> 62 <!--spring boot-->
54 <!-- alibaba的druid数据库连接池 --> 63 <!-- alibaba的druid数据库连接池 -->
55 <dependency> 64 <dependency>
  1 +package com.tianbo.warehouse.bean;
  2 +
  3 +import org.springframework.context.annotation.Bean;
  4 +import org.springframework.context.annotation.Configuration;
  5 +import org.springframework.web.socket.server.standard.ServerEndpointExporter;
  6 +
  7 +@Configuration
  8 +public class WebSocketConfig {
  9 + @Bean
  10 + public ServerEndpointExporter serverEndpointExporter() {
  11 + return new ServerEndpointExporter();
  12 + }
  13 +}
  1 +package com.tianbo.warehouse.controller;
  2 +
  3 +import org.springframework.stereotype.Controller;
  4 +import org.springframework.web.bind.annotation.RequestMapping;
  5 +
  6 +@Controller
  7 +public class ImfLog {
  8 +
  9 + @RequestMapping("/log/imf")
  10 + public String IMFlog(){
  11 + return "log/imf";
  12 + }
  13 +}
  14 +
  1 +package com.tianbo.warehouse.controller;
  2 +
  3 +import com.tianbo.warehouse.handle.IO_Log_Handle;
  4 +import org.springframework.stereotype.Component;
  5 +
  6 +import javax.websocket.OnClose;
  7 +import javax.websocket.OnError;
  8 +import javax.websocket.OnOpen;
  9 +import javax.websocket.Session;
  10 +import javax.websocket.server.ServerEndpoint;
  11 +import java.io.IOException;
  12 +import java.io.InputStream;
  13 +import java.util.concurrent.CopyOnWriteArraySet;
  14 +
  15 +
  16 +@ServerEndpoint(value = "/log")
  17 +@Component
  18 +public class Log {
  19 + private Process process;
  20 + private InputStream inputStream;
  21 + //与某个客户端的连接会话,需要通过它来给客户端发送数据
  22 + private Session session;
  23 +
  24 + //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
  25 + private static int onlineCount = 0;
  26 + //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。
  27 + private static CopyOnWriteArraySet<Log> webSocketSet = new CopyOnWriteArraySet<Log>();
  28 +
  29 +
  30 + @OnOpen
  31 + public void onOpen(Session session){
  32 + this.session = session;
  33 + webSocketSet.add(this);
  34 + addOnlineCount();
  35 + try {
  36 + process = Runtime.getRuntime().exec("tail -f logs/imf.log");
  37 + inputStream = process.getInputStream();
  38 + IO_Log_Handle thread = new IO_Log_Handle(inputStream, session);
  39 + thread.start();
  40 +
  41 + }catch (IOException e){
  42 + e.printStackTrace();
  43 + }
  44 +
  45 + }
  46 + /**
  47 + * WebSocket请求关闭
  48 + */
  49 + @OnClose
  50 + public void onClose() {
  51 + try {
  52 + if(inputStream != null) {
  53 + inputStream.close();
  54 + }
  55 + } catch (Exception e) {
  56 + e.printStackTrace();
  57 + }
  58 + if(process != null){
  59 + process.destroy();
  60 + }
  61 +
  62 + }
  63 +
  64 + @OnError
  65 + public void onError(Throwable thr) {
  66 + thr.printStackTrace();
  67 + }
  68 +
  69 + public static synchronized void addOnlineCount() {
  70 + Log.onlineCount++;
  71 + }
  72 + public static synchronized int getOnlineCount() {
  73 + return onlineCount;
  74 + }
  75 +
  76 +
  77 +}
  1 +package com.tianbo.warehouse.handle;
  2 +
  3 +import javax.websocket.Session;
  4 +import java.io.BufferedReader;
  5 +import java.io.IOException;
  6 +import java.io.InputStream;
  7 +import java.io.InputStreamReader;
  8 +
  9 +public class IO_Log_Handle extends Thread{
  10 +
  11 + private BufferedReader reader;
  12 + private Session session;
  13 +
  14 + public IO_Log_Handle(InputStream in, Session session) {
  15 + this.reader = new BufferedReader(new InputStreamReader(in));
  16 + this.session = session;
  17 +
  18 + }
  19 +
  20 + @Override
  21 + public void run() {
  22 + String line;
  23 + try {
  24 + while((line = reader.readLine()) != null) {
  25 + // 将实时日志通过WebSocket发送给客户端,给每一行添加一个HTML换行
  26 + session.getBasicRemote().sendText(line + "<br>");
  27 + }
  28 + } catch (IOException e) {
  29 + e.printStackTrace();
  30 + }
  31 + }
  32 +}
@@ -24,7 +24,7 @@ public class IMF_Task { @@ -24,7 +24,7 @@ public class IMF_Task {
24 public static String isNeedSend = "N"; 24 public static String isNeedSend = "N";
25 25
26 26
27 - @Scheduled(fixedRate = 5000) 27 + //@Scheduled(fixedRate = 5000)
28 private static void start() throws Exception { 28 private static void start() throws Exception {
29 PropertyConfigurator.configure("config/log4j.properties"); 29 PropertyConfigurator.configure("config/log4j.properties");
30 client = IMFClientFactory.createInstance(); 30 client = IMFClientFactory.createInstance();
此 diff 太大无法显示。
  1 +<!DOCTYPE html>
  2 +<html>
  3 +<head>
  4 + <meta charset="utf-8">
  5 + <title>tail log</title>
  6 + <script src="/js/jquery.js"></script>
  7 +</head>
  8 +<body>
  9 +<div id="log-container" style="height: 450px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;">
  10 + <div>
  11 + </div>
  12 +</div>
  13 +</body>
  14 +<script>
  15 + $(document).ready(function() {
  16 + // 指定websocket路径
  17 + var websocket = new WebSocket('ws://localhost:7003/log');
  18 + websocket.onmessage = function(event) {
  19 + // 接收服务端的实时日志并添加到HTML页面中
  20 + $("#log-container div").append(event.data);
  21 + // 滚动条滚动到最低部
  22 + $("#log-container").scrollTop($("#log-container div").height() - $("#log-container").height());
  23 + };
  24 + });
  25 +</script>
  26 +</body>
  27 +</html>