Datadog API を使用した Python カスタム インスツルメンテーション
自動インスツルメンテーションのセットアップ手順をまだ読んでいない場合は、まず Python セットアップ手順 から始めてください。
対応するライブラリインスツルメンテーションを使用しない場合( ライブラリの互換性参照)、手動でコードをインスツルメントする必要があります。
ddtrace ライブラリの機能性を拡張したり、アプリケーションのインスツルメントをより精確に制御するのに役立つ方法がライブラリにあります。
スパンの作成
ddtrace ライブラリは、ddtrace-run で多くのライブラリとフレームワークに対応するスパンを自動生成します。しかし、使用しているコードを可視化したい場合はスパンの利用が便利です。
Web リクエスト (例: make_sandwich_request) 内で、get_ingredients()、assemble_sandwich() など、測定に役立つさまざまなオペレーションを行うことができます。
def make_sandwich_request(request):
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
ddtrace から提供される tracer.wrap() デコレータを使用して、対象の関数を修飾することができます。呼び出し場所に関わらずに関数をトレースしたい場合に便利です。
from ddtrace import tracer
@tracer.wrap(service="my-sandwich-making-svc", resource="resource_name")
def get_ingredients():
# パントリーに行く
# 冷蔵庫の中身を確認
# 足りないものは買い出し
return
# スパンのカスタマイズに必要な情報を共有
@tracer.wrap("assemble_sandwich", service="my-sandwich-making-svc", resource="resource_name")
def assemble_sandwich(ingredients):
return
詳しくは、ddtrace.Tracer.wrap() のデコレータの API 詳細をご覧ください。
また、src/Services/SampleRegistry.php もです。
from ddtrace import tracer
def make_sandwich_request(request):
# スパンで両方のオペレーションを取得
with tracer.trace("sandwich.make"):
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
def make_sandwich_request(request):
# スパンで両方のオペレーションを取得
with tracer.trace("sandwich.create", resource="resource_name") as outer_span:
with tracer.trace("get_ingredients", resource="resource_name") as span:
ingredients = get_ingredients()
with tracer.trace("assemble_sandwich", resource="resource_name") as span:
sandwich = assemble_sandwich(ingredients)
詳しくは、ddtrace.Tracer() の API 詳細全文をお読みください。
class SampleRegistry
{
public function put($key, $value)
{
\App\some_utility_function(‘some argument’);
// 挿入されたアイテムの ID を返す
return 456;
}
デコレータおよびコンテキストマネージャー以外のトレーシング方法として、スパンの開始と終了を可能にする手動 API があります。これに必要なのは、
def make_sandwich_request(request):
span = tracer.trace("sandwich.create", resource="resource_name")
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
span.finish() # ここでスパンを閉じる
デコレータの API 詳細については、ddtrace.Tracer.trace ドキュメントまたは ddtrace.Span.finish ドキュメントをお読みください。
アクティブなスパンへのアクセス
内蔵のインスツルメンテーションおよびカスタムインスツルメンテーションは、有意義なオペレーションに関連するスパンを作成します。アクティブなスパンにアクセスして、これらの有意義なデータを含めるよう設定できます。
from ddtrace import tracer
def make_sandwich_request(request):
# スパンで両方のオペレーションを取得
with tracer.trace("sandwich.make") as my_span:
ingredients = get_ingredients()
sandwich = assemble_sandwich(ingredients)
def get_ingredients():
# アクティブなスパンを取得
span = tracer.current_span()
# 上記の make_sandwich_request からの my_span
def assemble_sandwich(ingredients):
with tracer.trace("another.operation") as another_span:
# アクティブなルートスパンを取得
span = tracer.current_root_span()
# 上記の make_sandwich_request からの my_span
ddtrace ライブラリの機能性を拡張したり、アプリケーションのインスツルメントをより精確に制御するのに役立つ方法がライブラリにあります。
スパンに set_tag メソッドを適用して、スパンにタグを追加することができます。
from ddtrace import tracer
def make_sandwich_request(request):
with tracer.trace("sandwich.make") as span:
ingredients = get_ingredients()
span.set_tag("num_ingredients", len(ingredients))
タグはトレーサー上にグローバルに設定することができます。これらのタグは作成されるスパンのそれぞれに適用されます。
from ddtrace import tracer
from myapp import __version__
# これは各スパンに適用されます
tracer.set_tags({"version": __version__, "<TAG_KEY_2>": "<TAG_VALUE_2>"})
例外発生時点でアクティブなスパンが存在した場合は、その例外の情報がスパンに添付されます。
from ddtrace import tracer
with tracer.trace("throws.an.error") as span:
raise Exception("Oops!")
# `span` にエラーフラグを立て、
# スタックトレースと例外メッセージをタグとして追加
スパンへのエラーフラグ適用は、手動でも行うことができます。
from ddtrace import tracer
span = tracer.trace("operation")
span.error = 1
span.finish()
発生したエラーでローカル ルート スパンにフラグを付けたい場合:
import os
from ddtrace import tracer
try:
raise TypeError
except TypeError as e:
root_span = tracer.current_root_span()
(exc_type, exc_val, exc_tb) = sys.exc_info()
# エラー タイプを設定し、スパンをエラーとしてマークし、トレースバックを追加します
root_span.set_exc_info(exc_type, exc_val, exc_tb)
ヘッダー抽出と挿入によるコンテキストの伝搬
分散型トレーシングのコンテキストの伝搬は、ヘッダーの挿入と抽出で構成できます。詳しくはトレースコンテキストの伝播をお読みください。
Baggage
スパンの バゲージ を操作する:
from ddtrace import tracer
# 新しいスパンを開始し、バゲージを設定
with tracer.trace("example") as span:
# set_baggage_item
span.context.set_baggage_item("key1", "value1")
span.context.set_baggage_item("key2", "value2")
# get_all_baggage_items
all_baggage = span.context.get_all_baggage_items()
print(all_baggage) # {'key1': 'value1', 'key2': 'value2'}
# remove_baggage_item
span.context.remove_baggage_item("key1")
print(span.context.get_all_baggage_items()) # {'key2': 'value2'}
# get_baggage_item
print(span.context.get_baggage_item("key1")) # None
print(span.context.get_baggage_item("key2")) # value2
# remove_all_baggage_items
span.context.remove_all_baggage_items()
print(span.context.get_all_baggage_items()) # {}
動作例は、trace-examples の flask-baggage を参照してください。
ddtrace-api
ddtrace-api はプレビューです!
ddtrace-api Python パッケージはプレビュー段階であり、必要な API 呼び出しをすべて含まない場合があります。より完全な機能が必要な場合は、前のセクションで説明した API を使用してください。
以下の手順は、プレビュー版の ddtrace-api パッケージで試してみたい場合にのみ必要です。
ddtrace-api パッケージ は、Datadog APM のカスタム Python インスツルメンテーション向けに安定したパブリック API を提供します。このパッケージは API インターフェイスのみを実装し、Datadog にスパンを作成・送信する基盤の機能は実装しません。
インターフェイス (ddtrace-api) と実装 (ddtrace) を分離することで、次の利点があります:
- カスタム インスツルメンテーション向けに、変更頻度が低く予測しやすい API に依存できます。
- 自動インスツルメンテーションのみを使用する場合、API の変更を完全に無視できます。
- シングル ステップとカスタム インスツルメンテーションの両方を実装する場合でも、
ddtrace パッケージの複数コピーに依存せずに済みます。
ddtrace-api を使用するには:
ddtrace と ddtrace-api の両方のライブラリをインストールします:
pip install 'ddtrace>=3.1' ddtrace-api
Python のエントリ ポイント コマンドの前に ddtrace-run を付けて、Python アプリケーションをインスツルメントします:
ddtrace-run python app.py
セットアップ後は、前のセクションの例とまったく同じ要領でカスタム インスツルメンテーションを記述できますが、ddtrace ではなく ddtrace_api から import します。
例:
from ddtrace_api import tracer
@tracer.wrap(service="my-sandwich-making-svc", resource="resource_name")
def get_ingredients():
# go to the pantry
# go to the fridge
# maybe go to the store
return
サポートされている API 呼び出しの全一覧は、そのパッケージの API 定義 を参照してください。
その他の参考資料