mcpField
I
implementing-observability

implementing-observability

github.com/ancoleman云与 DevOps52571 次安装46 周前更新
代码仓库

关于 implementing-observability

这项技能介绍如何用 OpenTelemetry 实现生产级可观测性,涵盖指标、日志、追踪和 LGTM 技术栈,适用于需要性能监控、分布式调试与告警的开发和运维场景。

主要功能

  1. 01OpenTelemetry 指标、日志与追踪
  2. 02LGTM 技术栈部署指南
  3. 03日志与追踪关联模式
  4. 04框架自动插桩示例
  5. 05告警与验证示例

适用场景

  1. 01为生产服务添加可观测性
  2. 02追踪分布式服务中的请求
  3. 03将错误日志关联到对应追踪
  4. 04设置指标与日志告警

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/ancoleman/ai-design-components --skill implementing-observability

安装后在 Claude Code 中输入/implementing-observability确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

outputs.yaml
examples/axum-tracing/
README.md
examples/fastapi-otel/
main.py
README.md
requirements.txt
examples/grafana-dashboards/
api-overview.json
examples/lgtm-docker-compose/
docker-compose.yml
README.md
references/
alerting-rules.md
lgtm-stack.md
opentelemetry-setup.md
structured-logging.md
trace-context.md
scripts/
generate_dashboards.py
setup_otel.py
validate_metrics.py

详细介绍

使用 OpenTelemetry 实现生产级可观测性

目的

使用 OpenTelemetry 实现生产级可观测性。OpenTelemetry 是 2025 年的行业标准。本节涵盖三大支柱(指标、日志、追踪)、LGTM 技术栈部署,以及关键的日志与追踪关联模式。

适用场景

适用于:

  • 构建需要了解性能和错误情况的生产系统
  • 调试包含多个服务的分布式系统
  • 设置监控、日志记录或追踪基础设施
  • 实现带有追踪关联的结构化日志
  • 为生产系统配置告警规则

不适用于:

  • 构建无需部署到生产环境的概念验证
  • 系统每天的请求数少于 100(控制台日志记录可能已足够)

OpenTelemetry 标准(2025)

OpenTelemetry 是 CNCF 的毕业项目,旨在统一可观测性:

┌────────────────────────────────────────────────────────┐
│          OpenTelemetry: The Unified Standard           │
├────────────────────────────────────────────────────────┤
│                                                         │
│  ONE SDK for ALL signals:                              │
│  ├── Metrics (Prometheus-compatible)                   │
│  ├── Logs (structured, correlated)                     │
│  ├── Traces (distributed, standardized)                │
│  └── Context (propagates across services)              │
│                                                         │
│  Language SDKs:                                         │
│  ├── Python: opentelemetry-api, opentelemetry-sdk      │
│  ├── Rust: opentelemetry, tracing-opentelemetry        │
│  ├── Go: go.opentelemetry.io/otel                      │
│  └── TypeScript: @opentelemetry/api                    │
│                                                         │
│  Export to ANY backend:                                │
│  ├── LGTM Stack (Loki, Grafana, Tempo, Mimir)          │
│  ├── Prometheus + Jaeger                               │
│  ├── Datadog, New Relic, Honeycomb (SaaS)              │
│  └── Custom backends via OTLP protocol                 │
│                                                         │
└────────────────────────────────────────────────────────┘

Context7 参考:/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. 追踪(时间花在哪里了?)

跟踪请求在分布式服务中的流转。

关键概念:追踪(端到端过程)、Span(单个操作)、父子关系(嵌套操作)。

简短示例(Python + FastAPI):

from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor

app = FastAPI()
FastAPIInstrumentor.instrument_app(app)  # Auto-traces all HTTP requests

参见:references/opentelemetry-setup.md,了解各语言的 SDK 安装方法。

LGTM 技术栈(自托管可观测性)

LGTM = Loki(日志)+ Grafana(可视化)+ Tempo(追踪)+ Mimir(指标)

┌────────────────────────────────────────────────────────┐
│                  LGTM Architecture                      │
├────────────────────────────────────────────────────────┤
│                                                         │
│  ┌──────────────────────────────────────────────┐      │
│  │           Grafana Dashboard (Port 3000)      │      │
│  │  Unified UI for Logs, Metrics, Traces       │      │
│  └──────┬──────────────┬─────────────┬─────────┘      │
│         │              │             │                 │
│         ▼              ▼             ▼                 │
│  ┌──────────┐   ┌──────────┐  ┌──────────┐            │
│  │   Loki   │   │  Tempo   │  │  Mimir   │            │
│  │  (Logs)  │   │ (Traces) │  │(Metrics) │            │
│  │Port 3100 │   │Port 3200 │  │Port 9009 │            │
│  └────▲─────┘   └────▲─────┘  └────▲─────┘            │
│       │              │             │                   │
│       └──────────────┴─────────────┘                   │
│                      │                                 │
│              ┌───────▼────────┐                        │
│              │ Grafana Alloy  │                        │
│              │  (Collector)   │                        │
│              │  Port 4317/8   │ ← OTLP gRPC/HTTP       │
│              └───────▲────────┘                        │
│                      │                                 │
│         OpenTelemetry Instrumented Apps                │
│                                                         │
└────────────────────────────────────────────────────────┘

快速开始:运行 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-char hex
    span_id=format(ctx.span_id, '016x'),    # 16-char hex
    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 automatically included
    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)  # Auto-trace all HTTP requests

支持的框架:FastAPI、Flask、Django、Express、Gin、Echo、Nest.js

参见:references/opentelemetry-setup.md,了解特定框架的设置方法。

常见模式

自定义 Span
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,了解后台任务追踪和上下文传播。

验证与测试

# Test log-trace correlation
# 1. Make request to your app
# 2. Copy trace_id from logs
# 3. Query in Grafana: {job="myapp"} |= "trace_id=<TRACE_ID>"

# Validate metrics
python scripts/validate_metrics.py

与其他技能集成

  • 仪表板:嵌入 Grafana 面板,查询 Prometheus 指标
  • 反馈:告警路由(Slack、PagerDuty)、通知界面
  • 数据可视化:时间序列图表、追踪瀑布图、延迟热力图

参见: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 + LGTM
  • examples/axum-tracing/ - Rust Axum + tracing + LGTM
  • examples/lgtm-docker-compose/ - 可用于生产环境的 LGTM 技术栈

脚本:

  • scripts/setup_otel.py - 初始化 OpenTelemetry SDK
  • scripts/generate_dashboards.py - 生成 Grafana 仪表板
  • scripts/validate_metrics.py - 验证指标命名

核心原则

  1. OpenTelemetry 是标准 - 使用 OTel SDK,而非特定供应商的 SDK
  2. 优先使用自动埋点 - 优先选择自动埋点,而非手动创建 Span
  3. 始终关联日志和追踪 - 将 trace_id/span_id 注入每条日志
  4. 使用结构化日志 - 采用 JSON 格式,并统一字段名称
  5. 使用 LGTM 技术栈进行自托管 - 可用于生产环境的开源技术栈

常见误区

不要:

  • 使用特定供应商的 SDK(使用 OpenTelemetry)
  • 在缺少 trace_id/span_id 上下文时记录日志
  • 手动埋点自动埋点已覆盖的内容
  • 混用日志库(选择一个:structlog、tracing、slog、pino)

应该:

  • 从自动埋点开始
  • 仅为业务关键操作添加手动 Span
  • 对 Span 属性使用语义约定
  • 导出到 OTLP(优先使用 gRPC 而非 HTTP)
  • 在生产环境部署前,使用 LGTM docker-compose 在本地测试

成功指标

  1. 在请求上下文中,100% 的日志包含 trace_id
  2. 平均解决时间(MTTR)降低 >50%
  3. 开发者将 Grafana 作为首选调试工具
  4. 80% 以上的遥测数据来自自动埋点
  5. 告警噪声中的误报率 < 5%

评论

支持 Markdown