一、前言
作为程序员经常调侃的一句玩笑话是:“程序员是一种一边写BUG,一边寻找并解决BUG的生物”。会心一笑过后你会发现,代码开发者很重要的一部分工作就是排查代码在运行过程中出现的问题。通常开发者都是接到监控报警(如:cpu、load、memory等系统指标异常,业务成功率、异常错误等业务指标异常)后第一时间响应,并在尽可能短的时间内能够定位问题并完成止血动作。问题排查效率越高则业务面临的损失就会越小,而代码问题排查效率的高度由取决代码的可观测性。所以如何高效地观测运行时的代码并进行问题诊断是每个代码开发者与企业的追求的目标。今天我们来聊聊这个话题,并给出云效Codeup的最佳实践。
二、什么是代码可观测性
在线排查代码问题的效率为什么依赖代码的可观测性呢?代码的可观测性具体又指的是什么呢?首先我们先了解一下“可观测性”,该术语起源与控制理论,最常见的是在描述系统的可观测性。系统的可观测性是指通过系统输出的信息来评估系统当前运行状态的一种属性。它既可以是针对单体系统,又可以针对由多个单体系统组成的复杂的分布式系统。而代码可观测性则是将代码运行所在的整体环境抽象成一个系统,包括各种基础的软硬件设施、可执行的业务代码等。即通过硬件的负载指标、代码打印的日志数据来评估当前代码运行的状态,当问题发生时能够快速定位到底是哪个代码模块出了问题。
容器和微服务的流行,虽然从架构上降低了系统与系统之间、软件与硬件之间的耦合。但分布式部署、敏捷的代码变更却增加了代码运行时不可预测的风险和可观测的难度。可观测性是一种度量,如何实现代码可观测行也就是要找出度量的数据。一般主要使用三类数据:链路跟踪数据(Traces)、应用指标(Metrics)、业务日志(Logs)。其中Metrics这种指标是为了问题的快速发现,比如cpu/load/memory指标达到临界值后快速报警;Traces是发现问题后能够端到端的还原调用链路,以便快速定位问题可能出现问题的代码模块;Logs则是记录详细的业务上下文,包括发生的时间、地点和具体原因描述等文本信息。当系统出现问题时,通常首选是查看Logs数据,并开始分析具体原因。Logs虽然记录了比较详细的上下文信息,但单凭日志数据就可以精准判断原因的情况还是偏少的,一般还是要结合源代码进行分析。这就好比断案需要收集案发现场数据(即Logs),还需要审问嫌疑对象(即源代码),二者缺一不可。下面整理了几种快速“断案”的具体实践。
三、AppObserver实现动态观测
排查线上问题,有时我们会发现关键的位置缺少了日志,没法准确的获知代码运行情况,这会极大阻碍我们定位问题。缺少日志只能补上,再发布一次。对于大多数应用系统来说,发布一次的时间成本是不低的,从数分钟到数小时不等。除时间成本外,发布期间可能会因为服务不可用而影响到用户的正常使用。所以生产系统上发现了 Bug,找起来通常很不容易。云效Devstudion提供了应用观测器(App Observer)可以做到不发布系统的前提下动态添加日志、非阻塞式断点、实时统计Metrics指标等功能。
动态添加日志观测,App Observer可以让你在后悔当初忘记打印的时候不再只剩下后悔。它提供的动态添加日志功能可以让你一扫后悔的阴霾,随时添加、即时生效。同时还可以配合条件表达式控制日志的打印与否,在日志表达式中观测变量值等功能。整个过程中,动态日志不会改变原有的代码行数,不影响通过原日志系统排查问题。
非阻塞断点观测,App Observer提供的非阻塞断点在问题排查上,比动态日志跟进一步。最显著的增强点在于可以观测程序的执行堆栈,让程序的调用链路一目了然。此外,在观测变量值方面,可以一步到位,自动观测函数体内的所有变量。所有的观测行为,都不会阻塞程序的执行,真正做到了似断点又非断点。
实时 Metrics 用于辅助排查程序的性能问题,不需要添加非业务代码,在保持了程序逻辑清爽的同时,完成了统计观测:
- 计数器:用于统计某一行代码的执行次数;
- 方法执行耗时:用于统计函数体的执行耗时;
四、Codeup+SLS实现云端源码级观测
无论是传统排查服务器上打印的日志,还是上面介绍的通过AppObserver动态观测,最终都必须结合已下载到本地的源码进行分析定位问题。这个过程涉及到一个环节就是要把代码库克隆到本地的操作,对于一个非常熟悉代码库的开发者或许不是个问题,但是对一个运维或开发人员碰到一个他不是很熟悉的代码库时,他需要先确定日志数据是由哪个代码库的代码打印的,其次获取代码库权限并克隆代码到本地,最后阅读源码定位问题代码行,这本身就是一个效率低下的过程。云效代码托管平台(Codeup)联合阿里云日志服务工具(SLS)一起打通了日志到源码关联通道,在排查过程中无需关心日志与代码库的关联关系,无需临时申请代码库权限等阻碍排查过程的操作,为在线代码问题排查提供了一种面向云的高效最佳实践。这里涉及到两款工具,其中Codeup是代码托管工具,提供了代码源文件的存储与版本控制、代码文本检索等服务;SLS提供了海量日志数据的收集、存储、检索等服务。
首先通过SLS收集上报业务系统打印的日志数据。一旦生产环境出现问题并由监控系统发出报警,则开发或运维人员接到报警后第一时间到SLS控制台查询具体的日志详情。然后分析具体日志详情以及日志关联的源码,整个过程全部一体化,让问题处理的人员专注于问题本身,极大提高应急效率。工具使用操作如下所示:
- 配置日志库与代码库的关联关系,通过点击如下图所示的“查看源码”功能,可以进入配置页面。配置是一次性工作,生效后无需重复配置。
具体过程如下图2所示:
配置成功后会在高级选项里新增“代码诊断”入口。(入口名称可以自定义,此处中自定义为:代码诊断)
- 查看SLS日志详情,如需配合源码分析,则只需选择相应的代码文本即可,如下图所示
- 选择日志关键字,跳转Codeup查看源码
还可以跳转到Codeup平台看更详细的代码内容
五、结束语
云效代码平台致力为企业用户提供稳定、安全、高效的代码服务。围绕以代码数据为中心,面向研发过程总结最佳实践呈现给用户。本文提供了两种应用于在线排查代码问题的高效实践,分别应对单应用场景(对应单个代码库)的精细化分析和分布式应用场景(对应多个代码库)端到端的日志分析,实现一站式在线代码诊断。同时,也欢迎使用我们自研的代码智能补全插件Alibaba Cloud AI Coding Assistant(https://developer.aliyun.com/tool/cosy),助力高效开发。