Erlo

Springboot + Websocket + Sockjs + Stomp + Vue + Iview 实现java后端日志显示在前端web页面上

2019-05-07 16:02:05 发布   1597 浏览  
页面报错/反馈
收藏 点赞

话不多说,看代码。

一、pom.xml 引入spring boot websocket依赖

1 
2 org.springframework.boot
3 spring-boot-starter-websocket
4 

二、WebSocketConfig 配置WebSocket消息代理端点,即stomp服务端

 1 @Slf4j
 2 @Configuration
 3 @EnableWebSocketMessageBroker // 注解开启STOMP协议来传输基于代理的消息,此时控制器支持使用
 4 @MessageMapping
 5 public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer
 6 {
 7     @Autowired
 8     private SimpMessagingTemplate messagingTemplate;
 9 
10     // 测试
11     // int info = 1;
12     //
13     // @Scheduled(fixedRate = 4000)
14     // public void outputLogger()
15     // {
16     // log.info("测试日志输出" + info++);
17     // }
18 
19     @Override
20     public void registerStompEndpoints(StompEndpointRegistry registry)
21     {
22         // 将clientMessage注册为STOMP的一个端点
23         // 客户端在订阅或发布消息到目的路径前,要连接该端点
24         // setAllowedOrigins允许所有域连接,否则浏览器可能报403错误
25         registry.addEndpoint("/websocket").setAllowedOrigins("*").addInterceptors().withSockJS(); //
26     }
27 
28     
29 
30     /**
31      * 推送日志到/topic/pullLogger
32      */
33     @PostConstruct
34     public void pushLogger()
35     {
36         ExecutorService executorService = Executors.newFixedThreadPool(4);
37         Runnable fileLog = new Runnable()
38         {
39             @Override
40             public void run()
41             {
42                 while (true)
43                 {
44                     try
45                     {
46                         String log = LoggerQueue.getInstance().poll().toString();
47                         if (log != null)
48                         {
49                             if (messagingTemplate != null)
50                                 messagingTemplate.convertAndSend("/topic/pullFileLogger", log);
51                         }
52                     }
53                     catch (Exception e)
54                     {
55                         e.printStackTrace();
56                     }
57                 }
58             }
59         };
60         executorService.submit(fileLog);
61         executorService.submit(fileLog);
62     }
63 }

三、新增日志消息实体

 1 /*
 2  * 日志消息实体类,这里用了lombok插件
 3  * 没有安装该插件的话,就手动添加get、set方法、toString方法
 4  */
 5 @Getter
 6 @Setter
 7 @ToString
 8 @AllArgsConstructor
 9 public class LoggerMessage
10 {
11     private String body;
12     private String timestamp;
13     private String threadName;
14     private String className;
15     private String level;
16     private String exception;
17     private String cause;
18 }

四、创建一个阻塞队列,作为日志系统输出的日志的一个临时载体

 

 1 /*
 2  * 创建一个阻塞队列,作为日志系统输出的日志的一个临时载体
 3  */
 4 public class LoggerQueue
 5 {
 6     // 队列大小
 7     public static final int QUEUE_MAX_SIZE = 10000;
 8     private static LoggerQueue alarmMessageQueue = new LoggerQueue();
 9     // 阻塞队列
10     private BlockingQueue blockingQueue = new LinkedBlockingQueue(QUEUE_MAX_SIZE);
11 
12     private LoggerQueue()
13     {
14     }
15 
16     public static LoggerQueue getInstance()
17     {
18         return alarmMessageQueue;
19     }
20 
21     /**
22      * 消息入队
23      *
24      * @param log
25      * @return
26      */
27     public boolean push(LoggerMessage log)
28     {
29         return this.blockingQueue.add(log);// 队列满了就抛出异常,不阻塞
30     }
31 
32     /**
33      * 消息出队
34      *
35      * @return
36      */
37     public LoggerMessage poll()
38     {
39         LoggerMessage result = null;
40         try
41         {
42             result = (LoggerMessage) this.blockingQueue.take();
43         }
44         catch (InterruptedException e)
45         {
46             e.printStackTrace();
47         }
48         return result;
49     }
50 }

 

