基于Sonar的代码质量检测技术研究
2019-07-16蔡建军任女尔魏金津
蔡建军 任女尔 魏金津
摘要:随着数据中心软件业务的快速发展,给质量控制带来极大的挑战。采用Sonar检测代码质量并开发扩展插件,按项目和人员两个维度统计代码质量情况,并集成Metrics,Druid以检测代码执行时的逻辑调用情况。通过建立好的评价体系,可以很好地提升内部软件代码质量管理的水平,加强对软件代码质量的在软件开发各个阶段的掌控。
关键词:Sonar;Metrics;Druid
中图分类号:TP311 文献标识码:A
文章编号:1009-3044(2019)14-0195-05
1 概述
数据资源中心软件业务的快速发展,带来了软件框架异构多样、软件资产复用率低的问题,更有代码质量参差不齐等带来的一系列软件可读性和维护性问题,传统的依靠人力的代码质量检测工作已经难以为继。所以需要构建一套自动化,完整高效的代码质量评价体系,将开发人员的工作质量进行量化和评级,用以提高软件项目开发过程中的代码质量和软件部署之后的可维护性。
从软件工程方法学进行统筹思考,着眼于软件工程中对于软件代码质量评价的几个重要指标:代码漏洞、BUG、坏味道、SQL语句平均执行时间、函数平均调用时间等,结合Sonar的代码质量统计功能,对Sonar插件进行扩展开发,按项目、人员两个维度统计代码质量增量情况,集成Metrics与Druid以检测代码运行时的调用逻辑,作为评价代码质量的重要指标之一。
依托于成熟的Sonar软件质量监测系统,构建一套科学的可量化的评价体系,从而达到减少人工工作,提升内部软件代码质量管理的水平,加强对软件代码质量的在软件开发各个阶段的掌控,对于科学管理软件资产,进一步提升软件复用率具有非常重要的意义。
2 基于Sonar衡量代码质量
1)Sonar介绍
软件行业内常将Sonar作为技术债务【1】管控的主流工具。Sonar是一个开源的代码质量分析平台,能够管理代码的质量,通过扫描代码,可以检测到代码的漏洞和潜在的编码层次的逻辑问题【2】。
Sonar的插件机制可以集成不同的工具,如代码分析、持续集成,我们还可以开发插件对检测结果进行再加工处理。
2)Jenkins集成Sonar
持续集成(CI)是个简单重复劳动,由人来操作费时费力,使用自动化集成技术能够节约大量的人力。将持续集成Jenkins与代码自动扫描集成【3】,能够自动对代码进行持续的代码规范扫描,并输出扫描结果。即使代码进行更改,持续集成技术也能够自动触发Sonar进行扫描,这对开发人员进行代码漏洞及规范扫描的帮助作用是非常明显的。
3)衡量代码质量的意义
代码质量,是衡量系统质量的重要指标。基于Sonar的扫描功能,构建一套软件代码质量评价体系,定期对系统内的项目进行统计分析,有利于及早发现问题,更好地掌控软件开发过程,做到问题早发现早解决,避免问题滞后导致的技术债务越滚越多的恶性循环,有利于提高代码质量监管能力,节约代码质量管理人力,提升整体的代码质量水准。
3 软件开发质量统计机制
1)基于Sonar的代码质量检测体系
借助于Sonar所支持的代碼质量检测机制,能够检测出项目中存在的一些问题,包括但不限于:可能存在的漏洞、安全问题、代码坏味道等。
这些统计数据可以非常直观地表现出一个工程的代码质量好坏,可以作为统计代码质量的量化指标。通过这些代码中发现的代码质量问题,我们不仅可以避免工程交付后,运行过程中出现致命性的问题,而且可以提高软件开发人员的工作规范,避免在日后的开发工作中再次出现类似的问题。
Sonar在6+的版本上增加了对“作者”的支持。作者的概念是:在版本控制系统中(如SVN,Git),某个文件的最后一次提交者即是当前文件的作者。
在Sonar中,检测出来的代码问题分为以下几种:1、提示级;2、次要级;3、主要级;4、严重级;5、阻断级。其严重程度依次递增,提示级对代码的整体运行几乎没有任何影响,而阻断级可能会产生各种严重的影响,甚至影响系统运行的稳定性和安全性。因此,越是高级的问题将会带来更大的威胁,也就意味着代码的质量越差,系统越不完善。
在有了作者这个概念之后,使对每一位参与开发的开发者进行各自的代码质量统计以及工作量统计成了可能。Sonar会记录当前项目下每一位作者的所有问题数量。对每一位参与开发的开发者,通过判断他所编写的代码中所包含的代码质量问题(Bug、漏洞、坏味道等),构建一个合理的评价体系,对每位开发者的代码质量进行评分。可以作为评估该开发者开发质量的一个重要指标。
2)Sonar登录验证
在Sonar提供的完备的代码质量统计结果的前提下,以代码质量统计体系标准为原则,构建代码统计质量对比体系。考虑到代码迭代周期,决定以月度为最小比较单位,上设季度对比。
Sonar对外提供了一些必要的接口,比如获取一个项目的issue数量,代码行数统计等基本信息,但是Sonar并不提供历史扫描信息,只是管理每个issue的状态变化信息。所以想要直接通过Sonar的接口获取到我们希望得到的对比统计数据是不可能的。
在调研了Sonar的接口之后,决定采用定时任务的方式,将当天最新的Sonar扫描结果进行保存,并记录保存的日期,以此作为按照周期进行统计的基础。
首先,通过Sonar提供的登录接口“api/authentication/login”进行Sonar后台的登录,此处为了保证能够获取到所有Sonar中的项目,应该以管理员权限登录,或者使用至少对所有项目具有可见权限的帐号进行后续操作。这一步的登录操作是为了获取授权Token,是后面所有获取统计数据的基础。
3)按照项目进行对比-代码问题
在Sonar中,每个被检测的项目有其唯一的、可由用户指定的ProjectKey来进行标识。这个项目扫描后的各项结果,均可以通过这个ProjectKey以及对应的接口进行获取。
这里根据上述的代码质量统计体系,重点关注上图中红线框出来的部分。这部分Sonar的接口因为集成了太多功能,所以仅仅列出本系统所使用的部分接口文档:
通过调用Sonar接口“api/issues”,可以获得各个等级的issue数量,接口返回的示例如下:
之后,将获得的这些数据,保存到数据库中,作为当天的扫描结果,用于后面按照固定周期的比对工作。
4)按照项目进行对比-代码问题
Sonar系统中保存了代码行数的相关度量,包括代码总行数,有效代码行数,注释行数和注释率等,如下图所示:
Sonar也提供了获取代码行数度量的接口,但是根据需求,需要收集后台(JAVA语言)的代码行数和全部的度量。全部的度量上图即可获得,但是JAVA语言的代码并不能直接通过接口获得。获取全部代码行数度量的接口是“api/measures”,通过这个接口可以获取到代码行数扫描的历史记录,我们取最近一条的检测记录并保存到数据库中。用于后面生成各项统计数据。下面是示例返回:
从上面接口的返回值可以看出,Sonar确实不会分别统计后台(JAVA)代码行数和全部的代码行数。我们在调研了Sonar的接口之后,发现了可以分文件来统计代码,下面是系统中使用到的接口描述:
使用这个接口返回的数据是一个大的文件扫描结果列表,列表中每一个节点中存储的数据都是一些可被自定义的度量,在这个功能模块中,我们通过它来获取这个文件中的代码(如果是代码文件的话)是由什么语言编写的,以及这个文件的代码行数相关度量,主要是总代码行数,有效代码行数,注释行数这三个值,根据文件中代码的编程语言判断是否是JAVA语言,如果是,则分别统计上面三个值的和,最后通过这三个值来计算代码注释率。
API接口返回的数据示例如下(一个节点):
5)按照作者进行对比-代码问题
这个部分和上述的代码行数统计部分十分类似。它们都具有共同的现状:Sonar本身不对作者产生的issue进行统计。而且根据需求,系统需要统计某个作者在所有他参与的项目中所编写的代码质量。Sonar的作者的概念是建立在项目这个基础上的,涉及跨项目的作者,Sonar本身并不支持,所以这里需要有一个前提:
Sonar所检测的项目所处的SCM管理系统为统一平台,即每个作者在这个SCM平台下有且仅有唯一的ID(用户名)与之对应。
在这个前提下,可以通过用户名将同一个作者不同项目下的代码问题连接到一起,是统计个人代码质量的基础。
通过对Sonar接口的调研,Sonar统计某个作者的问题是在项目中才有统计的,但是通过上述的前提条件,保证了作者名的唯一性,那么就可以通过扫描所有Sonar项目中的作者以及他们的各个等级的问题的数量,然后通过他们的作者名进行组织,统计出一个同一个作者名下,所有他参与的项目的代码质量问题统计评价。
获取所有Sonar扫描的项目的ProjectKey的接口是“api/components”,通過这个接口,不需要传入任何参数即可得到所有Sonar扫描过的ProjectKey,接口返回数据示例如下:
根据获取到的所有ProjectKey,分别去该项目下按照issue列表来统计issue所在文件的作者,issue的等级,作为该作者在该项目下的统计数量,并对作者列表中有该作者的项目所统计出的issue数量进行合并,作为该作者所有项目的issue数量统计。返回结果示例:
图中三个箭头分别指向了issue的等级,所属的项目和作者名,根据这些信息,不断迭代所有项目的所有issue,可以统计出作者的issue数量和等级。将这些数据保存在数据库中,用作后面的周期性统计使用。
6)代码质量按周期统计
在经过上面的流程,数据库中每天应该存有以下数据:每个Sonar中扫描的项目的各个等级的issue的数量、评分和评级;每个作者所有的各个等级的issue数量、评分和评级。根据需求,需要对月度信息和季度信息进行统计,包括同比和环比。
选择的依据是:选择月度信息时,按照时间区间从当月1号0点0分开始,到下月1号0点0分为止的时间段内,按照扫描时间(日期)进行降序排列,以排序后,第一条记录为基准进行同比,环比比较。季度信息同上。
7)代码质量统计模块的使用与导出
首先需要成功部署Sonar插件以及Vue前端。从Sonar主页进入需要查看代码质量的项目主页,在“More”(更多)下拉菜单中,选择“项目监控信息展示”:
倒计时过后,会跳转到各项信息展示的页面:
默认显示第一个标签页,标题为“代码质量统计”,该标签页显示的是代码质量问题合计,主要是各个级别的问题数量统计。
该标签页下方显示的是代码行数检测结果,显示了项目总行数,注释代码行数,有效代码行数,注释率等指标。
进入第二个标签页,会显示代码质量历史对比信息:
在这个页面中,首先展示出来的是该项目的按照月度和季度的对比信息,分别展示了本月最后一条记录、和上月对比的环比记录以及和去年本月对比的同比记录。按照季度对比也是同样,展示了环比和同比的记录。
在页面下部,展示的是该项目下,每个作者的issue数量统计以及对比结果:
分别展示了该项目下,每个作者的当前月(季度)issue数量和评级评分信息,以及同比和环比数据。
在统计结果导出的部分,由于考虑到权限的设置,将入口设置在了Administration的页面中,只有通过admin帐号登录才能看到入口:
单击统计结果导出,在倒计时结束之后即可自动开始下载数据导出表格。数据导出表格示例如下:
Excel表格文件中有多个表单(Sheet),从左到右分别展示的是:所有项目按照月度进行统计对比的结果,所有项目按照季度进行统计对比的结果,每个项目每个作者的issue数量按照月度进行统计对比的结果,每个项目每个作者issue数量按照季度进行统计对比的结果,每位作者所有项目按照月度进行统计对比的结果以及每位作者所有项目按照季度进行统计对比的结果。
4基于Metrics与Druid分析代码执行效率
Metrics【4】和Druid【5】作为项目运行时的监控工具,将之集成进Sonar插件,与Sonar统计出来的各项代码质量问题一起,作为评价代码质量的重要指标之一。
4.1 基于Metrics分析代码执行效率
1)什么是Metrics
Metrics可以监控和统计系统或服务运行时的物理性能(CPU,内存,IO等资源占用率)以及业务性能(每秒请求数,平均请求响应时间等)。Java有很多流行的库,可以在系统中集成并监控。
2)Metrics分析
进行Metrics分析的前提是需要有检测结果的csv文件供分析,所以为了将Metrics分析功能和Sonar进行结合,需要通过脚本转移Metrics监测结果文件到指定的文件夹下。
3)Metrics显示结果
Metrics使用“projectKey”来作为项目的唯一标识,“projectKey”对应的是sonarqube中唯一标识每个项目的主键。通过代码质量检测页面的Metrics统计子页面可以看到检测的结果,数据表左侧显示的时执行业务逻辑的方法名称,以及方法所在的路径。右侧mean time是方法的平均执行时间, 最后是对这个方法执行效率的评分。
4.2 基于Druid分析代码执行效率
阿里巴巴开源的Druid数据库连接池,可以很好地监控数据库连接池连接和SQL的执行情况,对于打开监控统计功能的项目,我们也可以通过Sonar插件集成Druid的Sql执行效率分析功能。
Druid的配置项保存在数据库表当中,每个“projectKey”对应的“druidURL”是运行中的druid项目的监控后台地址,需要通过其接口获取各种数据并统计。我们只需在页面配置每个项目的druidURL字段里指定具体的url信息即可。进入Druid的统计页面如图所示,数据表左侧指明执行的SQL语句,并有SQL执行次数,执行总时间,平均时间以及对每条SQL做的评分。
5 总结
Sonar是技术债务管控的主流工具,可以检测代码质量问题,开发Sonar插件可以扩展检测功能,按项目和人员维度统计代码质量包括增量情况,集成Metrics与Druid可以检测代码运行时逻辑。建立科学的可量化的评价体系,可以提升内部软件代码质量管理的水平,加强对软件代码质量的在软件开发各个阶段的掌控。
参考文献
[1] 刘亚珺,李兵,李增扬,等.软件集成开发环境的技术债务管理研究[J].计算机科学,2017,44(11):15-21.
[2] 肖汉.一种基于UML的Java類复杂性度量方法[J].计算机应用研究,2007(7).
[3] 赵晨煜.基于大数据技术的O2O电商用户数据挖掘探讨[J].中国战略新兴产业,2018(12).
【通联编辑:朱宝贵】