当前位置: 首页 > 工具软件 > websockets4j > 使用案例 >

log4j推送日志到本地然后再推送到前端

羊禄
2023-12-01

1、log4j.properties

log4j.rootLogger=debug,stdout,WriterAppender

#Console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%t] %c %L : %m%n
#log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} - %X{ip} -%5p %c{1}:%L - %m%n

# 选用WriterAppender作为Appender,表示以流的形式输出,这个Appender一般很少用,是常用Appender的父类
log4j.appender.WriterAppender=org.apache.log4j.WriterAppender
log4j.appender.WriterAppender.Threshold=debug
log4j.appender.WriterAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.WriterAppender.layout.ConversionPattern=%d %p [%t] %c %L : %m%n
# %X{ip} 输出本服务器的ip,通过MDC输入(见后面描述)
#log4j.appender.WA.layout.ConversionPattern=%d{ISO8601} - [%X{ip}] -%5p %c{1}:%L - %m%n

2、config

package com.yy.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**
 * Created by yanyong on 2020/6/4.
 */

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

3、处理器

package com.yy.config;

import org.apache.log4j.Appender;
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
import org.apache.log4j.WriterAppender;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.Writer;
import java.net.InetAddress;

/**
 * Created by yanyong on 2020/6/5.
 */
@ServerEndpoint("/log")
@Component
public class LogSocketHandle {

    private PipedReader reader;
    private Writer writer;

    /**
     * WebSocket请求开启
     */
    @OnOpen
    public void onOpen(Session session) {
        Logger root = Logger.getRootLogger();
        try {
            // 获取本服务器id
            String hostAddress = InetAddress.getLocalHost().getHostAddress();
// MDC是key-value结构,有兴趣的可以去了解下,在log4j的配置中设置 %X{ip},在日志中输出
            MDC.put("ip",hostAddress);
            Appender appender = root.getAppender("WriterAppender");
// 通过管道流进行线程间的通讯
            reader = new PipedReader();
            writer = new PipedWriter( reader) ;
            ((WriterAppender) appender).setWriter(writer);
            // 启动新的线程
            LogThread thread = new LogThread(reader, session);
            thread.start();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /**
     * WebSocket请求关闭,关闭请求时调用此方法,关闭流
     */
    @OnClose
    public void onClose() {
        try {
            if(reader != null) {
                reader.close();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        try {
            if(writer != null) {
                writer.close();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    @OnError
    public void onError(Throwable thr) {
        thr.printStackTrace();
    }
}

4、线程

package com.yy.config;

import javax.websocket.Session;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PipedReader;

/**
 * Created by yanyong on 2020/6/5.
 */
public class LogThread extends Thread {
    private BufferedReader reader;
    private Session session;

    public LogThread(PipedReader pipedReader, Session session) {
        this.reader = new BufferedReader(pipedReader);
        this.session = session;

    }

    @Override
    public void run() {
        String line;
        try {
            while((line = reader.readLine()) != null) {
                // 将实时日志通过WebSocket发送给客户端
                session.getBasicRemote().sendText(line + "<br>");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

5、前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>日志</title>
</head>
<body>
<h1 style="text-align: center;">实时日志</h1>

<div id="log-container" contenteditable="true" class="content"
style="width: 100%;height: 500px;background-color: ghostwhite;overflow: auto;">
</div>
<div>
    <!-- 下面div用的是miniui的样式,其他的稍微改变一下即可-->
    <button style="left: 30px;top: 1px" onclick="clearContext()">清屏</button>
</div>
<script>
    var ws = new WebSocket("ws://127.0.0.1:8080/log");

    ws.onopen = function() {
        ws.send("Hello WebSockets!");
    };

    ws.onmessage = function(evt) {
        var content = document.getElementsByClassName('content')[0];
        console.log(evt.data);
        content.innerHTML += evt.data;
    };
    //关闭连接
    ws.onclose = function() {
        ws.close();
    };
    // 清屏日志
    function clearContext() {
        var content = document.getElementsByClassName('content')[0];
        content.innerHTML = null;
    }
</script>
</body>
</html>

6、github源码
源码下载

 类似资料: