前端追踪技术:为UI添加后端式可观测性的完整指南

本文详细介绍了如何在前端应用中使用追踪技术,特别是OpenTelemetry工具,将用户界面行为与后端服务连接起来,实现全栈可观测性,帮助开发者快速定位性能问题。

前端追踪技术:为UI添加后端式可观测性的完整指南

如果你曾经在调试缓慢应用程序时陷入困境,你可能想知道:我应该首先从哪里开始查找——后端还是前端?

对于大多数团队来说,一旦到达后端,可观测性就结束了。我们有分布式追踪、日志和指标,为所有微服务提供了清晰的视图。但是前端呢?它通常被当作一个黑盒子来处理。

我们知道请求何时到达服务器以及它如何流经我们的服务,但我们不知道在此之前发生了什么——UI完成的设置持续时间,用户是否看到请求顺利返回等。

这正是前端追踪如此重要的原因。通过使用像OpenTelemetry(OTel)这样的工具在浏览器中检测用户交互,开发人员可以将前端和后端的跨度连接到一个单独的追踪中。

好处?全栈可见性,性能调试更快。

为什么前端需要追踪

前端系统有自己的差异,这些差异可能在后端日志中不可见:

  • 用户交互延迟 - 当用户点击按钮感觉"慢"时。是React重新渲染太多了吗?JS包太重了吗?API慢吗?没有追踪,我们根本不知道。

  • 异步复杂性 - 单页应用程序可以同时有多个请求,以及渲染任务和状态转换都在同时发生。没有追踪,就像试图解开一团意大利面。

  • 本地差异 - 后端日志不知道用户是否在使用受限的3G连接,使用了多少CPU,或者用户的浏览器是否有任何奇怪的行为。

前端追踪将所有这些结合在一起,使我们能够:

  • 将用户操作(点击、导航或输入事件)与触发的网络请求连接起来
  • 跟踪请求通过后端服务
  • 测量和比较感知延迟(用户认为的)与系统延迟(后端使用的)

一旦我们将所有这些整合在一起,发现瓶颈就只是一个可见性问题。我们可以清楚地看到,调试不再是一个猜谜游戏。

快速回顾:追踪如何工作

在继续讨论前端之前,让我们回顾一些基础知识。

  • 追踪:追踪是完整的执行路径,例如"用户点击结账"
  • 跨度:跨度是该追踪中完成的较小工作单元(UI渲染、API调用、数据库查询)

每个追踪都有一个唯一的ID,通过系统中的边界传播(通过像traceparent这样的头部)。

演练示例

用户在你的React应用中点击"立即购买" → 前端跨度开始 该点击向/checkout发出fetch请求 → OTel自动创建网络跨度 它将发送带有包含追踪ID的头部请求 后端将继续追踪,然后为订单处理、数据库写入等创建跨度 像Jaeger、Tempo或Datadog这样的观察工具将向你显示从端到端的整个追踪旅程

突然间,前端不再是一个黑盒子,它成为了分布式系统叙事的一部分。

在浏览器中设置OpenTelemetry

在前端设置OTel非常简单。

步骤1:安装依赖

1
npm install @opentelemetry/sdk-trace-web @opentelemetry/instrumentation-fetch @opentelemetry/exporter-trace-otlp-http

步骤2:在应用中引导

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { registerInstrumentations } from '@opentelemetry/instrumentation';
import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';

const provider = new WebTracerProvider();
const exporter = new OTLPTraceExporter({
  url: 'http://localhost:4318/v1/traces',
});

provider.addSpanProcessor(new BatchSpanProcessor(exporter));
provider.register();

registerInstrumentations({
  instrumentations: [new FetchInstrumentation()],
});

console.log('OpenTelemetry bootstrapped');

这意味着:

  • 每个fetch或XHR调用都被追踪
  • 跨度被发送到你的追踪收集器(OTLP、Jaeger、Datadog等)

上下文向下游传播,作为开发人员,你可以在不管理上下文的情况下开发应用程序逻辑。

记录用户事件

有网络请求很好,但当你能够捕获用户事件时,追踪变得更有价值。然后你可以关联:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { trace } from '@opentelemetry/api';

const tracer = trace.getTracer('ui-tracer');

document.getElementById('checkout-btn')?.addEventListener('click', () => {
  const span = tracer.startSpan('user.click.checkout');
  
  setTimeout(() => {
    span.end();
  }, 200);
});

