WebSocket页面显示日志的代码

该博客介绍了在前端 HTML 页面显示后台服务器日志信息的方法,目的是方便前端和测试调试。内容包含页面效果展示、前端页面代码及后台代码,如 WebSocket 相关配置、实时读取日志线程和给日志上色方法等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在前端html页面显示后台的服务器日志信息

主要是为了方便,前端也不会ssh去连接服务器tail -f日志。为了方便前端和测试调试,将日志 染色 并显示在页面上。

页面效果

在这里插入图片描述

前端页面代码

前面引用的easyui库这些是为了页面布局和原系统支持。其实对读者没啥用,不需要的去掉就行。

<!--showServiceLog.html-->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebSocket查看服务日志页面</title>
    <!-- easyUI样式 -->
    <link rel="stylesheet" type="text/css" href="../../Font-Awesome-master/css/font-awesome.min.css" />
    <link rel="stylesheet" type="text/css" href="../../css/common/main.css" />
    <link rel="stylesheet" type="text/css" href="../../css/common/my.css" />
    <link rel="stylesheet" type="text/css" href="../../css/themes/default/easyui.css" />
    <link rel="stylesheet" type="text/css" href="../../css/themes/icon.css" />
    <script type="text/javascript" src="../../js/jquery.min.js"></script>
    <script type="text/javascript" src="../../js/jquery.easyui.min.js"></script>
    <script type="text/javascript" src="../../js/easyui-lang-zh_CN.js"></script>
    <script type="text/javascript" src="../../js/common.js"></script>
    <script type="text/javascript" src="../../js/common/Cookie.js"></script>
    <script type="text/javascript" src="../../js/sockjs.js"></script>
    <style type="text/css">
        .datagrid-cell, .datagrid-cell-group, .datagrid-header-rownumber, .datagrid-cell-rownumber
        {
            text-overflow: ellipsis;
        }
    </style>

</head>
<body>
<!-- 标题和操作菜单 -->
<table class="title" style="width:100%;padding:5px;">
    <tbody>
    <tr>
        <td style="width:25%;color: #407EAC">
            <img src="../../images/common/title.gif" style="vertical-align:middle;">查看服务日志</td>
        <td style="text-align: right;">
            <!--按钮区域-->
            <a class="easyui-linkbutton l-btn l-btn-small" data-options="iconCls:'icon-search'"  onclick="loadSocket2()">&nbsp;查看日志&nbsp;</a>
            <a class="easyui-linkbutton l-btn l-btn-small" data-options="iconCls:'icon-search'"  onclick="looknearly()">&nbsp;查看最近&nbsp;</a>
            <a class="easyui-linkbutton l-btn l-btn-small" data-options="iconCls:'icon-search'"  onclick="cleanText()">&nbsp;清屏&nbsp;</a>
        </td>
    </tr>
    </tbody>
</table>
<!-- 模糊查询 -->
<table class="btbForm">
    <tbody>
    <tr>
        <!--<td>-->
            <!--小组发送<input id="groupId" class="easyui-combobox" data-options="editable:false,panelHeight:'auto',limitToList:'true'" style="width: 110px;">-->
            <!--&nbsp;&nbsp;&nbsp;组员&nbsp;<input id="userId" class="easyui-combobox" data-options="editable:false,panelHeight:'auto',limitToList:'true'" style="width: 110px;">-->
        <!--</td>-->
    </tr>
    </tbody>
</table>
<!-- 表格间距 -->
<div style="margin-top:5px"></div>
<!-- 数据表格 -->
<div>
    <div id="text" style=" overflow-y:scroll; width:100%; height:400px;word-break:break-word;">初始化完毕...</div>
