vue+springboot实现控制台日志实时推送前台

vue+springboot实现控制台日志实时推送前台

文章目录

  • vue+springboot实现控制台日志实时推送前台
    • 前言
    • 1.准备工作
      • 1.1 环境准备
      • 1.2 依赖准备
    • 2.原理解释
    • 3.代码实现
      • 3.1 前端部分代码
      • 3.2 后端部分代码
      • 3.3 配置部分
    • 4.运行结果
    • 5.参考文档
    • 6.最后

前言

​ 因为最近在做课程设计,然后采用了前后端分离技术进行开发,后端完成之后被我放到了阿里云服务器上,代码肯定有出问题的时候,刚开始每一次出问题我都跑去连接服务器,然后看问题,(一方面因为我懒没在上面挂专门的日志监控的,另一方面是部署后端的机器是学生机跑太多会影响机器的效率)非常麻烦,所以我就突发奇想做一个类似这个的日志监控程序,放在管理后台里面,在出错的时候用鲜明的颜色标注出来,便于查找问题。于是我就跑去研究折腾这个东西,还好网上有可以参考的地方。经过了2天的折腾已经初步完成了日志监控。

1.准备工作

1.1 环境准备

后端框架:springboot

前端框架:vue

通信方式:websocket

1.2 依赖准备

前端依赖:

npm install stompjs

运行npm run dev可能会报错,提示安装net,执行命令

npm install --save net

后端依赖:

这里两种方式都可以,具体你的框架是采用哪种方式搭建的。

maven:


	org.springframework.boot
	spring-boot-starter-websocket

gradle:

implementation group: 'org.springframework.boot', name: 'spring-boot-starter-websocket', version: '2.1.5.RELEASE'

:因为我搭建的springboot是基于2.1.5的所以我后面标明了版本,如果你是其他版本的,也可以修改。

2.原理解释

实现原理十分简单,一个过滤器(LogFilter),一个socket配置(WebSocketConfig),一个消息实体(LoggerMessage),一个任务队列(LoggerQueue),一个日志配置文件(logback.xml)即可完成该功能。

具体原理如图所示:

vue+springboot实现控制台日志实时推送前台_第1张图片
这是简单的原理图,仅供参考。

3.代码实现

3.1 前端部分代码

openSocket() {
  if (this.stompClient == null) {
    this.res = "
通道连接成功,静默等待....
"
// this.$refs['logContainerDiv'].append(); // 建立连接对象 let socket = new SockJS('http://127.0.0.1:8080/websocket?token=kl'); // 获取STOMP子协议的客户端对象 this.stompClient = Stomp.over(socket); this.stompClient.connect({token: 'kl'}, () => { this.stompClient.subscribe('/topic/pullLogger',(event) => { let content = JSON.parse(event.body); let leverhtml = ''; let className = ""+content.className + ""; switch (content.level) { case 'INFO': leverhtml = "" +content.level + ""; break; case 'DEBUG': leverhtml = "" +content.level + ""; break; case 'WARN': leverhtml = "" +content.level + ""; break; case 'ERROR': leverhtml = "" +content.level + ""; break; } this.res+= "
" + content.timestamp + " " +leverhtml + " --- [" + content.threadName + "] " + className + " :" + content.body + "
"
// this.$refs['logContainerDiv'].append(content.timestamp + " " + leverhtml + " --- [" + content.threadName + "] " + className + " :" + content.body + "
");
if (content.exception != "") { this.res+= "
" + content.exception + "
"
// this.$refs['logContainerDiv'].append(); } if (content.cause != "") { this.res+= "
" + content.cause + "
"
// this.$refs['logContainerDiv'].append(content.cause); } // this.$refs['logContainer'].scrollTo(this.$refs['logContainerDiv'].height() - this.$refs['logContainer'].height()); }, { token: "kltoen" }); }); } }, closeSocket() { if (this.stompClient != null) { this.stompClient.disconnect(); this.stompClient = null; } },

3.2 后端部分代码

后端部分在websocket模块,需要在对应的类上面加入@EnableWebSocketMessageBroker注解,如果不加该注解在运行程序的时候SimpMessagingTemplate类将抛出空指针异常,无法注入。

/**
 * @author gjt
 * @version 1.0
 * @date 2019/6/24 21:13
 * @Description 这里写描述内容
 */
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket")
                .setAllowedOrigins("*")
                .withSockJS();
    }

    /**
     * 推送日志到/topic/pullLogger
     */
    @PostConstruct
    public void pushLogger(){
        ExecutorService executorService= Executors.newFixedThreadPool(2);
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        LoggerMessage log = LoggerQueue.getInstance().poll();
                        if(log!=null){
                            if(messagingTemplate!=null)
                            {
                                messagingTemplate.convertAndSend("/topic/pullLogger",log);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        };
        executorService.submit(runnable);
    }
}
/**
 * @author gjt
 * @version 1.0
 * @date 2019/6/24 21:12
 * @Description 这里写描述内容
 */
@Service
public class LogFilter extends Filter<ILoggingEvent> {

    @Override
    public FilterReply decide(ILoggingEvent event) {
        String exception = "";
        IThrowableProxy iThrowableProxy1 = event.getThrowableProxy();
        if(iThrowableProxy1!=null){
            exception = ""+iThrowableProxy1.getClassName()+" "+iThrowableProxy1.getMessage()+"
"
; for(int i=0; i<iThrowableProxy1.getStackTraceElementProxyArray().length;i++){ exception += ""+iThrowableProxy1.getStackTraceElementProxyArray()[i].toString()+"
"
; } } LoggerMessage loggerMessage = new LoggerMessage( event.getMessage() , DateFormat.getDateTimeInstance().format(new Date(event.getTimeStamp())), event.getThreadName(), event.getLoggerName(), event.getLevel().levelStr, exception, "" ); LoggerQueue.getInstance().push(loggerMessage); return FilterReply.ACCEPT; } }

3.3 配置部分

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        
        <encoder>
            <pattern>${CONSOLE_LOG_PATTERN}pattern>
            
            <charset>UTF-8charset>
        encoder>
        
        <filter class="org.rc.base.filter.LogFilter">filter>
    appender>

4.运行结果

vue+springboot实现控制台日志实时推送前台_第2张图片
这是我已经整合进入后台管理之后的效果图。

5.参考文档

spring-boot推送实时日志到前端页面显示https://blog.csdn.net/u014174854/article/details/82143595

spring boot集成WebSocket https://blog.csdn.net/zhanghui3239619/article/details/78608662

vue中使用stompjs实现mqtt消息推送通知 https://www.cnblogs.com/liemei/p/7064386.html

6.最后

代码我没有放全,如果有需要的可以留言,我鼓励大家更多的是主动去尝试写完代码。

以上代码存在一个问题就是实时性,就是日志只能实时反馈不能看几分钟以内的,这一点需要改进,也是我后期打算优化的地方。

嘎嘎嘎我要准备升级了。。。。考完试就干!

来波关注吧老铁们~
vue+springboot实现控制台日志实时推送前台_第3张图片

你可能感兴趣的:(JAVA,Springboot入门手册)