技能创建器
skill-creator
创建、改进和评估自定义技能,把专业流程转化为可重复使用的 AI 能力。
instrument-distributed-tracing【数据与研究】Instrument applications with OpenTelemetry for distributed tracing, including auto and manual instrumentation, context propagation, sampling strategies, and integration with Jaeger or Tempo. Use when debugging latency issues in distributed systems, understanding request flow across microservices, correlating traces with logs and metrics for root caus…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
以 OpenTelemetry 施分散追蹤,跨微服務追請求,以辨性能之瓶頸。
完整配置檔案與樣板,見 Extended Examples。
佈 Jaeger 或 Grafana Tempo 以收存追蹤。
甲:Jaeger all-in-one(開發/測試用):
# 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
乙:Grafana Tempo(產線,可擴展):
# 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:
Tempo 之配置(tempo.yaml):
server:
http_listen_port: 3200
distributor:
receivers:
jaeger:
# ... (see EXAMPLES.md for complete configuration)
產線以 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
**得:**追蹤後端可達,備受 OTLP 追蹤之傳;Jaeger UI 或 Grafana 初顯「無追蹤」。
敗則:
netstat -tulpn | grep -E '(4317|16686|3200)'docker logs jaeger 或 docker logs tempocurl http://localhost:4318/v1/traces -vtempo -config.file=/etc/tempo.yaml -verify-config 驗配置語法用 OpenTelemetry 之自動佈儀於常見框架,以省改碼之勞。
Python 用 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 用 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 用 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)
**得:**已佈儀服務之追蹤現於 Jaeger UI 或 Grafana,HTTP 請求自動生 span。
敗則:
OTEL_EXPORTER_OTLP_ENDPOINT=http://tempo:4317OTEL_LOG_LEVEL=debug(Python)、OTEL_LOG_LEVEL=DEBUG(Node.js)為業務邏輯、資料庫查詢與外部呼叫建自訂 span。
Python 手動 span:
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)
Go 手動 span:
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)
span 屬性之善法:
http.method、http.status_code、db.system、db.statementuser.id、order.id、product.categoryinstance.id、region、availability_zonespan.RecordError(err) 與 span.SetStatus(codes.Error, message)span.AddEvent("cache_miss")**得:**自訂 span 現於追蹤視圖,父子關係正確,屬性於 span 詳情可見,錯誤顯明。
敗則:
defer span.End(),Python 用 with 區塊)確追蹤脈絡跨服務界與非同步作業無礙。
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)
訊息佇列傳播(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)
非同步作業(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)
**得:**追蹤跨數服務,trace ID 跨界一致,父子關係得保。
敗則:
otel.propagation.set_global_textmap(TraceContextTextMapPropagator())traceparent 標頭之值施抽樣以減追蹤之量與費,仍存可視。
抽樣策略:
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.sampling import (
ParentBased,
TraceIdRatioBased,
StaticSampler,
Decision
# ... (see EXAMPLES.md for complete configuration)
Tempo 之尾端抽樣:
於 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
以 Grafana Tempo 之 TraceQL 施動態抽樣:
# Sample traces with errors
{ status = error }
# Sample slow traces (>1s)
{ duration > 1s }
# Sample specific services
{ resource.service.name = "checkout-service" }
**得:**追蹤之量減至目標百分比,錯誤追蹤恆取樣,抽樣決策現於追蹤中繼。
敗則:
ingestion_burst_size_bytes)otel_traces_dropped_total 指標連追蹤、指標、日誌,成統一可觀測。
日誌加 trace ID(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)
自追蹤生指標(Tempo):
# tempo.yaml
metrics_generator:
registry:
external_labels:
cluster: production
storage:
# ... (see EXAMPLES.md for complete configuration)
此生 Prometheus 指標:
traces_service_graph_request_total — 服務間請求之數traces_span_metrics_duration_seconds — span 時距之直方圖traces_spanmetrics_calls_total — span 呼叫之數自指標查追蹤(Grafana):
於 Grafana 之 Prometheus 資料源添 exemplar 支援:
datasources:
- name: Prometheus
type: prometheus
url: http://prometheus:9090
jsonData:
exemplarTraceIdDestinations:
- name: trace_id
datasourceName: Tempo
於 Grafana 儀表板啟 exemplar:
{
"fieldConfig": {
"defaults": {
"custom": {
"showExemplars": true
}
}
}
}
**得:**點指標 exemplar 可開追蹤,日誌現 trace ID,追蹤連日誌,信號間除錯得一。
敗則:
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) and on() exemplarcontext 傳予下游呼叫,則追蹤斷。恆明傳脈絡。defer span.End()(Go)或 with 區塊(Python),span 不閉致記憶體洩漏。span.RecordError() 失珍貴除錯資訊。span 中恆記錯。ParentBased 取樣器以遵上游抽樣。correlate-observability-signals — 以 trace ID 連指標、日誌、追蹤,成統一除錯setup-prometheus-monitoring — 以 Tempo metrics generator 自追蹤生指標configure-log-aggregation — 日誌加 trace ID 以關聯分散追蹤build-grafana-dashboards — 於儀表板視覺化追蹤所生之指標與 exemplar 連結