</div>
<!--隐藏的昵称信息-->
<input id="nickName" style="display: none">
<script type="text/javascript">
    //定义WebSocket接口
    var ws;
    /**
     * jQuery初始化完毕执行的代码
     */
    $(function(){
        loadSocket2();
        setInterval(function(){
            $('#text').css("height",$(document.body).height()*0.8);
        },300);
    });

    /**
     * 下滑到底部
     */
    function looknearly() {
        try {
            $("#text").scrollTop($("#text")[0].scrollHeight);
        } catch (e) {
            console.error(e);
        }
    }

    /**
     * 获取WebSocket根地址
     */
    function wsPath() {
        //定义ws接口开头协议
        var wsPath = "ws://"+basePath.split("://")[1];
        if(basePath.split("://")[0].trim().toLowerCase().indexOf("https")>-1){
            wsPath = "wss://"+basePath.split("://")[1];
        }
        return wsPath;
    }

    function testOhter() {
        $.messager.prompt('提示信息', '请输入ws地址:', function(r){
            if (r){
                loadSocket2(r);
            }else{
                loadSocket2();
            }
        });
    }


    /**
     * 加载websocket数据
     */
    function loadSocket2(file){
        //console.log(ws);
        if(ws!=null&&ws!=undefined&&ws.readyState == 1){
            $('#text').append("连接已存在..<br/>");
            return;
        }
        if(file!=null&&file!=undefined&&file!=''){
            if ("WebSocket" in window){
                ws=new WebSocket(wsPath()+"/websocket/"+file+".json");
            }else{
                ws=new SockJS(wsPath()+"/sockjs/"+file+".ws");
            }
        }else{
            if ("WebSocket" in window){
                ws=new WebSocket(wsPath()+"/ws_showLog.json");
            }else{
                ws=new SockJS(wsPath()+"/sockjs/ws_showLog.ws");
            }
        }

        $('#text').append("<br/>开始建立连接...<br/>");
        ws.onopen=function(event){
            $('#text').append("连接已建立..<br/>");
            $('#start').linkbutton('disable');
        }
        /**接收消息*/
        ws.onmessage=function(event){
            //console.log(event);
            var msg=event.data;
            $('#text').append(msg);
            // 滚动条滚动到最低部
            try {
                $("#text").scrollTop($("#text")[0].scrollHeight);
            } catch (e) {
                console.error(e);
            }
        }
        ws.onclose=function(){
            $('#text').append("连接已关闭..<br/>");
            $('#start').linkbutton('enable');

        }
        ws.onerror = function(){
            $('#text').append("发生了错误..<br/>");
            $('#start').linkbutton('enable');
        }

    }

    /**
     * 手动加载websocket数据
     */
    function loadSocket(file){

        if(file!=null&&file!=undefined&&file!=''){
            if ("WebSocket" in window){
                ws=new WebSocket(wsPath()+"/websocket/"+file+".json");
            }else{
                ws=new SockJS(wsPath()+"/sockjs/"+file+".ws");
            }
        }else{
            if ("WebSocket" in window){
                ws=new WebSocket(wsPath()+"/ws_showLog.json");
            }else{
                ws=new SockJS(wsPath()+"/sockjs/ws_showLog.ws");
            }
        }

        $('#text').append("<br/>开始建立连接...<br/>");
        ws.onopen=function(event){
            $('#text').append("连接已建立..<br/>");
            $('#start').linkbutton('disable');
        }
        /**接收消息*/
        ws.onmessage=function(event){
            //console.log(event);
            var msg=event.data;
            $('#text').append(msg);
            // 滚动条滚动到最低部
            try {
                $("#text").scrollTop($("#text")[0].scrollHeight);
            } catch (e) {
                console.error(e);
            }
        }
        ws.onclose=function(){
            $('#text').append("连接已关闭..<br/>");
            $('#start').linkbutton('enable');

        }
        ws.onerror = function(){
            $('#text').append("发生了错误..<br/>");
            $('#start').linkbutton('enable');
        }

    }

    /**
     * 清除屏幕
     */
    function cleanText() {
        $('#text').html("屏幕已清除...<br/>");
    }

</script>

</body>
</html>

后台代码

WebSocketInterceptor拦截器

package com.faker.filter;

