mcpField
P
python-observability-ops

python-observability-ops

github.com/0xdarkmatter开发7835 次安装2 周前更新
代码仓库

关于 python-observability-ops

Python Observability Patterns 是一项技能,提供为 Python 应用添加日志、指标和追踪的示例与参考资料。内容涵盖 structlog、Prometheus 指标和 OpenTelemetry 追踪,面向维护生产服务的开发者。

主要功能

  1. 01使用 structlog 配置结构化日志
  2. 02传播请求上下文和 ID
  3. 03使用 prometheus-client 收集指标
  4. 04通过 OpenTelemetry 记录分布式追踪
  5. 05查阅参考指南和日志配置

适用场景

  1. 01为应用日志添加请求 ID
  2. 02跟踪请求数、错误和延迟
  3. 03追踪跨服务组件的请求

安装

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

$npx skills add https://github.com/0xdarkmatter/claude-mods --skill python-observability-ops

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

包含的文件

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

assets/
logging-config.py
references/
metrics.md
structured-logging.md
tracing.md
scripts/
.gitkeep

详细介绍

Python 可观测性模式

面向生产应用程序的日志记录、指标和追踪。

使用 structlog 进行结构化日志记录

import structlog

# Configure structlog
structlog.configure(
    processors=[
        structlog.contextvars.merge_contextvars,
        structlog.processors.add_log_level,
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.processors.JSONRenderer(),
    ],
    wrapper_class=structlog.make_filtering_bound_logger(logging.INFO),
    context_class=dict,
    logger_factory=structlog.PrintLoggerFactory(),
)

logger = structlog.get_logger()

# Usage
logger.info("user_created", user_id=123, email="[email protected]")
# Output: {"event": "user_created", "user_id": 123, "email": "[email protected]", "level": "info", "timestamp": "2024-01-15T10:00:00Z"}

请求上下文传播

import structlog
from contextvars import ContextVar
from uuid import uuid4

request_id_var: ContextVar[str] = ContextVar("request_id", default="")

def bind_request_context(request_id: str | None = None):
    """Bind request ID to logging context."""
    rid = request_id or str(uuid4())
    request_id_var.set(rid)
    structlog.contextvars.bind_contextvars(request_id=rid)
    return rid

# FastAPI middleware
@app.middleware("http")
async def request_context_middleware(request, call_next):
    request_id = request.headers.get("X-Request-ID") or str(uuid4())
    bind_request_context(request_id)
    response = await call_next(request)
    response.headers["X-Request-ID"] = request_id
    structlog.contextvars.clear_contextvars()
    return response

Prometheus 指标

from prometheus_client import Counter, Histogram, Gauge, generate_latest
from fastapi import FastAPI, Response

# Define metrics
REQUEST_COUNT = Counter(
    "http_requests_total",
    "Total HTTP requests",
    ["method", "endpoint", "status"]
)

REQUEST_LATENCY = Histogram(
    "http_request_duration_seconds",
    "HTTP request latency",
    ["method", "endpoint"],
    buckets=[0.01, 0.05, 0.1, 0.5, 1.0, 5.0]
)

ACTIVE_CONNECTIONS = Gauge(
    "active_connections",
    "Number of active connections"
)

# Middleware to record metrics
@app.middleware("http")
async def metrics_middleware(request, call_next):
    ACTIVE_CONNECTIONS.inc()
    start = time.perf_counter()

    response = await call_next(request)

    duration = time.perf_counter() - start
    REQUEST_COUNT.labels(
        method=request.method,
        endpoint=request.url.path,
        status=response.status_code
    ).inc()
    REQUEST_LATENCY.labels(
        method=request.method,
        endpoint=request.url.path
    ).observe(duration)
    ACTIVE_CONNECTIONS.dec()

    return response

# Metrics endpoint
@app.get("/metrics")
async def metrics():
    return Response(
        content=generate_latest(),
        media_type="text/plain"
    )

OpenTelemetry 追踪

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

# Setup
provider = TracerProvider()
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint="localhost:4317"))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)

tracer = trace.get_tracer(__name__)

# Manual instrumentation
async def process_order(order_id: int):
    with tracer.start_as_current_span("process_order") as span:
        span.set_attribute("order_id", order_id)

        with tracer.start_as_current_span("validate_order"):
            await validate(order_id)

        with tracer.start_as_current_span("charge_payment"):
            await charge(order_id)

快速参考

库用途
structlog结构化日志记录
prometheus-client指标收集
opentelemetry分布式追踪
指标类型使用场景
Counter请求总数、错误数
Histogram延迟、大小
Gauge当前连接数、队列大小

其他资源

  • ./references/structured-logging.md - structlog 配置、格式化器
  • ./references/metrics.md - Prometheus 模式、自定义指标
  • ./references/tracing.md - OpenTelemetry、分布式追踪

资源文件

  • ./assets/logging-config.py - 生产环境日志配置

另请参阅

前置条件:

  • python-async-ops - 异步上下文传播

相关技能:

  • python-fastapi-ops - 用于指标/追踪的 API 中间件
  • python-cli-ops - CLI 日志记录模式

集成技能:

  • python-database-ops - 数据库查询追踪

评论

支持 Markdown