name: implementing-observability description: 使用OpenTelemetry作为统一标准的监控、日志和追踪实施。适用于需要性能、错误和行为可见性的生产系统构建。涵盖OpenTelemetry(指标、日志、追踪)、Prometheus、Grafana、Loki、Jaeger、Tempo、结构化日志(structlog、tracing、slog、pino)和告警。
生产可观测性与OpenTelemetry
目的
使用OpenTelemetry作为2025年行业标准,实施生产级可观测性。涵盖三大支柱(指标、日志、追踪)、LGTM堆栈部署和关键的日志-追踪关联模式。
何时使用
使用时机:
- 构建需要性能和错误可见性的生产系统
- 调试多服务的分布式系统
- 设置监控、日志或追踪基础设施
- 实施带有追踪关联的结构化日志
- 为生产系统配置告警规则
跳过如果:
- 构建无需生产部署的概念验证
- 系统每日请求量<100(控制台日志可能足够)
OpenTelemetry标准(2025)
OpenTelemetry是CNCF毕业项目,统一可观测性:
┌────────────────────────────────────────────────────────┐
│ OpenTelemetry:统一标准 │
├────────────────────────────────────────────────────────┤
│ │
│ 一个SDK适用于所有信号: │
│ ├── 指标(Prometheus兼容) │
│ ├── 日志(结构化、关联) │
│ ├── 追踪(分布式、标准化) │
│ └── 上下文(跨服务传播) │
│ │
│ 语言SDK: │
│ ├── Python:opentelemetry-api, opentelemetry-sdk │
│ ├── Rust:opentelemetry, tracing-opentelemetry │
│ ├── Go:go.opentelemetry.io/otel │
│ └── TypeScript:@opentelemetry/api │
│ │
│ 导出到任何后端: │
│ ├── LGTM堆栈(Loki、Grafana、Tempo、Mimir) │
│ ├── Prometheus + Jaeger │
│ ├── Datadog、New Relic、Honeycomb(SaaS) │
│ └── 通过OTLP协议的自定义后端 │
│ │
└────────────────────────────────────────────────────────┘
上下文参考:/websites/opentelemetry_io(可信度:高,代码片段:5,888,分数:85.9)
可观测性的三大支柱
1. 指标(发生了什么?)
随时间跟踪系统健康和性能。
指标类型:计数器(始终增加)、仪表(上下浮动)、直方图(分布)、摘要(百分位数)。
简要示例(Python):
from opentelemetry import metrics
meter = metrics.get_meter(__name__)
http_requests = meter.create_counter("http.server.requests")
http_requests.add(1, {"method": "GET", "status": 200})
2. 日志(发生了什么?)
记录带有上下文的离散事件。
关键:始终注入trace_id/span_id用于日志-追踪关联。
简要示例(Python + structlog):
import structlog
from opentelemetry import trace
logger = structlog.get_logger()
span = trace.get_current_span()
ctx = span.get_span_context()
logger.info(
"processing_request",
trace_id=format(ctx.trace_id, '032x'),
span_id=format(ctx.span_id, '016x'),
user_id=user_id
)
参见:references/structured-logging.md获取完整配置。
3. 追踪(时间花在哪里了?)
跟踪请求在分布式服务中的流程。
关键概念:追踪(端到端旅程)、跨度(单个操作)、父子(嵌套操作)。
简要示例(Python + FastAPI):
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
app = FastAPI()
FastAPIInstrumentor.instrument_app(app) # 自动追踪所有HTTP请求
参见:references/opentelemetry-setup.md获取按语言SDK安装。
LGTM堆栈(自托管可观测性)
LGTM = Loki(日志) + Grafana(可视化) + Tempo(追踪) + Mimir(指标)
┌────────────────────────────────────────────────────────┐
│ LGTM架构 │
├────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────┐ │
│ │ Grafana仪表板(端口3000) │ │
│ │ 日志、指标、追踪的统一UI │ │
│ └──────┬──────────────┬─────────────┬─────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Loki │ │ Tempo │ │ Mimir │ │
│ │ (日志) │ │ (追踪) │ │(指标) │ │
│ │端口3100 │ │端口3200 │ │端口9009 │ │
│ └────▲─────┘ └────▲─────┘ └────▲─────┘ │
│ │ │ │ │
│ └──────────────┴─────────────┘ │
│ │ │
│ ┌───────▼────────┐ │
│ │ Grafana Alloy │ │
│ │ (收集器) │ │
│ │ 端口4317/8 │ ← OTLP gRPC/HTTP │
│ └───────▲────────┘ │
│ │ │
│ OpenTelemetry仪器化应用 │
│ │
└────────────────────────────────────────────────────────┘
快速开始:运行examples/lgtm-docker-compose/docker-compose.yml获取完整LGTM堆栈。
参见:references/lgtm-stack.md获取生产部署指南。
关键模式:日志-追踪关联
问题:日志和追踪存储在不同系统中。看到错误日志但找不到相关追踪。
解决方案:在每个日志记录中注入trace_id和span_id。
Python(structlog)
import structlog
from opentelemetry import trace
logger = structlog.get_logger()
span = trace.get_current_span()
ctx = span.get_span_context()
logger.info(
"request_processed",
trace_id=format(ctx.trace_id, '032x'), # 32字符十六进制
span_id=format(ctx.span_id, '016x'), # 16字符十六进制
user_id=user_id
)
Rust(tracing)
use tracing::{info, instrument};
#[instrument(fields(user_id = %user_id))]
async fn process_request(user_id: u64) -> Result<Response> {
// trace_id/span_id自动包含
info!(user_id = user_id, "processing request");
Ok(result)
}
参见:references/trace-context.md获取Go和TypeScript模式。
在Grafana中查询
{job="api-service"} |= "trace_id=4bf92f3577b34da6a3ce929d0e0e4736"
快速设置指南
1. 选择您的堆栈
决策树:
- 绿地项目:OpenTelemetry SDK + LGTM堆栈(自托管)或Grafana Cloud(托管)
- 现有Prometheus:添加Loki(日志)+ Tempo(追踪)
- Kubernetes:通过Helm的LGTM,Alloy DaemonSet
- 零运维:托管SaaS(Grafana Cloud、Datadog、New Relic)
2. 安装OpenTelemetry SDK
引导脚本:
python scripts/setup_otel.py --language python --framework fastapi
手动(Python):
pip install opentelemetry-api opentelemetry-sdk \
opentelemetry-instrumentation-fastapi \
opentelemetry-exporter-otlp
参见:references/opentelemetry-setup.md获取Rust、Go、TypeScript安装。
3. 部署LGTM堆栈
Docker Compose(开发):
cd examples/lgtm-docker-compose
docker-compose up -d
# Grafana:http://localhost:3000(admin/admin)
# OTLP:localhost:4317(gRPC),localhost:4318(HTTP)
参见:references/lgtm-stack.md获取生产Kubernetes部署。
4. 配置结构化日志
参见:references/structured-logging.md获取完整设置(Python、Rust、Go、TypeScript)。
5. 设置告警
参见:references/alerting-rules.md获取Prometheus和Loki告警模式。
自动仪器化
OpenTelemetry自动仪器化流行框架:
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
app = FastAPI()
FastAPIInstrumentor.instrument_app(app) # 自动追踪所有HTTP请求
支持:FastAPI、Flask、Django、Express、Gin、Echo、Nest.js
参见:references/opentelemetry-setup.md获取框架特定设置。
常见模式
自定义跨度
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("fetch_user_details") as span:
span.set_attribute("user_id", user_id)
user = await db.fetch_user(user_id)
span.set_attribute("user_found", user is not None)
错误追踪
from opentelemetry.trace import Status, StatusCode
with tracer.start_as_current_span("process_payment") as span:
try:
result = process_payment(amount, card_token)
span.set_status(Status(StatusCode.OK))
except PaymentError as e:
span.set_status(Status(StatusCode.ERROR, str(e)))
span.record_exception(e)
raise
参见:references/trace-context.md获取后台作业追踪和上下文传播。
验证和测试
# 测试日志-追踪关联
# 1. 向您的应用发出请求
# 2. 从日志复制trace_id
# 3. 在Grafana中查询:{job="myapp"} |= "trace_id=<TRACE_ID>"
# 验证指标
python scripts/validate_metrics.py
与其他技能集成
- 仪表板:嵌入Grafana面板,查询Prometheus指标
- 反馈:告警路由(Slack、PagerDuty),通知UI
- 数据可视化:时间序列图表,追踪瀑布图,延迟热图
参见:examples/fastapi-otel/获取完整集成。
渐进披露
设置指南:
references/opentelemetry-setup.md- SDK安装(Python、Rust、Go、TypeScript)references/structured-logging.md- structlog、tracing、slog、pino配置references/lgtm-stack.md- LGTM部署(Docker、Kubernetes)references/trace-context.md- 日志-追踪关联模式references/alerting-rules.md- Prometheus和Loki告警模板
示例:
examples/fastapi-otel/- FastAPI + OpenTelemetry + LGTMexamples/axum-tracing/- Rust Axum + tracing + LGTMexamples/lgtm-docker-compose/- 生产就绪LGTM堆栈
脚本:
scripts/setup_otel.py- 引导OpenTelemetry SDKscripts/generate_dashboards.py- 生成Grafana仪表板scripts/validate_metrics.py- 验证指标命名
关键原则
- OpenTelemetry是标准 - 使用OTel SDK,而非供应商特定SDK
- 自动仪器化优先 - 优先自动而非手动跨度
- 始终关联日志和追踪 - 在每个日志中注入trace_id/span_id
- 使用结构化日志 - JSON格式,一致的字段名
- 自托管用LGTM堆栈 - 生产就绪开源堆栈
常见陷阱
不要:
- 使用供应商特定SDK(使用OpenTelemetry)
- 记录日志时不带trace_id/span_id上下文
- 手动仪器化自动仪器化覆盖的内容
- 混合日志库(选择一个:structlog、tracing、slog、pino)
要:
- 从自动仪器化开始
- 仅为业务关键操作添加手动跨度
- 使用语义约定作为跨度属性
- 导出到OTLP(gRPC优于HTTP)
- 在生产前使用LGTM docker-compose本地测试
成功指标
- 100%的日志在请求上下文中包含trace_id
- 平均解决时间(MTTR)减少>50%
- 开发人员使用Grafana作为首要调试工具
- 80%+的遥测来自自动仪器化
- 告警噪音<5%假阳性