🐱 うさねこ教室 Python と可観測性の教室

ログを OTel に統合する

🐱 この章の目次

Logs Bridge API

OTel のログモデルは、既存のロギングライブラリを置き換えるのではなく「橋渡し(Bridge)」する設計です。 LoggerProvider がログの収集パイプラインを管理し、既存のログフレームワークから OTel フォーマットへ変換します。 Python では標準ライブラリの logging モジュールをそのまま活用できます。

pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp

LoggerProvider のセットアップ

from opentelemetry._logs import set_logger_provider
from opentelemetry.sdk._logs import LoggerProvider, LoggingHandler
from opentelemetry.sdk._logs.export import BatchLogRecordProcessor
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter

logger_provider = LoggerProvider()
logger_provider.add_log_record_processor(
    BatchLogRecordProcessor(OTLPLogExporter(endpoint="http://localhost:4317"))
)
set_logger_provider(logger_provider)

LogRecord は、タイムスタンプ・重大度・本文・属性・トレースコンテキストを含む構造化されたログエントリです。 BatchLogRecordProcessor によりバッファリングされ、OTLP で Collector またはバックエンドへ送信されます。

Python logging との統合

OTel SDK が提供する LoggingHandler を標準 logging に登録すると、既存のログ出力が自動的に OTel に流れます。

import logging
from opentelemetry.sdk._logs import LoggingHandler

handler = LoggingHandler(level=logging.INFO, logger_provider=logger_provider)
logging.getLogger().addHandler(handler)

# 通常どおり logging を使う
logger = logging.getLogger(__name__)
logger.info("Order created", extra={"order_id": "abc-123"})

extra で渡した値は LogRecord の属性として構造化されます。 既存コードの変更が最小限で済む点が、Bridge API の大きなメリットです。

トレースコンテキストの注入

OTel ログの真価は、トレースとの相関にあります。 アクティブな Span が存在する場合、LogRecord に trace_idspan_id が自動的に付与されます。

from opentelemetry import trace

tracer = trace.get_tracer(__name__)

with tracer.start_as_current_span("handle-request"):
    logger.info("Processing started")  # trace_id, span_id が自動付与
    # 処理ロジック
    logger.info("Processing completed")

バックエンド(Grafana など)でトレース ID をキーにログを横断検索できるため、障害調査が効率的になります。 ログとトレースを同一の Collector パイプラインで転送すれば、運用負荷も低減できます。