instrument-distributed-tracing
정보
이 스킬은 개발자가 분산 추적을 위해 OpenTelemetry로 애플리케이션을 계측하는 데 도움을 줍니다. 자동 및 수동 계측, 컨텍스트 전파, 샘플링 전략, Jaeger나 Tempo와 같은 백엔드 통합을 다룹니다. 마이크로서비스의 지연 시간 문제를 디버깅하거나, 요청 흐름을 이해하거나, 추적을 로그/메트릭과 연관시키거나, 레거시 추적 시스템에서 마이그레이션하는 데 사용하세요.
빠른 설치
Claude Code
추천npx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/instrument-distributed-tracingClaude 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 jaegerodocker 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)yspan.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, bloqueswithen 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 serviciostraces_span_metrics_duration_seconds- histograma de duración de spanstraces_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
contexta las llamadas posteriores rompe las trazas. Siempre pasar el contexto explícitamente. - Spans nunca terminados: La falta de
defer span.End()(Go) o bloqueswith(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
ParentBasedpara respetar el muestreo ascendente.
Habilidades Relacionadas
correlate-observability-signals- Depuración unificada con métricas, logs y trazas vinculadas por IDs de trazasetup-prometheus-monitoring- Generar métricas desde trazas usando el generador de métricas de Tempoconfigure-log-aggregation- Agregar IDs de traza a los logs para correlación con trazas distribuidasbuild-grafana-dashboards- Visualizar métricas derivadas de trazas y vínculos de exemplares en dashboards
GitHub 저장소
연관 스킬
executing-plans
디자인executing-plans 스킬은 검토 체크포인트가 포함된 통제된 배치로 실행할 완전한 구현 계획이 있을 때 사용합니다. 이 스킬은 계획을 불러와 비판적으로 검토한 후, 소규모 배치(기본값 3개 작업)로 작업을 실행하면서 각 배치 사이에 진행 상황을 아키텍트 검토를 위해 보고합니다. 이를 통해 내재된 품질 관리 체크포인트를 갖춘 체계적인 구현이 보장됩니다.
requesting-code-review
디자인이 스킬은 코드 변경 사항을 요구 사항에 따라 분석하기 위해 코드 리뷰어 하위 에이전트를 호출합니다. 작업 완료 후, 주요 기능 구현 후, 또는 메인 브랜치에 병합하기 전에 사용해야 합니다. 이 리뷰는 현재 구현체와 원래 계획을 비교하여 문제를 조기에 발견하는 데 도움이 됩니다.
connect-mcp-server
디자인이 스킬은 개발자들이 HTTP, stdio 또는 SSE 전송 방식을 통해 MCP 서버를 Claude Code에 연결하는 포괄적인 가이드를 제공합니다. GitHub, Notion 및 사용자 정의 API와 같은 외부 서비스를 통합하기 위한 설치, 구성, 인증 및 보안을 다룹니다. MCP 통합 설정, 외부 도구 구성 또는 Claude의 모델 컨텍스트 프로토콜 작업 시 활용하세요.
web-cli-teleport
디자인이 스킬은 작업 분석을 기반으로 개발자가 Claude Code 웹 인터페이스와 CLI 인터페이스 중 선택할 수 있도록 돕고, 두 환경 간 원활한 세션 텔레포트를 가능하게 합니다. 웹, CLI 또는 모바일 환경 전환 시 세션 상태와 컨텍스트를 관리하여 워크플로를 최적화합니다. 다양한 단계에서 서로 다른 도구가 필요한 복잡한 프로젝트에 사용하세요.
