log4j输出⽇志到前端页⾯⼀、简介
有些时候webapp有需求将⽇志输出到前台页⾯,便于开发者查看⽇志,本篇将介绍如何将⽇志输出到前台显⽰;⼆、准备
WebSocket技术、log4j、miniui(本项⽬所⽤前端,其他也⼀样);
三、参考⽂档
受到此博主的启发,特感谢此博主:
四、过程
1、log4j配置
# 选⽤WriterAppender作为Appender,表⽰以流的形式输出,这个Appender⼀般很少⽤,是常⽤Appender的⽗类
log4j.appender.WA=org.apache.log4j.WriterAppender
log4j.appender.WA.Threshold=debug
log4j.appender.WA.layout=org.apache.log4j.PatternLayout
# %X{ip} 输出本服务器的ip,通过MDC输⼊(见后⾯描述)
log4j.appender.WA.layout.ConversionPattern=%d{ISO8601} - [%X{ip}] -%5p %c{1}:%L - %m%n
2、WebSocket后台编写
import java.io.PipedReader;
import java.io.PipedWriter;
import java.io.Writer;
import java.InetAddress;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.apache.log4j.Appender;
import org.apache.log4j.Logger;
import org.apache.log4j.MDC;
import org.apache.log4j.WriterAppender;
/**
* @Author : ycj
* @Description : ⽇志⽂件处理websocket服务
* @CreateDate : 2018/6/12 9:42
*/
@ServerEndpoint("/log")
public class LogWebsocketHandle {
private PipedReader reader;
private Writer writer;
/**
* WebSocket请求开启
*/前端websocket怎么用
@OnOpen
public void onOpen(Session session) {
Logger root = RootLogger();
try {
// 获取本服务器id
String hostAddress = LocalHost().getHostAddress();
// MDC是key-value结构,有兴趣的可以去了解下,在log4j的配置中设置 %X{ip},在⽇志中输出
MDC.put("ip",hostAddress);
Appender appender = Appender("WA");
// 通过管道流进⾏线程间的通讯
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();
}
LogThread 线程
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PipedReader;
import javax.websocket.Session;
/**
* 新线程
*/
public class LogThread extends Thread {
private BufferedReader reader;
private Session session;
public LogThread(PipedReader pipedReader, Session session) {
this.session = session;
}
@Override
public void run() {
String line;
try {
while((line = adLine()) != null) {
// 将实时⽇志通过WebSocket发送给客户端
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
2、前端编写
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>tail log</title>
<!-- 此boot.js不需要-->
<script src="../../boot.js"></script>
<script src="../../js/jquery-1.6.2.min.js"></script>
</head>
<body>
<div id="log-container" >
<div>
</div>
</div>
<div>
<!-- 下⾯div⽤的是miniui的样式,其他的稍微改变⼀下即可-->
<div id="ck1" name="product" class="mini-checkbox" checked = "true" readOnly="false" text="是否滚动" onvaluechanged="onValueChanged" ></div>
<a class="mini-button mini-button-info"
onclick="clearContext()">清屏</a>
</div>
</body>
<script>
// 控制是否滚动显⽰⽇志
var checked = true;
function onValueChanged(e) {
checked = Checked();
}
$(document).ready(function() {
// 指定websocket路径,此地址建议根据⽤js动态获取
var websocket = new WebSocket('ws://localhost:8080/log');
// 接收服务端的实时⽇志并添加到HTML页⾯中(error显⽰红⾊)
if (event.data.search("ERROR") != -1) {
$("#log-container div").append(event.data).css("color", "#AA0000");
} else {
$("#log-container div").append(event.data).css("color", "#aaa");
}
// 是否滚动
if (checked) {
// 滚动条滚动到最低部
$("#log-container").scrollTop($("#log-container div").height() - $("#log-container").height());
}
};
});
// 清屏⽇志
function clearContext() {
$("#log-container div").empty();
}
</script>
</body>
</html>
3、js获取项⽬路径代码(供参考)
// 此⽅式获取的bootPath项⽬根路径放⼊WebSocket路径需要进⾏截取
JsPath = function (js) {
var scripts = ElementsByTagName("script");
var path = "";
for (var i = 0, l = scripts.length; i < l; i++) {
var src = scripts[i].src;
if (src.indexOf(js) != -1) {
var ss = src.split(js);
path = ss[0];
break;
}
var href = location.href;
href = href.split("#")[0];
href = href.split("?")[0];
var ss = href.split("/");
ss.length = ss.length - 1;
href = ss.join("/");
if (path.indexOf("https:") == -1 && path.indexOf("http:") == -1 && path.indexOf("file:") == -1 && path.indexOf("\/") != 0) { path = href + "/" + path;
}
return path;
}
var bootPATH = JsPath("boot.js");
4、成果展⽰
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论