标题党了点,不过大体逻辑就是如此。可观测性是软件的一个特性,和可用性、可靠性类似,每个软件工程师都应该关注,尤其是你需要自证清白的时候。
核心要点
- 可观测性不是运维团队独有的工作,而是软件工程的一部分。
- 研发写日志、暴露指标、接入链路追踪,本质上是在生产可观测性数据。
- 微服务架构下,只有单点日志不够,需要指标和链路追踪补充全局视角。
- 优秀的基础设施软件通常都会对外暴露运行状态,方便用户排查问题。
- 埋点和插桩应该像测试、可读代码、防卫判断一样,成为工程实践的一部分。
缘起
今天早上偶尔刷到一篇文章,是 Honeycomb 公司的工程师写的,深有同感,原文地址如下:
https://www.honeycomb.io/blog/observability-every-engineers-job-not-just-ops-problem
我把文章中的一些重要观点摘过来,也结合我自己的理解,做一些补充,和大家做一个探讨。
什么是可观测性
可观测性,顾名思义,指的是系统状态能够被观察与度量的特性。在 IT 领域,可观测性通常被理解为:根据系统生成的输出数据,例如日志、指标、链路追踪等,来测量和理解系统当前状态的能力。
Opentelemetry 网站对可观测性给出了深刻的阐述:可观测性赋予我们从外部视角洞察系统的能力,使我们能够在不了解系统内部工作机制的前提下,对系统提出疑问并寻求答案。它进一步使我们能够轻松应对新出现的问题(即“未知的未知”),并帮助我们深入探究“为何会发生这种情况”。向系统提出问题,本质上意味着我们具备收集系统执行与行为信息,并从中获取洞见的能力。
我们在软件架构设计时,经常会提到可用性、可靠性,随着微服务的发展,可观测性,也应该成为一个重要的设计方面。
从 printf 到可观测性
每个研发人员都熟悉“print 大法”。开发过程中,我们经常会在代码中加打印语句,帮助调试和排查问题。printf 可以看作最简单的观测工具。
随着时代发展,printf 逐渐被 logger 取代,logger 又逐渐演变成结构化日志。结构化日志可以看作可观测性的第一步。
姑且不论日志实践做得好不好,研发人员至少不会拒绝打印日志。从可观测性角度看,研发打印日志,就是在生产可观测性数据。之后谁来用?研发人员自己和运维人员都会用。
除了日志,研发还应该生产其他类型的观测数据,尤其是在需要自证清白的时候。
现实中,很多公司都是只有运维人员在推动可观测性的落地,研发人员爱答不理,甚至是抵制的态度。真的是不可理喻。
随着微服务发展,多个服务之间的调用关系越来越复杂,普通日志无法串联整个请求链路,于是就有了链路追踪,链路追踪姑且可以看做是串联各个服务调用的结构化日志。
虽然日志顺手即来,但日志通常是面向“点”的。我们很难只靠日志获取全局视角的信息,比如各个接口的成功率、延迟,整个服务的成功率、延迟等。此时就需要指标上场。
原文提到,Google 要求服务暴露 /varz 接口来展示服务指标数据。这个例子说明,指标不是运维人员事后强加的负担,而是服务本身应该对外暴露的运行状态。
为什么可观测性是研发职责?
研发最了解代码逻辑、业务分支和异常路径。如果埋点完全交给运维,运维只能从系统外部推测,很难知道哪些日志字段关键、哪些异常分支应该暴露、哪些业务状态需要指标化。
研发至少应该关注四类输出:
- 日志:关键事件、错误上下文、请求 ID、用户或租户维度、异常栈。
- 指标:请求量、成功率、错误率、延迟、队列长度、业务关键计数。
- 链路追踪:跨服务调用路径、Span 名称、重要标签和错误状态。
- 状态和事件:健康检查、版本信息、依赖状态、发布和配置变更。
这些数据不是给平台“凑数”的,而是给未来排障时的自己和同事留下线索。
优秀的软件都具备可观测性
业务研发领域不好举例,我们可以拿开源基础设施软件来举例,比如 Linux、Kubernetes、MySQL、Redis、Kafka,你能想到的优秀的开源软件,都会对外暴露观测数据。虽然大家暴露方式不同,但是理念是一样的,都是想方设法让用户能看到系统的运行状态,帮助用户排查问题。
软件工程的几个最佳实践
我们认为软件工程应具备一些最佳实践,甚至可以称为不可协商的原则:
- 测试
- 可读代码
- 减少内存分配
- 防卫判断
- 等等
在实现需求的同时,把优秀的软件实践落实到位,就可以称之为优秀的程序员。埋点,或称为插桩,是时候作为软件工程的最佳实践之一了。
代码开发中,我提倡遵从“面向交接”的原则。也就是说,我们在编写代码时,不仅要考虑当前需求,还要考虑之后其他人愿不愿意接手你的代码。
以己度人,你愿意接手一段不易阅读、不做防卫判断、漏洞百出、不打日志、不暴露监控指标的代码吗?即便只是为了几个月之后的自己,也应该遵从“面向交接”的原则。
研发可以立刻做的几件事
如果想把可观测性落实到日常开发,可以从这些低成本动作开始:
- 关键日志全部结构化,至少包含时间、服务、环境、请求 ID、错误码和关键业务字段。
- 对核心接口暴露请求量、错误率和延迟指标。
- 跨服务调用尽量保留 trace_id,让日志和链路追踪能互相跳转。
- 对发布、配置变更、重要任务执行结果记录事件。
- 在代码评审中检查新增功能是否具备必要观测数据。
这些动作不需要一次性建设完整平台,但会显著提升线上问题可调查性。
FAQ
Q1:可观测性为什么不是运维一个团队的事?
A:因为观测数据往往产生于代码内部。研发最了解业务语义和异常路径,只有研发参与,日志、指标和链路追踪才会有足够上下文。
Q2:日志已经很多了,还需要指标吗?
A:需要。日志适合查看事件细节,指标适合观察趋势和全局健康状态。两者解决的问题不同。
Q3:埋点会不会增加开发负担?
A:会有成本,但这是软件工程成本的一部分。缺少埋点会把成本转移到故障现场,最终变成更长的排障时间和更高的沟通成本。
结语
谨以本文引发大家对可观测性的思考,尤其是研发人员。可观测性不是某个工具团队的专属工作,而是软件本身应该具备的质量属性。
当一个系统能清楚暴露自己的状态,研发、运维和 SRE 才能在故障发生时更快判断影响、定位问题并恢复服务。埋点和插桩,真的应该成为软件工程的最佳实践之一了。
监控、可观测性整套体系确实非常驳杂,我们在这个领域做了十年,如果您需要乙方协助构建整套体系,欢迎联系我们: https://flashcat.cloud/contact/