“用户点击结账”

→ 触发的API调用 → 后端订单服务 → 数据库查询

你可以简单地将整个东西放在React的钩子或高阶组件中,以确保你的追踪在整个应用程序中保持一致。

连接前端和后端

这就是魔法在程序上发生的地方,当跨度跨越边界时。

  • OTel将自动注入traceparent头部
  • 当后端服务收到请求时,它们将拾取它并继续追踪
  • 你的追踪查看器将所有这些拼接在一起,创建统一的时间线

Jaeger中的示例追踪可能看起来像这样:

1
2
3
4
user.click.checkout (Frontend, 50ms)
 └── fetch /checkout (Frontend, 20ms)
       └── OrderService.processOrder (Backend, 120ms)
            └── Database query (DB, 80ms)

通过这个视图,可以非常清楚地看到请求的减速发生在哪里,无论是在客户端、API中,还是在更深的数据库中。

实际调试和监控

调试难以复现的错误

曾经有用户说"结账很慢",而你无法复现吗?通过追踪,你可以找出问题是否是:

  • 解析JavaScript包的时间较慢
  • 缓慢的API调用
  • 或者来自后端数据库的东西

性能监控

追踪向我们显示:

  • 渲染时间与后端处理时间
  • 阻塞交互性的长任务
  • 前端测量(交互时间)和后端API延迟之间的联系

可靠性洞察

随时间采样追踪可以显示:

  • 仅在特定UI路径下失败的不可靠API
  • 减速可能仅限于特定浏览器
  • 查看设备特定的减速

超越OpenTelemetry:其他工具

OpenTelemetry是一个广泛使用的开放标准,有几个流行的供应商特定工具,它们不是OpenTelemetry规范的一部分,你可以使用。

  • Sentry Performance - 一个性能工具,具有事务追踪,设置非常简单
  • Datadog RUM - 一个真实用户监控工具,将RUM与后端追踪结合起来

其他供应商工具可能比OpenTelemetry更容易使用和实现;OpenTelemetry可以在未来实现可移植性。

前端可观测性最佳实践

  • 明智采样:你不需要追踪每一次点击。建议使用概率采样,以可管理的开销找到正确的可见性水平。
  • 不要捕获敏感数据:你永远不应该捕获原始击键、密码或个人信​​息。始终确保清理跨度。
  • 跨堆栈沟通策略:只有前端和后端团队在这里有一定程度的一致性时,可观测性才能工作(专业提示:到处使用OTel)。
  • 为可视化提供上下文:如果你不能将用户体验指标(如LCP、TTI)与后端跨度联系起来,火焰图就没有多大意义。

结论:黑盒子被关闭了

在太长时间里,前端的性能在可观测性中被视为事后想法。但注意!用户不关心API响应时间本身。他们只体验端到端的逻辑旅程(即点击按钮,等待屏幕加载,并看到结果)。

前台追踪(可能使用像OpenTelemetry这样的东西)最终将在UI中给我们带来后端式的可观测性。

这意味着:

  • 将用户交互连接到后端请求
  • 将分布式系统作为一个整体进行调试
  • 提供更好、可预测的用户体验

换句话说,对于可观测性来说,追踪不仅仅是一个可有可无或增值的东西:它是全栈可观测性的缺失环节。

常见问题解答

Q1:追踪对前端应用来说不是太重了吗?

通过采样,绝对不是。你不需要每一个追踪——你需要足够的追踪来识别模式。

Q2:我需要更改后端才能在前端进行追踪吗?

在理想世界中,是的。为了将追踪拼接在一起,你的后端也需要有OTel或兼容的东西。

Q3:追踪会取代日志和指标吗?

不会。追踪不会取代日志和指标。日志为你提供所有细节,指标为你提供趋势,追踪为你提供跨系统的故事。

Q4:如果我的团队已经在使用Sentry或Datadog怎么办?

没关系!许多供应商工具都带有开箱即用的追踪功能。你仍然可以引入OTel,以避免未来的供应商锁定。

👉 现在我很好奇:如果你今天可以在前端应用中追踪任何一件事,你会追踪什么?那个似乎总是滞后的按钮点击?那个神秘的网络请求?或者,可能是在使用旧设备时似乎永远挂起的渲染阶段?

这就是追踪的美:它正好照亮你需要它的地方。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计