恋上蓝花楹

使用 OpenTelemetry 打造可观测性系统:从日志到链路追踪的完整指南

可观测性

当你的系统只有一台服务器、几十行代码时,日志打印到控制台就能解决所有问题。但当系统演进到十几甚至上百个微服务,任何一个请求都可能穿越七八个服务节点——传统日志和监控手段已经远远不够了。

这就是”可观测性”(Observability)这个词近年来在工程界大火的原因。

什么是可观测性?

可观测性不是某个具体的工具,而是一种系统设计理念:通过系统外部输出推断其内部状态的能力

OpenTelemetry 给出了一个实用框架,将可观测性拆分为三大支柱:

  • Logs(日志):离散的事件记录,”某时某刻发生了什么”
  • Metrics(指标):聚合后的数值,”系统运行得怎么样”
  • Traces(链路追踪):请求在系统中的完整旅行路径,”这个请求经历了什么”

数据中心

实战一:Spring Boot 接入 OpenTelemetry

Spring Boot 3.x 完美支持 OpenTelemetry,只需要几行配置即可完成接入。

添加依赖(使用 Spring Boot Starter):

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>

配置 application.yml:

yaml
spring:
  application.name: xma-supervise
  otlp:
    tracing:
      endpoint: http://localhost:4318/v1/traces
    metrics:
      endpoint: http://localhost:4318/v1/metrics

management:
  tracing:
    sampling:
      probability: 1.0
  metrics:
    export:
      prometheus:
        enabled: true

这样配置后,Spring Boot 会自动为每个 HTTP 请求创建 Span,并在服务间传递 TraceId。

实战二:结构化日志输出

可观测性最基础的环节是日志。但传统日志只是文本,搜索困难,难以关联。

推荐使用 Logstash JSON Format,将日志输出为结构化 JSON:

yaml
logging:
  pattern:
    console: '{"time":"%d{yyyy-MM-dd HH:mm:ss.SSS}","level":"%level","traceId":"%X{traceId:-}","spanId":"%X{spanId:-}","service":"${spring.application.name}","msg":"%msg"}%n'
  level:
    root: INFO
    com.xma: DEBUG

这样每条日志都包含 traceId,可以与链路追踪无缝关联。

实战三:自定义链路追踪

自动埋点只能追踪 HTTP 请求,对于异步任务、数据库操作、外部 API 调用,需要手动埋点:

java
import io.opentelemetry.api.trace.Tracer;

@Service
public class OrderService {

    private final Tracer tracer;

    public void createOrder(Order order) {
        // 创建子Span
        Span span = tracer.spanBuilder("createOrder").startSpan();
        try (Scope scope = span.makeCurrent()) {
            span.setAttribute("order.id", order.getId());
            span.setAttribute("order.amount", order.getAmount());

            validateOrder(order);
            saveOrder(order);
            sendNotification(order);

        } catch (Exception e) {
            span.recordException(e);
            throw e;
        } finally {
            span.end();
        }
    }
}

实战四:Grafana 可视化大盘

数据图表

数据收集完毕后,需要一个统一的展示平台。推荐组合:

  • Prometheus:指标存储与查询
  • Grafana:可视化大盘
  • JaegerTempo:链路追踪展示
  • Loki:日志聚合与检索

在 Grafana 中配置数据源后,可以搭建以下关键 Dashboard:

  • 📊 QPS 与延迟分布:P50/P95/P99 响应时间
  • ⚠️ 错误率监控:4xx/5xx 占比告警
  • 🔗 调用链路图:服务依赖拓扑
  • 📝 日志检索:按 TraceId 聚合全链路日志

写在最后

可观测性不是一蹴而就的工程,而是一种持续演进的能力。建议从小处着手:先为新增接口开启链路追踪,用起来之后再逐步回溯历史接口。

当你在 Grafana 上第一次看到某个慢请求穿越了 6 个服务节点、定位到具体是某一次 Redis 慢查询导致的问题时——那种”掌控感”,才是可观测性最大的价值。

记住:**看不见的东西,永远无法优化。**

wulilele

我是一名热爱科技与AI的软件工程师。