ログを 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_id と span_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 パイプラインで転送すれば、運用負荷も低減できます。