import com.faker.app.util.ToolsUtil;
import org.apache.log4j.Logger;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * <p>Title: WebSocketInterceptor拦截器 - WebSocketInterceptor_ShowLog</p>
 *
 * <p>Description:WebSocket 适配器 拦截器 显示tomcat日志的拦截器</p>
 *
 * <p>Copyright: Copyright Faker(c) 2018</p>
 *
 * <p>Company: 无</p>
 *
 * @author Anlinxi
 *
 * @version 1.0
 */
public class WebSocketInterceptor_ShowLog implements HandshakeInterceptor {

    /**
     * 日志
     */
    private final static Logger log= Logger.getLogger(WebSocketInterceptor_ShowLog.class);

    /**
     * 握手前
     * @param request 请求
     * @param response 响应
     * @param handler ws握手
     * @param attributes 属性
     * @return 是否握手成功
     * @throws Exception 异常
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler,
                                   Map<String, Object> attributes) throws Exception {
        log.info("执行握手: "+handler+"map: "+attributes.values());
        if(request != null){
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            HttpSession session = servletRequest.getServletRequest().getSession();
            if(session!=null){
                String userId = (String) session.getAttribute("WEBSOCKET_SL_ID");
                if(userId!=null){
                    session.setAttribute("SESSION_SL_ID", userId);
                    attributes.put("WEBSOCKET_SL_ID", userId);
                }else{
                    session.setAttribute("SESSION_SL_ID", session.getId());
                    attributes.put("WEBSOCKET_SL_ID", session.getId());
                }
            }
        }
        return true;
    }

    /**
     * 将属性设置到session里
     * @param session session
     * @param attributes Map
     * @param attributeName 待设置的属性名
     * @param attribute 待设置的属性
     */
    private void setAttributes(HttpSession session,Map<String, Object> attributes,String attributeName,String attribute){
        if (ToolsUtil.isNotNull(attribute)) {
            String attributeNameUp = attributeName.toUpperCase();
            session.setAttribute("SESSION_"+attributeNameUp, attribute);
            attributes.put("WEBSOCKET_"+attributeNameUp, attribute);
        }
    }

    /**
     * 握手后
     * @param request 请求
     * @param response 响应
     * @param handler ws握手
     * @param exceptions 错误
     */
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Exception exceptions) {
        log.info("握手后: "+handler+"exceptions: "+exceptions);
    }

}


WebSocketHandler握手动作

package com.faker.filter;
import com.faker.app.util.CpdetectorUtils;
import com.faker.app.util.TailLogThread;
import com.faker.app.util.ToolsUtil;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.springframework.web.util.HtmlUtils;

import java.io.*;
import java.util.*;

import static java.lang.Thread.sleep;

/**
 * <p>Title: Websocket处理器 - WebSocketHandler_ShowLog</p>
 *
 * <p>Description:统一发送信息等操作的</p>
 *
 * <p>Copyright: Copyright Faker(c) 2018</p>
 *
 * <p>Company: 无</p>
 *
 * @author Anlinxi
 *
 * @version 1.0
 */
public class WebSocketHandler_ShowLog extends TextWebSocketHandler {

    private final static Logger logger = LoggerFactory.getLogger(WebSocketHandler_ShowLog.class);

    /**储存分组信息 分组名:用户分组list*/
    public static final Map<Object, WebSocketSession> userSocketSessionMap;
    static {
        userSocketSessionMap = new HashMap<Object, WebSocketSession>();
    }

    /**实例化的类*/
    public static WebSocketHandler_ShowLog webSocketHandler;
    /**运行的日志程序cmd*/
    private static Process process;
    /**输入流*/
    private static InputStream inputStream;

    /**
     * 实例化方法
     * @return webSocketHandler
     */
    public static WebSocketHandler_ShowLog getBeans(){
        if(webSocketHandler == null){
            webSocketHandler = new WebSocketHandler_ShowLog();
        }
        return webSocketHandler;
    }

