1. 程式人生 > >jenkins報錯日誌顯示紅色

jenkins報錯日誌顯示紅色

用過jenkins的都知道,jenkins的日誌顯示都是黑色,沒有對錯誤或者成功日誌進行區別顯示。
如果程式碼的打斷機制沒有做得很好的話,很難發現是否有報錯資訊。在專案組被坑過多次之後,決定對jenkins的日誌顯示進行優化,讓錯誤日誌顯示紅色,成功日誌顯示綠色,方便執行任務的時候檢視。
最開始肯定是考慮外掛的方案了,找到一篇部落格https://www.jianshu.com/p/0ba349c3aae8使用AnsiColor外掛實現,研究了一下這個外掛的工作方式,發現需要在任務執行的日誌中增加顏色的顯示,就是外掛本身不會對關鍵字進行識別,只是把日誌裡面本身有顏色輸出的顯示到jenkins介面,這個實現方式需要對任務程式碼進行改造,工作量大,只適合用於新專案。
於是想能不能通過js,直接在頁面識別關鍵字,更改html樣式的方法來實現。首先得看一下這個日誌是怎麼拿到的,檢視一下獲取日誌的按鈕,發現是通過a標籤來發送請求的。
按鈕綁定了一個a標籤


找到這個就可以進一步處理了,給a標籤繫結一個點選事件,放回false就可以阻止a標籤的跳轉行為,同時拿到這個a標籤繫結的url,通過ajax訪問後臺,對返回的html資料進行處理,然後顯示在頁面。實現思路就是這樣。
然後找一個js來做這個事情,看一下偵錯程式的source裡面的靜態資源,找到一個hudson-behavior.js,說明這個頁面有載入過這個js,在jenkins部署目錄下的webapps/jenkins/scripts下找到這個檔案。在前面加入如下程式碼:

		//標紅的關鍵字,不區分大小寫
	var failWorlds=["error","fail","denied","cannot"];
	//標綠的關鍵字
	var successWorlds=["SUCCESS"];
	
	//增加頁面載入完成後執行事件
	function addLoadEvent(func){
		var oldonload = window.onload;

		if (typeof window.onload != 'function') {
			window.onload = func;
		} else {
			window.onload = function(e) {
				oldonload(e);
				func(e);
			}
		}
	}
	
	//頁面載入完繫結點選事件
	addLoadEvent(function(){
		var historyA = document.querySelectorAll('.build-status-link');
		for(var i=0;i<historyA.length;i++){
			historyA[i].onclick=function addRedForErrMessage(){
				var url = this.getAttribute("href");
				//呼叫jenkins寫好的ajax方法
				new Ajax.Request(url, {
					onSuccess:function(rspHtml){
							var rspHtmlhtml = document.createElement('html');
							rspHtmlhtml.innerHTML=rspHtml.responseText;
							//獲取到日誌區域的內容
							var log_text = rspHtmlhtml.getElementsByTagName("pre")[0].innerHTML;
							var changed_log_text = changeToRed(log_text);
							rspHtmlhtml.getElementsByTagName("pre")[0].innerHTML=changed_log_text;
							//將變更後的html內容寫入到當前頁面
							document.getElementsByTagName("html")[0].innerHTML=rspHtmlhtml.innerHTML;
					}
				});
				return false;
			};
		}
		});
	
	//根據關鍵字陣列對更改關鍵字顯示樣式
	function changeToRed(log_text){
		
		for(var i=0;i<failWorlds.length;i++){
			var failworld = failWorlds[i];
			var regworld = "/"+failworld+"/gi";
			var log_text = log_text.replace(eval(regworld),'<span style="color:red">'+failworld+'</span>');
		}
		
		for(var i=0;i<successWorlds.length;i++){
			var successWorld = successWorlds[i];
			var regworld = "/"+successWorld+"/gi";
			var log_text = log_text.replace(eval(regworld),'<span style="color:green">'+successWorld+'</span>');
		}
		return log_text;
	}

這裡有一點需要注意的,頁面載入事件不能直接使用window.onload進行繫結,因為一個html頁面只能有一個這種操作,直接繫結會影響jenkins本身的一些繫結操作。addLoadEvent這個方法也是在scripts目錄下的behavior.js中找到的。
更改完成儲存,重新整理一下瀏覽器快取就可以實現功能了,效果圖如下:
實現後的效果圖
唯一的問題是在任務構建中,日誌還在生成的時候這個沒有生效,只有任務跑完才有效果。對於專案組,到這裡已經夠用了。有興趣的可以再研究一下,因為這個時候前臺獲取日誌的請求方式不一樣,需要找到相應請求然後對返回資料作相同處理。
jenkins重啟後這個會失效,有兩個辦法,一個是把jenkinswar包裡面對應的hudson-behavior.js檔案也改了,放在wenbapps下面。一個是備份hudson-behavior.js檔案,每次重啟後手動替換這個檔案。
jenkins升級後不要直接替換這個檔案,將上面程式碼複製到升級後的hudson-behavior.js檔案前面。