五、获取logback的日志,塞入日志队列中

  1.定义Logfilter拦截输出日志

 

 1 @Service
 2 public class LogFilter extends Filter
 3 {
 4     @Override
 5     public FilterReply decide(ILoggingEvent event)
 6     {
 7         String exception = "";
 8         IThrowableProxy iThrowableProxy1 = event.getThrowableProxy();
 9         if (iThrowableProxy1 != null)
10         {
11             exception = "" + iThrowableProxy1.getClassName() + " " + iThrowableProxy1.getMessage() + "";
12             for (int i = 0; i )
13             {
14                 exception += "" + iThrowableProxy1.getStackTraceElementProxyArray()[i].toString() + "";
15             }
16         }
17         LoggerMessage loggerMessage = new LoggerMessage(event.getMessage(), DateFormat.getDateTimeInstance().format(new Date(event.getTimeStamp())), event.getThreadName(), event.getLoggerName(),
18                 event.getLevel().levelStr, exception, "");
19         LoggerQueue.getInstance().push(loggerMessage);
20         return FilterReply.ACCEPT;
21     }
22 }

 

  2.配置logback-spring.xml,添加我们自定义的filter

 1 xml version="1.0" encoding="UTF-8"?>
 2  日志级别从低到高分为TRACE -->
 3  scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
 4  scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。
 5                  当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
 6  debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
 7 configuration  scan="true" scanPeriod="10 seconds">
 8     contextName>logbackcontextName>
 9      include resource="org/springframework/boot/logging/logback/defaults.xml" />
10      include resource="org/springframework/boot/logging/logback/file-appender.xml" />
11      name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义后,可以使“${}”来使用变量。 -->
12     property name="log.path" value="/var/log/" />
13  
14     0. 日志格式和颜色渲染 -->
15      彩色日志依赖的渲染类 -->
16     conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
17     conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
18     conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
19      彩色日志格式 -->
20     property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
21  
22     1. 输出到控制台-->
23     appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
24         此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
25          
26             info
27          -->
28         encoder>
29             Pattern>${CONSOLE_LOG_PATTERN}Pattern>
30              设置字符集 -->
31             charset>UTF-8charset>
32         encoder>
33         此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
34         filter class="com.hmkj.ddos.config.LogFilter">
35         filter>
36     appender>
37  
38      2.2 level为 INFO 日志,时间滚动输出  -->
39     appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
40          正在记录的日志文档的路径及文档名 -->
41         file>${log.path}/hmddos.logfile>
42         日志文档输出格式-->
43         encoder>
44             pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%npattern>
45             charset>UTF-8charset>
46         encoder>
47          日志记录器的滚动策略,按日期,按大小记录 -->
48         rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
49              每天日志归档路径以及格式 -->
50             fileNamePattern>${log.path}/web-info-%d{yyyy-MM-dd}.%i.logfileNamePattern>
51             timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
52                 maxFileSize>10MBmaxFileSize>
53             timeBasedFileNamingAndTriggeringPolicy>
54             日志文档保留天数-->
55             maxHistory>15maxHistory>
56         rollingPolicy>
57          此日志文档只记录info级别的 -->
58         filter class="ch.qos.logback.classic.filter.LevelFilter">
59             level>infolevel>
60             onMatch>ACCEPTonMatch>
61             onMismatch>DENYonMismatch>
62         filter>
63     appender>
64  
65     root level="info">
66         appender-ref ref="CONSOLE" />
67         appender-ref ref="INFO_FILE" />
68     root>
69 configuration>

六、Vue中添加基于webSocket通信的库

  先安装 sockjs-client 和 stompjs

  注意: 在安装stompjs出现一个问题,net 模块不存在,则应该在项目根目录再执行npm install net 即可。

1 npm install sockjs-client
2 npm install stompjs

  .vue页面

 1 template>
 2   div>
 3     Card dis-hover>
 4       p slot="title" style="padding-bottom: 20px; padding-top: 5px;">
 5             监听程序日志
 6       p>
 7               Button type="primary" @click="openSocket">开启日志Button>  
 8               Button type="error" @click="closeSocket">关闭日志Button>br>br>
 9               div id="filelog-container" style="height: 400px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;">
10                 div id="aa">{{pullFileLogger}}div>
11               div>
12       Card>
13     div>
14 template>
15 
16 &
登录查看全部

参与评论

评论留言

还没有评论留言,赶紧来抢楼吧~~

手机查看

返回顶部

给这篇文章打个标签吧~

棒极了 糟糕透顶 好文章 PHP JAVA JS 小程序 Python SEO MySql 确认