    /**
     * 处理前端发送的文本信息
     * js调用websocket.send时候,会调用该方法
     * @param session session
     * @param message 发送信息
     * @throws Exception 异常
     */
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        if(message.getPayloadLength()==0){
            return;
        }
        // message.getPayload().toString() 获取消息具体内容
        Map<String, Object> msg = JSONObject.fromObject(message);
        logger.info("handleMessage......."+message.getPayload()+"..........."+msg);
        session.sendMessage(message);
        // 调用方法(发送消息给所有人)
        this.sendMessageToAllUsers(msg.get("msgContent").toString());
    }

    /**
     * 当新连接建立的时候,被调用
     * 连接成功时候,会触发页面上onOpen方法
     * @param session session
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String uid = (String) session.getAttributes().get("WEBSOCKET_SL_ID");
        if (userSocketSessionMap.get(uid) == null) {//获取用户id
            uid = session.getId();
            userSocketSessionMap.put(uid, session);
        }
        logger.info("======"+uid+" 建立连接完成======");
        //读取配置文件里日志文件地址
        String fileAddr = ToolsUtil.getInstence().getProperties("myConfig","log.tomcat.catalina");
        if(ToolsUtil.isNotNull(fileAddr)){
            //读取现有日志信息
            this.readCatalinaFile(fileAddr,session);
            //进程为空或者未激活时执行cmd命令
            // 执行tail -f命令
            String cmd = "tail -f "+fileAddr;
            try {
                process = Runtime.getRuntime().exec(cmd);
                inputStream = process.getInputStream();
                if(process.isAlive()){
                    // 一定要启动新的线程,防止InputStream阻塞处理WebSocket的线程
                    TailLogThread thread = new TailLogThread(inputStream, session );
                    thread.start();
                }
            } catch (IOException e) {
                //logger.error(cmd);
                System.err.println(cmd);
                e.printStackTrace();
                this.close();
            }

        }else{
            logger.error("======未配置myConfig文件中log.tomcat.catalina属性(tomcat日志路径)======");
        }
    }

    /**
     * 读取现有日志信息
     * @param fileAddr 文件地址
     * @param session WebSocketSession
     */
    private void readCatalinaFile(String fileAddr, WebSocketSession session) {
        Map<String,Object> result = new HashMap<>(4);
        FileInputStream inStream  = null;
        try {
            File file = new File(fileAddr);
            //如果文件夹不存在,先创建文件夹
            if(!file.exists()){
                System.err.println("文件不存在");
                return;
            }
            inStream = new FileInputStream(file);
            String bm =  CpdetectorUtils.getInstence().getFileOrIOEncode(fileAddr,"file");
            InputStreamReader isr = new InputStreamReader(inStream, bm);
            BufferedReader reader = new BufferedReader(isr);
            String pythonText;
            //读取的一行
            String readline;
            List<String> sbList = new ArrayList();
            while((readline = reader.readLine())!=null){
                sbList.add(this.setColorToMsg(readline));
            }
            reader.close();
            int rowsNum  = sbList.size();
            int sendNum  = 0;
            StringBuffer sb = new StringBuffer();
            for(String l:sbList){
                if(1<=rowsNum&&rowsNum<=400){
                    sb.append(l);
                }
                if(sb.length()>4096){
                    session.sendMessage(new TextMessage(sb.toString()));
                    sb.setLength(0);
                    sendNum++;
                    try {
                        //发送一次的时间间隔,给浏览器反映的时间
                        sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                else if(rowsNum<=1&&sb.length()>0){
                    session.sendMessage(new TextMessage(sb.toString()));
                    sb.setLength(0);
                    sendNum++;
                }
                rowsNum--;
            }

            logger.info("原始日志共计"+sbList.size()+"行。发送信息"+sendNum+"次。");
            session.sendMessage(new TextMessage(System.lineSeparator()+System.lineSeparator()+"最近日志加载完毕......"+System.lineSeparator()+System.lineSeparator()));
            inStream.close();

        } catch (IllegalStateException | IOException e) {
            e.printStackTrace();
        }
        return;
    }

    /**
     * 给日志上色!
     * @param msg 日志消息
     * @return html
     */
    private String setColorToMsg(String msg){
        String color = "";
        if(msg.toLowerCase().contains("error")){
            color = "#ff0000";
        }else if(msg.toLowerCase().contains("warn")){
            color = "#ff9900";
        }else if(msg.toLowerCase().contains("debug")){
            color = "#336600";
        }else if(msg.toLowerCase().contains("info")){
            color = "#0033cc";
        }else if(msg.contains("定时清除游离文件中(时间间隔5分钟)")){
            color = "#C1CDCD";
        }else if(msg.contains("Exception")){
            color = "#FFD700";
        }
        //对文本中含有的html代码进行转义
        msg = HtmlUtils.htmlEscape(msg);
        String html = "<p class='log_msg' style='color:"+color+"'>"+msg+"</p>";
        return html;
    }

    /**
     * 当连接关闭时被调用
     * @param session session
     * @param status 连接状态
     * @throws Exception 异常
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        logger.info("Websocket:" + session.getId() + "已经关闭");
        Iterator<Map.Entry<Object, WebSocketSession>> it = userSocketSessionMap
                .entrySet().iterator();
        // 移除Socket会话
        logger.info("======关闭连接======");
        while (it.hasNext()) {
            Map.Entry<Object, WebSocketSession> entry = it.next();
            if (entry.getValue().getId().equals(session.getId())) {
                userSocketSessionMap.remove(entry.getKey());
                logger.warn("Socket会话已经移除:用户ID" + entry.getKey());
                break;
            }
        }
        this.close();
    }

    /**
     * 关闭程序和流
     */
    private void close(){
//        logger.info("关闭ws的程序和流!");
//        try {
//            if(inputStream != null)
//                inputStream.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        if(process != null){
//            process.destroy();
//        }
    }

    /**
     * 传输错误时调用
     * @param session session
     * @param exception 异常
     * @throws Exception 异常
     */
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        if (session.isOpen()) {
            session.close();
        }
        Iterator<Map.Entry<Object, WebSocketSession>> it = userSocketSessionMap
                .entrySet().iterator();
        logger.info("======消息传输错误======");
        // 移除Socket会话
        while (it.hasNext()) {
            Map.Entry<Object, WebSocketSession> entry = it.next();
            if (entry.getValue().getId().equals(session.getId())) {
                userSocketSessionMap.remove(entry.getKey());
                logger.error("Socket会话已经移除:用户ID" + entry.getKey());
                break;
            }
        }
        this.close();
    }

    /**
     * 给所有在线用户发送消息
     * @param message 发送消息
     */
    public void sendMessageToAllUsers(String message) {
        Iterator<Map.Entry<Object, WebSocketSession>> it = userSocketSessionMap
                .entrySet().iterator();
        logger.info("======群发======");
        // 多线程群发
        while (it.hasNext()) {
            final Map.Entry<Object, WebSocketSession> entry = it.next();
            if (entry.getValue().isOpen()) {
                new Thread(new Runnable() {
                    public void run() {
                        try {
                            if (entry.getValue().isOpen()) {
                                entry.getValue().sendMessage(new TextMessage(message));
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        }
    }


    /**
     * 给某个用户发送消息
     * @param userId 用户id
     * @param message 发送信息
     */
    public void sendMessageToUser(String userId,String message) throws IOException {
        WebSocketSession session = userSocketSessionMap.get(userId);
        logger.info("======给某个用户发送消息======");
        if (session != null && session.isOpen()) {
            session.sendMessage(new TextMessage(message));
        }
    }

}

WebSocketConfig配置类

package com.faker.filter;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

/**
 * <p>Title: websocket配置类 - WebSocketConfig_ShowLog</p>
 *
 * <p>Description:websocket日志显示的配置信息</p>
 *
 * <p>Copyright: Copyright Faker(c) 2018</p>
 *
 * <p>Company: 无</p>
 *
 * @author Anlinxi
 *
 * @version 1.0
 */
@Configuration
//这个标注可以不加,如果有加,要extends WebMvcConfigurerAdapter
@EnableWebMvc
@EnableWebSocket
public class WebSocketConfig_ShowLog extends WebMvcConfigurerAdapter implements WebSocketConfigurer {

    /**
     * 注册websocket的信息
     * @param registry registry
     */
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        //设置websocket的地址,注册Handler,注册Interceptor
        registry.addHandler(SocketHandler(), "/ws_showLog.json").setAllowedOrigins("*").addInterceptors(new WebSocketInterceptor_ShowLog());
        //注册SockJS,提供SockJS支持(主要是兼容ie8)
        registry.addHandler(SocketHandler(), "/sockjs/ws_showLog.ws")
                //允许跨域
                .setAllowedOrigins("*")
                //注册Interceptor
                .addInterceptors(new WebSocketInterceptor_ShowLog())
                //支持sockjs协议
                .withSockJS();
    }

    @Bean
    public org.springframework.web.socket.WebSocketHandler SocketHandler(){
        return new com.faker.filter.WebSocketHandler_ShowLog ();
    }


    /**
     * 配置webSocket引擎
     * 用于tomcat 可以不配置
     * @return Bean
     */
    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(8192);
        container.setMaxBinaryMessageBufferSize(8192);
        return container;
    }

}

TailLogThread实时读取日志的线程

package com.faker.app.util;
import org.apache.commons.codec.StringEncoder;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.util.HtmlUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class TailLogThread extends Thread {

    /**读取缓冲*/
    private BufferedReader reader;
    /**WebSocketSession*/
    private WebSocketSession session;
    /**消息队列*/
    private List<String> msgs = new ArrayList<>();
    /**cmd的文本编码*/
    private String encoding;

    public TailLogThread(InputStream in, WebSocketSession session) {
        this.reader = new BufferedReader(new InputStreamReader(in));
        this.session = session;

    }

    /**
     * 读取日志的方法
     */
    @Override
    public void run() {
        this.method1();
    }

    /**
     * 原始读取日志的方法
     */
    private void method1(){
        String line;
        try {
            if(session.isOpen()){
                //如果消息队列有数据,则先输出消息队列消息
                if(msgs.size()>0){
                    List<String> errMsgs = new ArrayList<>();
                    for(String msg:msgs){
                        try {
                            //输出消息队列消息
                            this.sendMsg(msg,session);
                        } catch (IOException e) {
                            //未发送的信息储存在错误消息队列中
                            System.err.println(e.getMessage());
                            errMsgs.add(msg);
                        }
                    }
                    //清空消息队列
                    msgs.clear();
                    //如果有错误的消息队列,储存给消息队列中
                    if(errMsgs.size()>0){
                        msgs = errMsgs;
                    }
                }
            }
            while((line = reader.readLine()) != null) {
                if(encoding==null||encoding==""){
                    encoding = this.StringEncoding(line);
                }
                //String text = new String(line.getBytes(encoding),"UTF-8");
                // 将实时日志通过WebSocket发送给客户端,给每一行添加一个HTML换行
                if(session.isOpen()){
                    this.sendMsg(line,session);
                }else{
                    msgs.add(line);
                }
            }
        } catch (IOException e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 发送消息
     * @param msg
     * @param session
     * @throws IOException
     */
    private void sendMsg(String msg,WebSocketSession session) throws IOException {
        String str = msg;
        if(1==1){
            str = this.setColorToMsg(msg);
        }else{
            //文本域
            str = str + System.lineSeparator();
        }
        session.sendMessage(new TextMessage(str));
    }

    /**
     * 判断字符串编码
     * @param sb 字符串
     * @return 编码类型
     */
    private String StringEncoding(String sb){
        String backEncoding = "";
        String iso8859 = this.testEncoding(sb,"iso8859-1");
        String gbk = this.testEncoding(sb,"gbk");
        String utf8 = this.testEncoding(sb,"utf-8");
        if(iso8859.equals(sb.toString())){
            backEncoding = "iso8859";
        }else  if(gbk.equals(sb.toString())){
            backEncoding = "gbk";
        }else  if(utf8.equals(sb.toString())){
            backEncoding = "utf8";
        }
        return backEncoding;
    }

    /**
     * 给日志上色!
     * @param msg 日志消息
     * @return html
     */
    private String setColorToMsg(String msg){
        String color = "";
        if(msg.toLowerCase().contains("error")){
            color = "#ff0000";
        }else if(msg.toLowerCase().contains("warn")){
            color = "#ff9900";
        }else if(msg.toLowerCase().contains("debug")){
            color = "#336600";
        }else if(msg.toLowerCase().contains("info")){
            color = "#0033cc";
        }else if(msg.contains("定时清除游离文件中(时间间隔5分钟)")){
            color = "#C1CDCD";
        }else if(msg.contains("Exception")){
            color = "#FFD700";
        }
        //对文本中含有的html代码进行转义
        msg = HtmlUtils.htmlEscape(msg);
        String html = "<p class='log_msg' style='color:"+color+"'>"+msg+"</p>";
        return html;
    }

    /**
     * 测试编码
     * @param sb 文本
     * @param encoding 编码
     * @return
     */
    private String testEncoding(String sb,String encoding){
        String tmpStrin = null;
        try {
            tmpStrin = new String(sb.toString().getBytes(encoding));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return tmpStrin;
    }
}

ToolsUtil工具类

package com.faker.app.util;

import com.sun.istack.internal.NotNull;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;

/**
 * <p>Title: 常用的工具类 - ToolsUtil</p>
 *
 * <p>Description:常用工具放这儿</p>
 *
 * <p>Copyright: Copyright Faker(c) 2018</p>
 *
 * <p>Company: 无</p>
 *
 * @author Anlinxi
 *
 * @version 1.0
 */
public class ToolsUtil {

    /**
     * 工具类实例化对象
     */
    private static ToolsUtil toolsUtil = null;

    /**
     * 私有化构造函数防止new对象消耗内存
     */
    private ToolsUtil() {

    }
    /**
     * 静态实例化方法获取实例化对象
     * 使用同一个lCsinginUtil,减少内存占用
     * @return LCsinginUtil
     */
    public static ToolsUtil getInstence(){
        if(toolsUtil==null){
            toolsUtil = new ToolsUtil();
        }
        return toolsUtil;
    }

    /**
     * 日志
     */
    private final static Logger logger = LoggerFactory.getLogger(ToolsUtil.class);

    /**
     * 发送json数据
     * @param response 响应
     * @param object 发送的对象
     */
    public static void WriterJson(@NotNull HttpServletResponse response, Object object){
        try {
            String backJson = null;
            if(object instanceof List){
                JSONArray jsonArray = JSONArray.fromObject(object);
                backJson = jsonArray.toString();
            }else{
                JSONObject jsonObject = JSONObject.fromObject(object);
                backJson = jsonObject.toString();
            }
            response.setHeader("Cache-Control", "no-cache");
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setContentType("text/json;charset=utf-8");
            PrintWriter printWriter = response.getWriter();
            logger.info("发送json数据>>>>>>>>>>>>>>>>"+backJson);
            printWriter.write(backJson);
            printWriter.flush();
            printWriter.close();
        } catch (IOException e) {
            logger.error("发送json数据失败");
            e.printStackTrace();
        }
    }


    /**
     * 判断一个字符串是否为null或空字符,是则返回false,否为true
     * @param str 字符串对象
     * @return 是否为null或空字符
     */
    public static boolean isNotNull(Object str){
        return !isNullOrEmpty(str);
    }

    /**
     * 判断一个字符串是否为null或空字符,是则返回true,否为false
     * @param str 字符串对象
     * @return 是否为null或空字符
     */
    public static boolean isNullOrEmpty(Object str){
        String t = trim(str);
        if(t.equals("") || t==null){
            return true;
        } else {
            return false;
        }
    }

    /**
     * 字符串对象去空
     * @param str 字符串对象
     * @return 替换空
     */
    public static String trim(Object str){
        return trim(str, "");
    }

    /**
     * 将对象转换为字符串类型
     * @param obj 对象
     * @param nullToString 如果为空就返回该默认值
     * @return 字符串类型
     */
    public static String trim(Object obj, String nullToString){
        return obj == null ? nullToString : obj.toString().trim();
    }

    /**
     * 读取python文件代码
     * @param fileName 文件名(含后缀)
     * @param path 文件夹路径
     * @return 读取的字符串
     */
    public Boolean download( HttpServletResponse response,String fileName, String path){
        FileInputStream inStream  = null;
        try {
            inStream = new FileInputStream(path+fileName);
            //通过available方法取得流的最大字符数
            byte[] inOutb = new byte[inStream.available()];
            //读入流,保存在byte数组
            inStream.read(inOutb);
            //设置文件类型
            response.setContentType(Files.probeContentType(Paths.get(path+fileName)));
            //将response提取流
            OutputStream out = response.getOutputStream();
            //将byte数组写入response中
            out.write(inOutb);
            //刷新流
            out.flush();
            out.close();
            inStream.close();
        } catch (Exception e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 获取系统信息
     */
    Properties prop = System.getProperties();

    /**
     * 获取当前服务器所在系统的路径
     * @return 服务器的路径
     */
    public String classRootPath() {
        //确定jython目录的路径
        String classRootPath = this.getClass().getResource("/").toString();
        String os = prop.getProperty("os.name");
        if (os != null && os.toLowerCase().indexOf("linux") > -1) {
            return classRootPath.replace("file:", "");
        } else {
            return classRootPath.replace("file:/", "");
        }
    }

    /**
     * 获取properties文件配置信息
     * @param fileName 文件名(不含后缀)
     * @param key 取值对应的键名
     * @return 值
     * @throws Exception 异常
     */
    public String getProperties (String fileName,String key) throws Exception {
        //文件名不为空
        if(fileName!=null&&!"".equals(fileName)){
            //不需要后缀
            if(fileName.contains(".properties")){
                fileName.replace(".properties","");
            }
            if(key!=null&&!"".equals(key)){
                //properties文件放置的位置
                String fileAddr = "config/"+fileName;
                ResourceBundle resource = ResourceBundle.getBundle(fileAddr);
                String text = new String(resource.getString(key).getBytes("ISO-8859-1"), "UTF8");
                return text;
            }else{
                throw new Exception("取值键名为空!");
            }
        }else{
            throw new Exception("文件名为空!");
        }
    }
}

给日志上色的方法

这个方法是去匹配字符串,不是原本的错误就是红色,所以可能有误差。配色也不会配,颜色区分这些还是前端要敏感一些。

	/**
     * 给日志上色!
     * @param msg 日志消息
     * @return html
     */
    private String setColorToMsg(String msg){
        String color = "";
        if(msg.toLowerCase().contains("error")){
            color = "#ff0000";
        }else if(msg.toLowerCase().contains("warn")){
            color = "#ff9900";
        }else if(msg.toLowerCase().contains("debug")){
            color = "#336600";
        }else if(msg.toLowerCase().contains("info")){
            color = "#0033cc";
        }else if(msg.contains("定时清除游离文件中(时间间隔5分钟)")){
            color = "#C1CDCD";
        }else if(msg.contains("Exception")){
            color = "#FFD700";
        }
        //对文本中含有的html代码进行转义
        msg = HtmlUtils.htmlEscape(msg);
        String html = "<p class='log_msg' style='color:"+color+"'>"+msg+"</p>";
        return html;
    }
    ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值