最近做了一個檢視伺服器新增日志将日志實時顯示到前端頁面的功能,采用的websocket通信,由于項目比較複雜(web 和server進行連接配接,server 和多個節點建立連接配接,節點下有很多個伺服器,監聽的是這個伺服器檔案)我就不過多地介紹websocket的連接配接方式什麼的了,就介紹下實時監聽日志檔案的和關閉監聽
下面是我的日志檢視者類
package com.monitor.socket.handle;
import com.air.utils.SocketSessionUtil;
import com.alibaba.fastjson.JSONObject;
import javax.websocket.Session;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class LogWatcher {
//儲存已啟動定時檢視的類
public static ConcurrentHashMap<String,LogWatcher> logWatcherMap=new ConcurrentHashMap<>();
//編碼格式
public static final String ISO="ISO8859-1";
//上次檔案讀取的位置
private long lastTimeFileSize;
//是否為第一次讀取 第一次讀取讀取的是之前所有的日志,隻要新增的,不要之前的
private boolean first =true;
private RandomAccessFile randomFile =null;
//節點下的項目裡log檔案的相對路徑
private final String PATH = File.separator + "log" + File.separator + "sys" + File.separator + "SystemLog.log";
//啟動一個線程每1秒鐘讀取新增的日志資訊
private ScheduledExecutorService exec =
Executors.newScheduledThreadPool(1);
//啟動定時将新增的日志發送出去
public void realtimeShowLog(Session session, JSONObject jsonObject) throws IOException {
String projectPath= (String) jsonObject.get("projectPath");
File file=new File(projectPath+PATH);
//指定檔案可讀可寫
randomFile = new RandomAccessFile(file,"rw");
exec.scheduleWithFixedDelay(new Runnable(){
public void run() {
try {
//隻擷取新增部分的
if(first){
lastTimeFileSize=randomFile.length();
first=false;
return;
}
//沒有變化不發送
if(lastTimeFileSize==randomFile.length()){
return;
}
//日志檔案被替換了,從0開始讀取
if(lastTimeFileSize>randomFile.length()){
lastTimeFileSize=0;
}
randomFile.seek(lastTimeFileSize);
StringBuffer sbf = new StringBuffer();
String tmp = "";
while( (tmp = randomFile.readLine())!= null) {
sbf.append(new String(tmp.getBytes(ISO)));
sbf.append("\r\n");
}
System.err.println(sbf.toString());
jsonObject.put("content",sbf.toString());
lastTimeFileSize = randomFile.length();
SocketSessionUtil.send(session,jsonObject.toJSONString());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}, 0, 1, TimeUnit.SECONDS);
}
//停止定時任務
public void close() throws IOException {
if(randomFile!=null){
randomFile.close();
}
exec.shutdown();
}
}
SocketSessionUtil.send(session,jsonObject.toJSONString());Session是websocket發送資料不用太在乎我的,根據自己的情況去做處理
sbf.toString()就是我們每次擷取的新增的日志資料,我這裡設定的是一秒擷取一次
因為我的業務需求我是以token作為key,進行銷毀
logWatcherMap是協助我們對實時監控進行銷毀,同時也可以從裡面檢視有多少正在進行
這是啟動代碼:
LogWatcher logWatcher=new LogWatcher();
logWatcher.realtimeShowLog(session,object);
LogWatcher.logWatcherMap.put(token,logWatcher);
這是銷毀代碼
LogWatcher logWatcher=LogWatcher.logWatcherMap.get(token);
logWatcher.close();
LogWatcher.logWatcherMap.remove(token);
最後最重要的一點:
