返回技能列表

instrument-distributed-tracing

pjt222
更新于 2 days ago
7 次查看
17
2
17
在 GitHub 上查看
设计design

关于

This skill helps developers instrument applications with OpenTelemetry for distributed tracing. It covers both automatic and manual instrumentation, context propagation, sampling strategies, and integration with backends like Jaeger or Tempo. Use it to debug latency issues in microservices, understand request flows, correlate traces with logs/metrics, or migrate from legacy tracing systems.

快速安装

Claude Code

推荐
主要方式
npx skills add pjt222/agent-almanac -a claude-code
插件命令备选方式
/plugin add https://github.com/pjt222/agent-almanac
Git 克隆备选方式
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/instrument-distributed-tracing

在 Claude Code 中复制并粘贴此命令以安装该技能

技能文档


name: instrument-distributed-tracing description: > Instrumenta aplicaciones con OpenTelemetry para rastreo distribuido, incluyendo instrumentación automática y manual, propagación de contexto, estrategias de muestreo e integración con Jaeger o Tempo. Útil para depurar problemas de latencia en sistemas distribuidos, comprender el flujo de solicitudes entre microservicios, correlacionar trazas con logs y métricas para análisis de causa raíz, medir la latencia de extremo a extremo, o migrar desde sistemas de rastreo heredados a OpenTelemetry. locale: es source_locale: en source_commit: 6f65f316 translator: claude-opus-4-6 translation_date: 2026-03-16 license: MIT allowed-tools: Read Write Edit Bash Grep Glob metadata: author: Philipp Thoss version: "1.0" domain: observability complexity: advanced language: multi tags: opentelemetry, tracing, jaeger, tempo, instrumentation

Instrumentar Rastreo Distribuido

Implementa rastreo distribuido con OpenTelemetry para rastrear solicitudes entre microservicios e identificar cuellos de botella de rendimiento.

Cuándo Usar

  • Depurar problemas de latencia en sistemas distribuidos con múltiples servicios
  • Comprender el flujo de solicitudes y las dependencias entre microservicios
  • Identificar consultas lentas de base de datos o llamadas a APIs externas dentro de una transacción
  • Correlacionar trazas con logs y métricas para análisis de causa raíz
  • Medir la latencia de extremo a extremo desde la solicitud del usuario hasta la respuesta
  • Migrar desde sistemas de rastreo heredados (Zipkin, Jaeger) a OpenTelemetry
  • Establecer el cumplimiento de SLO mediante el seguimiento detallado de percentiles de latencia

Entradas

  • Requerido: Lista de servicios a instrumentar (lenguajes y frameworks)
  • Requerido: Elección de backend de rastreo (Jaeger, Tempo, Zipkin, o SaaS de proveedor)
  • Opcional: Bibliotecas de instrumentación existentes (OpenTracing, Zipkin)
  • Opcional: Requisitos de estrategia de muestreo (porcentaje, limitación de tasa)
  • Opcional: Atributos de span personalizados para metadatos específicos del negocio

Procedimiento

Consulta Ejemplos Extendidos para archivos de configuración completos y plantillas.

Paso 1: Configurar el Backend de Rastreo

Despliega Jaeger o Grafana Tempo para recibir y almacenar trazas.

Opción A: Jaeger todo-en-uno (desarrollo/pruebas):

# docker-compose.yml
version: '3.8'
services:
  jaeger:
    image: jaegertracing/all-in-one:1.51
    ports:
      - "5775:5775/udp"   # Zipkin compact thrift
      - "6831:6831/udp"   # Jaeger compact thrift
      - "6832:6832/udp"   # Jaeger binary thrift
      - "5778:5778"       # Serve configs
      - "16686:16686"     # Jaeger UI
      - "14268:14268"     # Jaeger HTTP thrift
      - "14250:14250"     # Jaeger GRPC
      - "9411:9411"       # Zipkin compatible endpoint
    environment:
      - COLLECTOR_ZIPKIN_HOST_PORT=:9411
      - COLLECTOR_OTLP_ENABLED=true
    restart: unless-stopped

Opción B: Grafana Tempo (producción, escalable):

# docker-compose.yml
version: '3.8'
services:
  tempo:
    image: grafana/tempo:2.3.0
    command: ["-config.file=/etc/tempo.yaml"]
    volumes:
      - ./tempo.yaml:/etc/tempo.yaml
      - tempo-data:/tmp/tempo
    ports:
      - "3200:3200"   # Tempo HTTP
      - "4317:4317"   # OTLP gRPC
      - "4318:4318"   # OTLP HTTP
      - "9411:9411"   # Zipkin
    restart: unless-stopped

volumes:
  tempo-data:

Configuración de Tempo (tempo.yaml):

server:
  http_listen_port: 3200

distributor:
  receivers:
    jaeger:
# ... (see EXAMPLES.md for complete configuration)

Para producción con almacenamiento S3:

storage:
  trace:
    backend: s3
    s3:
      bucket: tempo-traces
      endpoint: s3.amazonaws.com
      region: us-east-1
    wal:
      path: /tmp/tempo/wal
    pool:
      max_workers: 100
      queue_depth: 10000

Esperado: Backend de rastreo accesible, listo para recibir trazas vía OTLP, la interfaz de Jaeger o Grafana muestra "no traces" inicialmente.

En caso de fallo:

  • Verificar que los puertos no estén ya en uso: netstat -tulpn | grep -E '(4317|16686|3200)'
  • Verificar los logs del contenedor: docker logs jaeger o docker logs tempo
  • Probar el endpoint OTLP: curl http://localhost:4318/v1/traces -v
  • Para Tempo: validar la sintaxis de configuración con tempo -config.file=/etc/tempo.yaml -verify-config

Paso 2: Instrumentar Aplicaciones (Auto-Instrumentación)

Usa la auto-instrumentación de OpenTelemetry para frameworks comunes para minimizar cambios de código.

Python con Flask:

pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install
# app.py
from flask import Flask
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
# ... (see EXAMPLES.md for complete configuration)

Go con framework Gin:

go get go.opentelemetry.io/otel
go get go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
go get go.opentelemetry.io/otel/sdk/trace
go get go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin
package main

