龙空技术网

spring boot集成WebSocket实时输出日志到web页面

小陈博主 3416

前言:

眼前我们对“jquery日志动态显示”大致比较讲究,我们都需要剖析一些“jquery日志动态显示”的相关内容。那么小编同时在网络上收集了一些有关“jquery日志动态显示””的相关内容,希望看官们能喜欢,姐妹们一起来学习一下吧!

前言碎语

今天来做个有趣的东西,就是实时将系统日志输出的前端web页面,因为是实时输出,所有第一时间就想到了使用webSocket,而且在spring boot中,使用websocket超级方便,阅读本文,你会接触到以下关键词相关技术,WebSocket(stopmp服务端),stomp协议,sockjs.min.js,stomp.min.js(stomp客户端),本文使用到的其实就是使用spring boot自带的webSocket模块提供stomp的服务端,前端使用stomp.min.js做stomp的客户端,使用sockjs来链接,前端订阅后端日志端点的消息,后端实时推送,达到日志实时输出到web页面的目的,效果如下图

首先了解下stomp?

STOMP即Simple (or Streaming) Text Orientated Messaging Protocol,简单(流)文本定向消息协议,它提供了一个可互操作的连接格式,允许STOMP客户端与任意STOMP消息代理(Broker)进行交互。STOMP协议由于设计简单,易于开发客户端,因此在多种语言和多种平台上得到广泛地应用。

STOMP协议的前身是TTMP协议(一个简单的基于文本的协议),专为消息中间件设计。

STOMP是一个非常简单和容易实现的协议,其设计灵感源自于HTTP的简单性。尽管STOMP协议在服务器端的实现可能有一定的难度,但客户端的实现却很容易。例如,可以使用Telnet登录到任何的STOMP代理,并与STOMP代理进行交互。

下面是具体的步骤,主要是日志信息的获取和日志信息的推送,不多说,上代码

一.引入spring boot websocket依赖

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

二.新增日志消息实体

/*** Created by kl on 2017/10/9.* Content :日志消息实体,注意,这里为了减少篇幅,省略了get,set代码*/public class LoggerMessage{private String body;private String timestamp;private String threadName;private String className;private String level;public LoggerMessage(String body, String timestamp, String threadName, String className, String level) {this.body = body;this.timestamp = timestamp;this.threadName = threadName;this.className = className;this.level = level;}public LoggerMessage() {}}

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

public class LoggerQueue {//队列大小public static final int QUEUE_MAX_SIZE = 10000;private static LoggerQueue alarmMessageQueue = new LoggerQueue();//阻塞队列private BlockingQueueblockingQueue = new LinkedBlockingQueue<>(QUEUE_MAX_SIZE);private LoggerQueue() {}public static LoggerQueue getInstance() {return alarmMessageQueue;}/*** 消息入队* @param log* @return*/public boolean push(LoggerMessage log) {return this.blockingQueue.add(log);//队列满了就抛出异常,不阻塞}/*** 消息出队* @return*/public LoggerMessage poll() {LoggerMessage result = null;try {result = this.blockingQueue.take();} catch (InterruptedException e) {e.printStackTrace();}return result;}}

四.获取logback的日志,塞入日志队列中

1.定义Logfilter拦截输出日志

public class LogFilter extends Filter{@Overridepublic FilterReply decide(ILoggingEvent event) {LoggerMessage loggerMessage = new LoggerMessage(event.getMessage(), DateFormat.getDateTimeInstance().format(new Date(event.getTimeStamp())),event.getThreadName(),event.getLoggerName(),event.getLevel().levelStr);LoggerQueue.getInstance().push(loggerMessage);return FilterReply.ACCEPT;}}

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

<?xml version="1.0" encoding="UTF-8"?><configuration scan="true"><include resource="org/springframework/boot/logging/logback/defaults.xml" /><property name="LOG_FILE"value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}" /><include resource="org/springframework/boot/logging/logback/file-appender.xml" /><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>utf8</charset></encoder><filter class="com.example.websocket.LogFilter"></filter></appender><root level="INFO"><appender-ref ref="FILE" /><appender-ref ref="CONSOLE" /></root></configuration>

五.配置WebSocket消息代理端点,即stomp服务端

@Configurationpublic class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/websocket").setAllowedOrigins("").withSockJS();}}

注意:为了连接安全,setAllowedOrigins设置的允许连接的源地址,如果在非这个配置的地址下发起连接会报403,进一步还可以使用addInterceptors设置拦截器,来做相关的鉴权操作

六.启动类,开启webSocket消息代理功能,并推送日志信息

@SpringBootApplication@EnableScheduling@EnableWebSocketMessageBrokerpublic class WebsocketApplication {private Logger logger = LoggerFactory.getLogger(WebsocketApplication.class);public static void main(String[] args) {SpringApplication.run(WebsocketApplication.class, args);}@Autowiredprivate SimpMessagingTemplate messagingTemplate;int info=1;@Scheduled(fixedRate = 1000)public void outputLogger(){logger.info("测试日志输出"+info++);}/*** 推送日志到/topic/pullLogger*/@PostConstructpublic void pushLogger(){ExecutorService executorService=Executors.newFixedThreadPool(2);Runnable runnable=new Runnable() {@Overridepublic 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);executorService.submit(runnable);}}

七.html页面,连接stomp服务端,订阅/topic/pullLogger的消息,展示日志信息

<!DOCTYPE html><html><head><meta charset="utf-8"><title>WebSocket Logger</title><script src=""></script><script src=""></script><script src=""></script></head><body><button onclick="openSocket()">开启日志</button><button onclick="closeSocket()">关闭日志</button><div id="log-container" style="height: 450px; overflow-y: scroll; background: #333; color: #aaa; padding: 10px;"><div></div></div></body><script>var stompClient = null;$(document).ready(function() {openSocket();});function openSocket() {if(stompClient==null){var socket = new SockJS('');stompClient = Stomp.over(socket);stompClient.connect({token:"kl"}, function(frame) {stompClient.subscribe('/topic/pullLogger', function(event) {var content=JSON.parse(event.body);$("#log-container div").append(content.timestamp +" "+ content.level+" --- ["+ content.threadName+"] "+ content.className+" :"+content.body).append("<br/>");$("#log-container").scrollTop($("#log-container div").height() - $("#log-container").height());},{token:"kltoen"});});}}function closeSocket() {if (stompClient != null) {stompClient.disconnect();stompClient=null;}}</script></body></html>

相关技术官网参考地址:

stomp.js客户端:

scok.js客户端:

spring webSocket:

标签: #jquery日志动态显示