如何實現類似「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);

當點擊查看日誌時,觸發此函數,就可以隨時隨地看到最新的滾動日誌了。