如何實現類似「jenkins」的滾動日誌功能?
- 2019 年 10 月 6 日
- 筆記
本文實現了一個類似jenkins滾動日誌的小功能,如果你正在做發佈系統類似的東西,這個功能會非常有用。
滾動日誌
jenkins的日誌能夠滾動顯示,關閉後重新進入依然能夠繼續滾動,非常棒。做這種效果,直接想到的有兩種方式: 1) Websocket 2) 輪詢獲取
可是我太笨了,websocket
代碼對我來說有點複雜。另外我還沒想清楚如果關了日誌窗口重新進入,ws
會有什麼樣的反應。所以我們還是輪詢吧。
通過chrome的Inspect
功能去偷窺jenkins
。可以看到,每隔1秒鐘會發送一次請求到服務器,進行增量日誌的獲取。傳入的參數只有一個,就是文件偏移量。

我覺得我們可能想一塊兒去了。
整個過程還是比較簡單的,下面簡短的描述下,並附上最主要功能的代碼塊。
服務端
開啟一個新的線程執行構建
過程如下:

兩點說明: 1) 終止條件成功的判斷需要進行約定。比如,讀到」BUILD-OK」字樣,證明Build成功 2) 服務可能異常終止。所以需要有定時清理進程,去更新長時間沒有相應的線程狀態 3) 通過添加一個內存Map
,可以很容易實現正在執行的JOB
功能
根據提供的偏移量讀取文件內容
String logPath = "tmp.log"; BufferedReader reader = new BufferedReader( new FileReader(new File(logPath)));/* 跳過已經讀取過的日誌 */long realSkip = reader.skip(start);/* 從跳過的地址開始讀取下面的日誌 */String line; StringBuilder sb = new StringBuilder();while ((line = reader.readLine()) != null) { sb.append(line); sb.append("n"); /* 將讀取的長度追加到變量中 */ realSkip +=sb.length(); } reader.close();/* 查詢build的狀態,用來給前端滾動日誌一個截止狀態 */int status = this.queryBuildStatus(buildId);/* 返回三個值 1)本次讀取的內容 2)下次讀取的偏移量 3)項目狀態 */return new ChunkLog(sb.toString(),realSkip ,status);
本段代碼試圖通過傳入的文件偏移量,讀取當前文件剩餘的內容返回給用戶。如果文件持續寫入,通過不斷的輪詢,就可以達到滾動日誌的效果。 不多說,看注釋即可。
前端
設置幾個全局變量
//起始便宜量 var Start = 0 //輪詢 var timer = null
主要的輪詢接口
id為log的<pre>
標籤,用來接收、顯示日誌。
function appendData(hash) { $.ajax({ url: '/chunk/' + hash + '/' + Start, type: 'GET', dataType: 'json', success: function(res) { var log = res.log; $("#log").append(log) Start = res.start End = res.end if (End) { if(typeof timer !== 'undefined' ){ clearInterval(timer) } } } })}
按鈕觸發事件
//重置$("#log").html("") Start = 0; timer = setInterval(function() { appendData(hash) },1000);
當點擊查看日誌時,觸發此函數,就可以隨時隨地看到最新的滾動日誌了。