- 重要な情報
- はじめに
- 用語集
- エージェント
- インテグレーション
- OpenTelemetry
- 開発者
- API
- CoScreen
- アプリ内
- インフラストラクチャー
- アプリケーションパフォーマンス
- 継続的インテグレーション
- ログ管理
- セキュリティ
- UX モニタリング
- 管理
このページでは、Datadog APM で可観測性を追加・カスタマイズするための一般的なユースケースを詳しく説明します。サポートされているランタイムの一覧は、.NET Framework 互換性要件または .NET Core 互換性要件を参照してください。
デフォルトの自動インスツルメンテーション以上を取得するためには、いくつかの方法があります。
これらのソリューションを互いに組み合わせることで、求めるインスツルメンテーションの精度を実現することができます。
環境変数 DD_TRACE_METHODS
を使用すると、アプリケーションコードを変更せずに、サポートされていないフレームワークを可視化することができます。DD_TRACE_METHODS
の入力フォーマットの詳細については、.NET Framework 構成手順または .NET Core 構成手順を参照してください。例えば、Store.Managers.SessionManager
型で定義された SaveSession
というメソッドをインスツルメンテーションするには、次のように設定します。
DD_TRACE_METHODS=Store.Managers.SessionManager[SaveSession]
結果として得られるスパンは、trace.annotation
という値を持つ operationName
属性と SaveSession
という値を持つ resourceName
属性を持っています。
スパンの属性をカスタマイズしたい場合で、ソースコードを修正する能力がある場合は、代わりに属性を通してメソッドをインスツルメントすることが可能です。
Datadog.Trace.Annotations
NuGet パッケージを追加し、自動インスツルメンテーションを設定する必要があります。.NET トレーサーのセットアップ方法と自動インスツルメンテーションの有効化については、.NET Framework セットアップ手順または .NET Core セットアップ手順を参照してください。Datadog が自動インスツルメンテーションを行う際に、メソッドに [Trace]
を追加し、トレースするようにします。自動インスツルメンテーションが有効でない場合、この属性はアプリケーションに何の影響も及ぼしません。
[Trace]
属性はデフォルトのオペレーション名 trace.annotation
とトレースされるメソッドのリソース名を持っています。操作名とリソース名を [Trace]
属性の名前付き引数として設定することで、インスツルメンテーションされる内容をより良く反映させることができます。[Trace]
属性に設定できる引数は、オペレーション名とリソース名のみです。例:
using Datadog.Trace.Annotations;
namespace Store.Managers
{
public class SessionManager
{
[Trace(OperationName = "database.persist", ResourceName = "SessionManager.SaveSession")]
public static void SaveSession()
{
// ここにメソッドの実装
}
}
}
Datadog.Trace
NuGet パッケージをアプリケーションに追加する必要があります。これは、トレーサーとアクティブスパンに直接アクセスするための API を提供します。Datadog.Trace
NuGet パッケージと自動インスツルメンテーションの両方を使用する場合、バージョンを同期させることが重要です。アプリケーションを構成する方法は複数あります。環境変数、web.config
ファイル、datadog.json
ファイルを使用する方法があり、 ドキュメントで説明されています。また、Datadog.Trace
NuGet パッケージでは、コード内で構成を行うことができます。
構成設定をオーバーライドするには、TracerSettings
のインスタンスを作成して、静的な Tracer.Configure()
メソッドに渡します。
using Datadog.Trace;
// 既存の環境変数と構成ソースを使用して
// 設定オブジェクトを作成します
var settings = TracerSettings.FromDefaultSources();
// 値をオーバーライドします
settings.GlobalTags.Add("SomeKey", "SomeValue");
// トレーサーの構成を置き換えます
Tracer.Configure(settings);
Tracer.Configure()
を呼び出すと、カスタムインスツルメンテーションでも自動インスツルメンテーションでも、それ以降のすべてのトレースの設定が置き換わります。
自動インスツルメンテーション、 [Trace]
属性、DD_TRACE_METHODS
の構成に加えて、プログラム的に任意のコードブロックの周りにスパンを作成することで、観測可能性をカスタマイズすることが可能です。
カスタムスパンを作成してアクティブにするには、Tracer.Instance.StartActive()
を使用します。トレースがすでにアクティブな場合 (例えば、自動インスツルメンテーションによって作成された場合)、スパンは現在のトレースの一部となります。現在のトレースがない場合は、新しいトレースが開始されます。
StartActive
から返されたスコープを確実にディスポーズしてください。スコープをディスポーズすると、スパンが閉じられ、そのスパンがすべて閉じられると、トレースが Datadog にフラッシュされるようになります。using Datadog.Trace;
// 新しいスパンを開始します
using (var scope = Tracer.Instance.StartActive("custom-operation"))
{
// 操作を実行します
}
カスタムスパンタグをスパンに追加して、Datadog 内の可観測性をカスタマイズします。スパンタグは受信トレースに適用されるため、観測された動作を、マーチャントの階層、チェックアウト金額、ユーザー ID などのコードレベルの情報と関連付けることができます。
手動で作成したスパンは、他のトレースメカニズムからのスパンと自動的にインテグレーションされます。つまり、トレースがすでに開始されている場合、手動スパンはその呼び出し元を親スパンとして持っています。同様に、ラップされたコードブロックから呼び出されたトレースされたメソッドは、その親として手動スパンを持ちます。
using (var parentScope =
Tracer.Instance.StartActive("manual.sortorders"))
{
parentScope.Span.ResourceName = "<RESOURCE NAME>";
using (var childScope =
Tracer.Instance.StartActive("manual.sortorders.child"))
{
// トレースするコードの周囲にあるステートメントを使用してネストします
childScope.Span.ResourceName = "<RESOURCE NAME>";
SortOrders();
}
}
customer.id
などのアプリケーションコード内の動的な値に対応するカスタムタグをスパンに追加します。
using Datadog.Trace;
public class ShoppingCartController : Controller
{
private IShoppingCartRepository _shoppingCartRepository;
[HttpGet]
public IActionResult Index(int customerId)
{
// グローバルトレーサーでアクティブスコープにアクセスする
// 注: アクティブなスパンが存在しない場合は null を返すことがあります
var scope = Tracer.Instance.ActiveScope;
if (scope != null)
{
// Datadog の Web UI で使用するためのタグをスパンに追加する
scope.Span.SetTag("customer.id", customerId.ToString());
}
var cart = _shoppingCartRepository.Get(customerId);
return View(cart);
}
}
コードで発生したエラーをマークするには、Span.SetException(Exception)
メソッドを使用します。このメソッドは、スパンをエラーとしてマークし、関連するスパンメタデータを追加して、例外の情報を提供します。
try
{
// 例外をスローする可能性のある作業を行います
}
catch(Exception e)
{
span.SetException(e);
}
これは、スパンに以下のタグを設定します。
"error.msg":exception.Message
"error.stack":exception.ToString()
"error.type":exception.GetType().ToString()
Datadog APM トレーサーは、分散型トレーシングのための B3 と W3C のヘッダー抽出と注入をサポートしています。詳細については、セットアップドキュメントを参照してください。
ほとんどの場合、ヘッダーの抽出と注入は透過的に行われます。分散トレースが切断される可能性があるケースも知られています。例えば、分散キューからメッセージを読み込むとき、ライブラリによってはスパンコンテキストを失うことがあります。また、Kafka メッセージを消費する際に DD_TRACE_KAFKA_CREATE_CONSUMER_SCOPE_ENABLED
を false
に設定した場合にも発生することがあります。そのような場合、以下のコードを使ってカスタムトレースを追加することができます。
var spanContextExtractor = new SpanContextExtractor();
var parentContext = spanContextExtractor.Extract(headers, (headers, key) => GetHeaderValues(headers, key));
var spanCreationSettings = new SpanCreationSettings() { Parent = parentContext };
using var scope = Tracer.Instance.StartActive("operation", spanCreationSettings);
GetHeaderValues
メソッドを提供します。このメソッドの実装方法は、SpanContext
を保持する構造に依存します。
以下はその例です。
// Confluent.Kafka
IEnumerable<string> GetHeaderValues(Headers headers, string name)
{
if (headers.TryGetLastBytes(name, out var bytes))
{
try
{
return new[] { Encoding.UTF8.GetString(bytes) };
}
catch (Exception)
{
// 無視
}
}
return Enumerable.Empty<string>();
}
// RabbitMQ
IEnumerable<string> GetHeaderValues(IDictionary<string, object> headers, string name)
{
if (headers.TryGetValue(name, out object value) && value is byte[] bytes)
{
return new[] { Encoding.UTF8.GetString(bytes) };
}
return Enumerable.Empty<string>();
}
Kafka コンシューマースパンをトレースするために SpanContextExtractor
API を使用する場合、DD_TRACE_KAFKA_CREATE_CONSUMER_SCOPE_ENABLED
を false
に設定します。これにより、メッセージがトピックから消費された直後にコンシューマースパンが正しく閉じられ、メタデータ (partition
や offset
など) が正しく記録されることが保証されます。SpanContextExtractor
API を使用して Kafka メッセージから作成されたスパンは、プロデューサーのスパンの子であり、コンシューマーのスパンの兄弟になります。
DD_TAGS
環境変数を使用して、アプリケーションに対して生成されたすべてのスパンにタグを設定します。これは、Datadog UI 内でアプリケーション、データセンター、または地域の統計データをグループ化するのに役立ちます。例:
DD_TAGS=datacenter:njc,key2:value2
リソース名に基づいてトレースを除外することで、ヘルスチェックなどの Synthetic トラフィックを削除することができます。セキュリティや追加構成については、データセキュリティのための Datadog Agent またはトレーサーの構成を参照してください。