挿入可否

標準ライブラリロギング

トレースとログを相関付けるには、以下の手順を実行します。

  1. 自動インスツルメンテーションを有効にする.
  2. ログレコードから必要な属性を含める.

ステップ 1 - 自動インスツルメンテーションを有効にする

以下のいずれかのオプションを使用して、自動インスツルメンテーションを有効にします。

オプション 1: ライブラリインジェクション:

  1. アプリケーションの deployment/manifest ファイルで環境変数 DD_LOGS_INJECTION=true を設定します。
  2. ライブラリインジェクションの手順に従って、トレーシングを設定します。

オプション 2: ddtrace-run:

  1. アプリケーションを実行している環境で環境変数 DD_LOGS_INJECTION=true を設定します。
  2. ddtrace をアプリケーションにインポートします。
  3. ddtrace-run でアプリケーションを実行します (例: ddtrace-run python appname.py)。

オプション 3: patch:

  1. ddtrace をアプリケーションにインポートします。
  2. ddtrace.patch(logging=True) をアプリケーションコードの先頭に追加します。

ステップ 2 - 必要な属性を含める

ログレコードから必要な属性を含むように、ログフォーマットを更新します。

ログレコードの dd.envdd.servicedd.versiondd.trace_iddd.span_id 属性を、フォーマット文字列に含めます。

以下は、logging.basicConfig を使用して、ログ挿入の構成を行う例です。

import logging
from ddtrace import tracer

FORMAT = ('%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] '
          '[dd.service=%(dd.service)s dd.env=%(dd.env)s dd.version=%(dd.version)s dd.trace_id=%(dd.trace_id)s dd.span_id=%(dd.span_id)s] '
          '- %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger(__name__)
log.level = logging.INFO

@tracer.wrap()
def hello():
    log.info('Hello, World!')

hello()

ログインジェクションの詳細については、ddtrace のドキュメントをお読みください。

標準ライブラリロギングなし

標準ライブラリの logging モジュールを使用していない場合は、以下のコードスニペットを使用してトレーサー情報をログに挿入することができます。

from ddtrace import tracer

span = tracer.current_span()
correlation_ids = (str((1 << 64) - 1 & span.trace_id), span.span_id) if span else (None, None)

以下の例では、ログ出力にトレーサーフィールドを追加するために、structlog 内で processor として関数を定義しています。

import ddtrace
from ddtrace import tracer

import structlog

def tracer_injection(logger, log_method, event_dict):
    # 現在のトレーサーコンテキストから相関 ID を取得
    span = tracer.current_span()
    trace_id, span_id = (str((1 << 64) - 1 & span.trace_id), span.span_id) if span else (None, None)

    # structlog イベントの辞書に ID を追加
    event_dict['dd.trace_id'] = str(trace_id or 0)
    event_dict['dd.span_id'] = str(span_id or 0)

    # トレーサー用に構成された env、service、version を追加
    event_dict['dd.env'] = ddtrace.config.env or ""
    event_dict['dd.service'] = ddtrace.config.service or ""
    event_dict['dd.version'] = ddtrace.config.version or ""

    return event_dict

structlog.configure(
    processors=[
        tracer_injection,
        structlog.processors.JSONRenderer()
    ]
)
log = structlog.get_logger()

ロガーが構成されたら、イベントのログを取るトレースされた関数を実行すると、挿入されたトレーサー情報が得られます:

>>> traced_func()
{"event": "In tracer context", "dd.trace_id": 9982398928418628468, "dd.span_id": 10130028953923355146, "dd.env": "dev", "dd.service": "hello", "dd.version": "abc123"}

: Datadog ログインテグレーションを使ってログをパースしていない場合は、カスタムログパースルールによって dd.trace_iddd.span_id が文字列としてパースされ、トレースリマッパーを使って再マップされていることを確実にする必要があります。詳細については、関連するログがトレース ID パネルに表示されないを参照してください。

Python ロギングのドキュメントを参照して Python ログインテグレーションを適切に構成し、Python ログが自動的にパースされるようにしてください。

その他の参考資料