java将tomcat的日志显示在web端
后台代码
public class SocketManager{
// 用来记录当前在线链接数
private static volatile int onlineCount = 0;
// 标记文件已读行数
private static volatile long lines = 0L;
// 判断是不是第一次加载
private static volatile boolean isFirstRunning = true;
// concurrent包的线程安全Set,用来存放每一个客户端对应的MyWebSocket对象
// 若要实现服务端与单一客户端通讯的话,能够使用Map来存放,其中Key能够为用户标识
public static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
// 开启监听
public static synchronized void startListening(String rootDir) {
File file = new File(rootDir+java.io.File.separator+"catalina.out");
if(file.exists()){
int lineNumber = getLineNumber(file);
System.out.println("Total number of lines : " + lineNumber);
List<String> readLines = readLastLine(file,3000);
for(int i=readLines.size()-1;i>=0;i--){
sendMsgToAll(readLines.get(i));
}
if(lineNumber>=3000){
lines = lineNumber-3000;
}
}
if (!isFirstRunning) {
System.err.println("监听服务已经启动!");
return;
}
// 监控目录
// 轮询间隔 1 秒
long interval = TimeUnit.SECONDS.toMillis(1);
// 建立一个文件观察器用于处理文件的格式
FileAlterationObserver observer = new FileAlterationObserver(
rootDir,
FileFilterUtils.and(
FileFilterUtils.fileFileFilter(),
FileFilterUtils.suffixFileFilter(".out"),
FileFilterUtils.prefixFileFilter("catalina")), //过滤文件格式
null);
observer.addListener(new LogListener());
// 建立文件变化监听器
FileAlterationMonitor monitor = new FileAlterationMonitor(interval, observer);
// 开始监控
try {
monitor.start();
isFirstRunning = false;
} catch (Exception e) {
e.printStackTrace();
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
onlineCount++;
}
public static synchronized void subOnlineCount() {
onlineCount--;
}
private static class LogListener extends FileAlterationListenerAdaptor {
@Override
public void onFileChange(File file) {
BufferedReader br;
try {
InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
br = new BufferedReader(isr);
if (br.ready()) {
lines += br.lines()
.skip(lines <= 0L ? 0L : lines)
.peek(LogListener::sendMsgToAll)
.count();
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static void sendMsgToAll(String msg) {
webSocketSet.forEach(item -> {
try {
item.getSession().getBasicRemote().sendText(msg);
} catch (IOException ex) {
ex.printStackTrace();
}
});
}
}
//发送消息
private static void sendMsgToAll(String msg) {
webSocketSet.forEach(item -> {
try {
item.getSession().getBasicRemote().sendText(msg);
} catch (IOException ex) {
ex.printStackTrace();
}
});
}
//从最后一行开始读取日志
private static List<String> readLastLine(File file, int numLastLineToRead) {
List<String> result = new ArrayList<String>();
try (ReversedLinesFileReader reader = new ReversedLinesFileReader(file)) {
String line = "";
while ((line = reader.readLine()) != null && result.size() < numLastLineToRead) {
result.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
//获取日志的行数
private static int getLineNumber(File file) {
int lineNumber = 0;
try {
long fileLength = file.length();
LineNumberReader lineNumberReader = new LineNumberReader(new FileReader(file));
lineNumberReader.skip(fileLength);
lineNumber = lineNumberReader.getLineNumber();
lineNumberReader.close();
}catch (IOException ex) {
ex.printStackTrace();
}
return lineNumber;
}
@ServerEndpoint("/webSocket")
public class MyWebSocket{
// 与某个客户端的链接会话,须要经过它来给客户端发送数据
private Session session;
public MyWebSocket() {
String classesPath = this.getClass().getResource("/").getPath();
String logRootPath = new java.io.File(classesPath)
.getParentFile().getParentFile().getParentFile().getParentFile()
.getPath() + java.io.File.separator + "logs";
System.out.println(logRootPath);
SocketManager.startListening(logRootPath);
}
public Session getSession() {
return session;
}
/** * 链接创建成功调用的方法 * @param session 可选的参数。session为与某个客户端的链接会话,须要经过它来给客户端发送数据 */
@OnOpen
public void onOpen(Session session) {
this.session = session;
SocketManager.webSocketSet.add(this); // 加入set中
SocketManager.addOnlineCount(); // 在线数加1
System.out.println("有新链接加入!当前在线人数为" + SocketManager.getOnlineCount());
}
/** * 链接关闭调用的方法 */
@OnClose
public void onClose() {
SocketManager.webSocketSet.remove(this); // 从set中删除
SocketManager.subOnlineCount(); // 在线数减1
System.out.println("有一链接关闭!当前在线人数为" + SocketManager.getOnlineCount());
}
/** * 收到客户端消息后调用的方法 * @param message 客户端发送过来的消息 * @param session 可选的参数 */
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("来自客户端" + session.getId() + "的消息:" + message);
}
/** * 发生错误时调用 */
@OnError
public void onError(Session session, Throwable error) {
System.out.println("onError");
System.out.println(session.getId() + "发生错误");
error.printStackTrace();
}
前台代码:
<!DOCTYPE html>
<html>
<head>
<title>catalina.out</title>
<meta charset="UTF-8">
<style type="text/css"> html, body { background: #000; margin: 0; padding: 0; } #message { color: #0F0; font-size: 12px; padding: 3px; } </style>
</head>
<body>
<div id="message"></div>
</body>
<script type="text/javascript">
function getWebsocketUrlPrefix(){
var domainPort = window.location.host;
var url = window.location.pathname;
var webApp = url.split('/')[1];
var urlPrefix = "";
if (webApp == "pages") {
urlPrefix = domainPort;
} else {
urlPrefix = domainPort + "/" + webApp
}
return urlPrefix;
}
var websocket = null;
// 判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
var webSocketUrl = getWebsocketUrlPrefix();
websocket = new WebSocket('ws://'+webSocketUrl+'/webSocket');
} else {
alert('当前浏览器不支持WebSocket')
}
// 链接发生错误的回调方法
websocket.onerror = function () {
setMessageInnerHTML("WebSocket链接发生错误");
};
// 链接成功创建的回调方法
websocket.onopen = function () {
setMessageInnerHTML("WebSocket链接成功");
}
// 接收到消息的回调方法
websocket.onmessage = function (event) {
setMessageInnerHTML(event.data);
}
// 链接关闭的回调方法
websocket.onclose = function () {
setMessageInnerHTML("WebSocket链接关闭");
}
// 监听窗口关闭事件,当窗口关闭时,主动去关闭websocket链接,防止链接还没断开就关闭窗口,server端会抛异常。
window.onbeforeunload = function () {
closeWebSocket();
}
// 将消息显示在网页上
function setMessageInnerHTML(text) {
document.getElementById('message').innerText += text ;
document.getElementById('message').innerHTML += '<br/>'
}
// 关闭WebSocket链接
function closeWebSocket() {
websocket.close();
}
</script>
</html>
浙公网安备 33010602011771号