import (
    "context"
    "github.com/gin-gonic/gin"
    "go.opentelemetry.io/otel"
# ... (see EXAMPLES.md for complete configuration)

Node.js con Express:

npm install @opentelemetry/api \
            @opentelemetry/sdk-node \
            @opentelemetry/auto-instrumentations-node \
            @opentelemetry/exporter-trace-otlp-grpc
// tracing.js
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
const { Resource } = require('@opentelemetry/resources');
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
# ... (see EXAMPLES.md for complete configuration)

Esperado: Las trazas de los servicios instrumentados aparecen en la interfaz de Jaeger o Grafana, las solicitudes HTTP crean spans automáticamente.

En caso de fallo:

  • Verificar que el endpoint del exportador sea alcanzable desde la aplicación
  • Verificar las variables de entorno: OTEL_EXPORTER_OTLP_ENDPOINT=http://tempo:4317
  • Habilitar el registro de depuración: OTEL_LOG_LEVEL=debug (Python), OTEL_LOG_LEVEL=DEBUG (Node.js)
  • Probar con un span simple: crear manualmente un span para verificar el pipeline de exportación
  • Verificar conflictos de versiones entre paquetes de OpenTelemetry

Paso 3: Agregar Instrumentación Manual

Crea spans personalizados para lógica de negocio, consultas de base de datos y llamadas externas.

Spans manuales en Python:

from opentelemetry import trace

tracer = trace.get_tracer(__name__)

def process_order(order_id):
    # Create a span for the entire operation
# ... (see EXAMPLES.md for complete configuration)

Spans manuales en Go:

import (
    "context"
    "go.opentelemetry.io/otel"
    "go.opentelemetry.io/otel/attribute"
    "go.opentelemetry.io/otel/codes"
    "go.opentelemetry.io/otel/trace"
# ... (see EXAMPLES.md for complete configuration)

Buenas prácticas para atributos de span:

  • Usar convenciones semánticas: http.method, http.status_code, db.system, db.statement
  • Agregar contexto de negocio: user.id, order.id, product.category
  • Incluir identificadores de recursos: instance.id, region, availability_zone
  • Registrar errores: span.RecordError(err) y span.SetStatus(codes.Error, message)
  • Agregar eventos para hitos significativos: span.AddEvent("cache_miss")

Esperado: Los spans personalizados aparecen en la vista de traza, las relaciones padre-hijo son correctas, los atributos son visibles en los detalles del span, los errores están resaltados.

En caso de fallo:

  • Verificar la propagación de contexto: el contexto del span padre se pasa al hijo
  • Verificar que los nombres de span sean descriptivos y sigan las convenciones de nomenclatura
  • Asegurarse de que los spans se terminan (usar defer span.End() en Go, bloques with en Python)
  • Revisar los tipos de atributos: solo cadenas, enteros, booleanos, números de punto flotante
  • Validar las convenciones semánticas: usar nombres de atributos estándar donde sea aplicable

Paso 4: Implementar Propagación de Contexto

Asegúrate de que el contexto de traza fluya a través de los límites de servicio y operaciones asíncronas.

Propagación de encabezados HTTP (W3C Trace Context):

# Client side (Python with requests)
import requests
from opentelemetry import trace
from opentelemetry.propagate import inject

tracer = trace.get_tracer(__name__)
# ... (see EXAMPLES.md for complete configuration)
// Server side (Go with Gin)
import (
    "go.opentelemetry.io/otel"
    "go.opentelemetry.io/otel/propagation"
)

# ... (see EXAMPLES.md for complete configuration)

Propagación de cola de mensajes (Kafka):

# Producer
from opentelemetry.propagate import inject
from kafka import KafkaProducer

producer = KafkaProducer(bootstrap_servers=['kafka:9092'])

# ... (see EXAMPLES.md for complete configuration)
# Consumer
from opentelemetry.propagate import extract

def process_message(msg):
    # Extract trace context from Kafka headers
    headers = {k: v.decode('utf-8') for k, v in msg.headers}
    ctx = extract(headers)

    # Continue the trace
    with tracer.start_as_current_span("process_order_event", context=ctx):
        order_id = json.loads(msg.value)['order_id']
        handle_order(order_id)

Operaciones asíncronas (Python asyncio):

import asyncio
from opentelemetry import trace, context

async def async_operation():
    # Capture current context
    token = context.attach(context.get_current())
    try:
        with tracer.start_as_current_span("async_database_query"):
            await asyncio.sleep(0.1)  # Simulated async work
            return "result"
    finally:
        context.detach(token)

Esperado: Las trazas abarcan múltiples servicios, los IDs de traza son consistentes entre límites de servicio, las relaciones padre-hijo se preservan.

En caso de fallo:

  • Verificar que el propagador de W3C Trace Context esté configurado: otel.propagation.set_global_textmap(TraceContextTextMapPropagator())
  • Verificar que los encabezados se pasen en las solicitudes HTTP
  • Para Kafka: asegurarse de que los encabezados sean soportados por la versión del broker (v0.11+)
  • Depurar con inspección de encabezados: registrar el valor del encabezado traceparent
  • Usar la visualización de trazas para identificar vínculos de traza rotos

Paso 5: Configurar Estrategias de Muestreo

Implementa el muestreo para reducir el volumen de trazas y el costo mientras se mantiene la visibilidad.

Estrategias de muestreo:

from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.sampling import (
    ParentBased,
    TraceIdRatioBased,
    StaticSampler,
    Decision
# ... (see EXAMPLES.md for complete configuration)

Muestreo basado en cola con Tempo:

Configurar en tempo.yaml:

overrides:
  defaults:
    metrics_generator:
      processors: [service-graphs, span-metrics]
      storage:
        path: /tmp/tempo/generator/wal
        remote_write:
          - url: http://prometheus:9090/api/v1/write
            send_exemplars: true

    # Tail sampling (requires tempo-query)
    ingestion_rate_limit_bytes: 5000000
    ingestion_burst_size_bytes: 10000000

Usar TraceQL de Grafana Tempo para muestreo dinámico:

# Sample traces with errors
{ status = error }

# Sample slow traces (>1s)
{ duration > 1s }

# Sample specific services
{ resource.service.name = "checkout-service" }

Esperado: El volumen de trazas se reduce al porcentaje objetivo, las trazas con errores siempre se muestrean, la decisión de muestreo es visible en los metadatos de la traza.

En caso de fallo:

  • Verificar que el muestreador se aplique antes de la inicialización del proveedor de rastreo
  • Verificar el atributo de decisión de muestreo en los spans exportados
  • Para el muestreo de cola: asegurarse de que haya suficiente buffer (ingestion_burst_size_bytes)
  • Monitorear las trazas descartadas: métrica otel_traces_dropped_total
  • Probar con tráfico sintético de alto volumen para validar la tasa de muestreo

Paso 6: Correlacionar Trazas con Métricas y Logs

Vincula las trazas con métricas y logs para observabilidad unificada.

Agregar IDs de traza a logs (Python):

import logging
from opentelemetry import trace

# Custom log formatter with trace context
class TraceFormatter(logging.Formatter):
    def format(self, record):
# ... (see EXAMPLES.md for complete configuration)

Generar métricas desde trazas (Tempo):

# tempo.yaml
metrics_generator:
  registry:
    external_labels:
      cluster: production
  storage:
# ... (see EXAMPLES.md for complete configuration)

Esto genera métricas de Prometheus:

  • traces_service_graph_request_total - recuento de solicitudes entre servicios
  • traces_span_metrics_duration_seconds - histograma de duración de spans
  • traces_spanmetrics_calls_total - recuentos de llamadas de span

Consultar trazas desde métricas (Grafana):

Agrega soporte de exemplar a la fuente de datos de Prometheus en Grafana:

datasources:
  - name: Prometheus
    type: prometheus
    url: http://prometheus:9090
    jsonData:
      exemplarTraceIdDestinations:
        - name: trace_id
          datasourceName: Tempo

En el dashboard de Grafana, habilitar los exemplares:

{
  "fieldConfig": {
    "defaults": {
      "custom": {
        "showExemplars": true
      }
    }
  }
}

Esperado: Al hacer clic en los exemplares de métricas se abre la traza, los logs muestran los IDs de traza, las trazas enlazan a los logs, depuración unificada entre señales.

En caso de fallo:

  • Verificar que el soporte de exemplares esté habilitado en Prometheus (requiere v2.26+)
  • Verificar el formato del ID de traza (hex de 32 caracteres)
  • Asegurarse de que el generador de métricas esté habilitado en la configuración de Tempo
  • Validar que el endpoint de escritura remota sea accesible desde Tempo
  • Probar consultas de exemplares: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) and on() exemplar

Validación

  • El backend de rastreo recibe spans de todos los servicios instrumentados
  • Las trazas muestran relaciones padre-hijo correctas entre servicios
  • Los atributos de span incluyen convenciones semánticas y contexto de negocio
  • El contexto se propaga correctamente a través de llamadas HTTP y colas de mensajes
  • La estrategia de muestreo reduce el volumen de trazas al porcentaje objetivo
  • Las trazas con errores siempre se muestrean (si se usa muestreo consciente de errores)
  • Los IDs de traza aparecen en los logs de aplicación con el formato correcto
  • Grafana muestra trazas vinculadas desde métricas mediante exemplares
  • Los paneles de logs tienen vínculos de datos al visor de trazas
  • La retención de trazas coincide con la política de almacenamiento configurada

Errores Comunes

  • Contexto no propagado: Olvidar pasar context a las llamadas posteriores rompe las trazas. Siempre pasar el contexto explícitamente.
  • Spans nunca terminados: La falta de defer span.End() (Go) o bloques with (Python) causa que los spans permanezcan abiertos y pérdidas de memoria.
  • Sobre-instrumentación: Crear spans para cada función causa inflación de trazas. Centrarse en los límites de servicio, llamadas de base de datos y APIs externas.
  • Falta de registro de errores: No llamar a span.RecordError() pierde información valiosa de depuración. Siempre registrar errores en los spans.
  • Atributos de alta cardinalidad: Usar valores ilimitados (IDs de usuario, cuerpos de solicitud) como atributos de span causa problemas de almacenamiento. Usar muestreo o etiquetas de agregación.
  • Tipo de span incorrecto: Usar el tipo de span incorrecto (CLIENT vs SERVER vs INTERNAL) afecta la generación del gráfico de servicios. Seguir las convenciones semánticas.
  • Muestreo antes del contexto: Las decisiones de muestreo deben respetar el contexto de traza padre. Usar el muestreador ParentBased para respetar el muestreo ascendente.

Habilidades Relacionadas

  • correlate-observability-signals - Depuración unificada con métricas, logs y trazas vinculadas por IDs de traza
  • setup-prometheus-monitoring - Generar métricas desde trazas usando el generador de métricas de Tempo
  • configure-log-aggregation - Agregar IDs de traza a los logs para correlación con trazas distribuidas
  • build-grafana-dashboards - Visualizar métricas derivadas de trazas y vínculos de exemplares en dashboards

GitHub 仓库

pjt222/agent-almanac
路径: i18n/es/skills/instrument-distributed-tracing
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

相关推荐技能

executing-plans

设计

该Skill用于当开发者提供完整实施计划时,以受控批次方式执行代码实现。它会先审阅计划并提出疑问,然后分批次执行任务(默认每批3个任务),并在批次间暂停等待审查。关键特性包括分批次执行、内置检查点和架构师审查机制,确保复杂系统实现的可控性。

查看技能

requesting-code-review

设计

该Skill可在完成任务、实现主要功能或合并代码前自动调度代码审查子代理,确保实现符合需求和计划。它支持通过指定git SHA范围进行精准的代码变更审查,帮助开发者在关键节点及时发现潜在问题。核心原则是"早审查、勤审查",适用于开发流程的各个关键阶段。

查看技能

connect-mcp-server

设计

这个Skill指导开发者如何将MCP服务器连接到Claude Code,支持HTTP、stdio和SSE三种传输协议。它涵盖了从安装配置到认证安全的完整流程,适用于集成GitHub、Notion、数据库等外部服务。当开发者需要添加集成、配置外部工具或提及MCP相关功能时,这个Skill能提供实用的操作指南。

查看技能

web-cli-teleport

设计

该Skill帮助开发者根据任务特性选择Claude Code的Web或CLI界面,并指导如何在两种环境间无缝迁移会话。它能分析任务复杂度、迭代需求等要素,推荐最优工作界面和工作流。关键特性包括会话状态管理、环境切换指导和上下文优化建议。

查看技能