mcpField
P
python-observability-ops

python-observability-ops

github.com/0xdarkmatter開発7835 回インストール2 週間前に更新
リポジトリ

python-observability-ops について

Python Observability Patternsは、Pythonアプリケーションにログ、メトリクス、トレースを導入する例と資料をまとめたスキルです。structlog、Prometheusのメトリクス、OpenTelemetryのトレースを扱い、本番サービスを運用する開発者向けです。

主な機能

  1. 01structlogで構造化ログを設定
  2. 02リクエストコンテキストとIDを伝播
  3. 03prometheus-clientでメトリクスを収集
  4. 04OpenTelemetryで分散トレースを計測
  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 - データベースクエリのトレーシング

コメント