用过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文件前面。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