.NET ログとトレースの接続

トレースとスパンの ID がアプリケーションログに挿入されるようロギングライブラリおよび .NET トレーシングのコンフィギュレーションを設定し、ログデータと相関したアプリケーションのパフォーマンスモニタリングデータを取得することができます。

.NET トレーサーを統合サービスタグ付けで構成し、アプリケーションのトレースとログの相関付けに最高の使用体験と有用なコンテキストを確保します。

.NET トレーサーは、以下のロギングライブラリをサポートします。

はじめに

ログメッセージに相関関係のある識別子を挿入するには、お使いのロギングライブラリの指示に従ってください。

その他の例については、dd-trace-dotnet にあるサンプルを参照してください。
注: NET トレーサーバージョン 2.0.1 以降、Serilog ロギングライブラリの自動挿入には、アプリケーションが自動インスツルメンテーションされているれていることが必要になります。

ログメッセージに相関性のある識別子を自動的に挿入するには:

  1. 以下のトレーサー設定で .NET トレーサーを構成します。

    • DD_ENV
    • DD_SERVICE
    • DD_VERSION
  2. .NET Tracer のインストール手順に従って、アプリの自動インスツルメンテーショントレーシングを有効にします。

注: NET トレーサーバージョン 1.29.0 以降、log4net ロギングライブラリの自動挿入には、アプリケーションが自動インスツルメンテーションされているれていることが必要になります。

ログメッセージに相関性のある識別子を自動的に挿入するには:

  1. 以下のトレーサー設定で .NET トレーサーを構成します。

    • DD_ENV
    • DD_SERVICE
    • DD_VERSION
  2. .NET Tracer のインストール手順に従って、アプリの自動インスツルメンテーショントレーシングを有効にします。

  3. ログ出力に dd.envdd.servicedd.versiondd.trace_iddd.span_id のログプロパティを追加してください。これは、これらのプロパティを個別に含めることもできますし、すべてのログプロパティを含めることもできます。どちらの方法も、次のサンプルコードに示されています。

  <layout type="log4net.Layout.SerializedLayout, log4net.Ext.Json">
    <decorator type="log4net.Layout.Decorators.StandardTypesDecorator, log4net.Ext.Json" />
    <default />
    <!--明示的なデフォルトメンバー-->
    <remove value="ndc" />
    <!--書式設定済みのデフォルトメッセージメンバーを削除-->
    <remove value="message" />
    <!--未加工のメッセージを追加-->
    <member value="message:messageobject" />

    <!-- Datadog のプロパティを含める -->
    <!-- EITHER 個々のプロパティを value='<property_name>' で含める-->
    <member value='dd.env' />
    <member value='dd.service' />
    <member value='dd.version' />
    <member value='dd.trace_id' />
    <member value='dd.span_id' />
    <!-- OR value='properties' を持つすべてのプロパティを含める -->
    <member value='properties'/>
  </layout>

その他の例については、GitHub の log4net トレース ID 自動挿入プロジェクトを参照してください。

注: NET トレーサーバージョン 2.0.1 以降、NLog ロギングライブラリの自動挿入には、アプリケーションが自動インスツルメンテーションされているれていることが必要になります。

ログメッセージに相関性のある識別子を自動的に挿入するには:

  1. 以下のトレーサー設定で .NET トレーサーを構成します。

    • DD_ENV
    • DD_SERVICE
    • DD_VERSION
  2. .NET Tracer のインストール手順に従って、アプリの自動インスツルメンテーショントレーシングを有効にします。

  3. 次の NLog バージョン 4.6 向けのサンプルコードに示すように、マップされた診断コンテキスト (MDC) を有効にします。

  <!-- includeMdlc="true" を追加して MDC プロパティを表示 -->
  <layout xsi:type="JsonLayout" includeMdlc="true">
    <attribute name="date" layout="${longdate}" />
    <attribute name="level" layout="${level:upperCase=true}"/>
    <attribute name="message" layout="${message}" />
    <attribute name="exception" layout="${exception:format=ToString}" />
  </layout>

NLog バージョン 4.5 の場合

  <!-- includeMdc="true" を追加して MDC プロパティを表示 -->
  <layout xsi:type="JsonLayout" includeMdc="true">
    <attribute name="date" layout="${longdate}" />
    <attribute name="level" layout="${level:upperCase=true}"/>
    <attribute name="message" layout="${message}" />
    <attribute name="exception" layout="${exception:format=ToString}" />
  </layout>

その他の例については、GitHub で NLog 4.0NLog 4.5NLog 4.6 を使用したトレース ID 自動挿入プロジェクトを参照してください。

ログメッセージに相関性のある識別子を自動的に挿入するには:

  1. 以下のトレーサー設定で .NET トレーサーを構成します。

    • DD_ENV
    • DD_SERVICE
    • DD_VERSION
  2. .NET Tracer のインストール手順に従って、アプリの自動インスツルメンテーショントレーシングを有効にします。

  3. サンプルコードに示するように、お使いのロギングプロバイダーのログスコープを有効にします。ログスコープをサポートしているプロバイダーにのみ、相関関係のある識別子が挿入されます。

Host.CreateDefaultBuilder(args)
    .ConfigureLogging(logging =>
    {
        logging.AddFile(opts =>
        {
            opts.IncludeScopes = true; // 相関識別子が追加されるように、スコープを含む必要があります
            opts.FormatterName = "json";
        });
    }

ログが書き込まれているときにアクティブなトレースがあれば、トレースとスパン ID が dd_trace_id および dd_span_id プロパティと合わせて自動的にアプリケーションログに挿入されます。アクティブなトレースがない場合は、dd_envdd_servicedd_version プロパティのみが挿入されます。

注: Serilog.Extensions.HostingSerilog.Extensions.Loggingパッケージのように、デフォルトの LoggerFactory の実装を置き換えるロギングライブラリを使用している場合は、フレームワーク固有の指示に従ってください (この例では、Serilog をご参照ください)。

その他の例については、GitHub の Microsoft.Extensions.Logging トレース ID 自動挿入プロジェクトを参照してください。

次に、自動または手動挿入のセットアップを完了します。

自動挿入

相関識別子の自動挿入を有効にするための最後のステップは次の通りです。

  1. .NET トレーサーの環境変数で DD_LOGS_INJECTION=true を有効にします。.NET トレーサーを構成するその他の方法については、.NET トレーサーの構成をご参照ください。

相関識別子の挿入を構成した後、C# ログ収集を参照してログ収集の構成を行います。

注: トレースとログを関連付けるには、ログのトレース ID として dd_trace_id をパースするトレース ID リマッパーをセットアップする必要があるかもしれません。詳しくは、関連するログがトレース ID パネルに表示されないを参照してください。

手動挿入

トレースとログを手動で相関させたい場合は、ログに相関識別子を追加することができます。

必要なキー説明
dd.envトレーサー用に env をグローバルに構成します。設定されていない場合のデフォルトは "" となります。
dd.serviceルートサービス名をグローバルに構成します。設定されていない場合のデフォルトは、アプリケーションの名前または IIS サイト名となります。
dd.versionサービス用に version をグローバルに構成します。設定されていない場合のデフォルトは "" となります。
dd.trace_idログステートメント中のアクティブなトレース ID。トレースがない場合は 0 となります。
dd.span_idログステートメント中のアクティブなスパン ID。トレースがない場合は 0 となります。

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

: ILogger を通して Serilog、Nlog、log4net を使用している場合、BeginScope() を使用してこれらのプロパティを構成するには、Microsoft.Extensions.Logging セクションを見てください。

はじめのステップが完了したら、手動のログ加工設定を終了します。

  1. プロジェクトの Datadog.Trace NuGet パッケージを参照します。

  2. CorrelationIdentifier API を使用して相関識別子を取得し、スパンがアクティブな間にログのコンテキストに追加します。

最後に、C# ログ収集を参照して、ログ収集を構成します。

例:

: Serilog ライブラリでは、メッセージプロパティ名が有効な C# 識別子である必要があります。要求されるプロパティ名は、dd_envdd_servicedd_versiondd_trace_iddd_span_id です。

using Datadog.Trace;
using Serilog.Context;

// スパンはこのブロック以前に開始され、アクティブになっている必要があります。
using (LogContext.PushProperty("dd_env", CorrelationIdentifier.Env))
using (LogContext.PushProperty("dd_service", CorrelationIdentifier.Service))
using (LogContext.PushProperty("dd_version", CorrelationIdentifier.Version))
using (LogContext.PushProperty("dd_trace_id", CorrelationIdentifier.TraceId.ToString()))
using (LogContext.PushProperty("dd_span_id", CorrelationIdentifier.SpanId.ToString()))
{
    // 任意のログを記録
}
using Datadog.Trace;
using log4net;

// スパンはこのブロック以前に開始され、アクティブになっている必要があります。
try
{
    LogicalThreadContext.Properties["dd.env"] = CorrelationIdentifier.Env;
    LogicalThreadContext.Properties["dd.service"] = CorrelationIdentifier.Service;
    LogicalThreadContext.Properties["dd.version"] = CorrelationIdentifier.Version;
    LogicalThreadContext.Properties["dd.trace_id"] = CorrelationIdentifier.TraceId.ToString();
    LogicalThreadContext.Properties["dd.span_id"] = CorrelationIdentifier.SpanId.ToString();

    // 任意のログを記録

}
finally
{
    LogicalThreadContext.Properties.Remove("dd.env");
    LogicalThreadContext.Properties.Remove("dd.service");
    LogicalThreadContext.Properties.Remove("dd.version");
    LogicalThreadContext.Properties.Remove("dd.trace_id");
    LogicalThreadContext.Properties.Remove("dd.span_id");
}
using Datadog.Trace;
using NLog;

// スパンはこのブロック以前に開始され、アクティブになっている必要があります。
using (MappedDiagnosticsLogicalContext.SetScoped("dd.env", CorrelationIdentifier.Env))
using (MappedDiagnosticsLogicalContext.SetScoped("dd.service", CorrelationIdentifier.Service))
using (MappedDiagnosticsLogicalContext.SetScoped("dd.version", CorrelationIdentifier.Version))
using (MappedDiagnosticsLogicalContext.SetScoped("dd.trace_id", CorrelationIdentifier.TraceId.ToString()))
using (MappedDiagnosticsLogicalContext.SetScoped("dd.span_id", CorrelationIdentifier.SpanId.ToString()))
{
    // 任意のログを記録
}
using Datadog.Trace;
using Microsoft.Extensions.Logging;

ILogger _logger;

// スパンはこのブロック以前に開始され、アクティブになっている必要があります。
using(_logger.BeginScope(new Dictionary<string, object>
{
    {"dd.env", CorrelationIdentifier.Env},
    {"dd.service", CorrelationIdentifier.Service},
    {"dd.version", CorrelationIdentifier.Version},
    {"dd.trace_id", CorrelationIdentifier.TraceId.ToString()},
    {"dd.span_id", CorrelationIdentifier.SpanId.ToString()},
}))
{
    // 何かしらのログを記録
}

BeginScope を使用して、以下のログプロバイダーの構造化されたログメッセージを作成する方法については、こちらをご覧ください。

ログ収集の構成

ログパイプラインがログファイルをパースできるように、Datadog Agent でログ収集が構成され、追跡する指定ファイルの Logs Agent の構成source: csharp に設定されていることを確認します。詳細は、C# ログ収集を参照してください。sourcecsharp 以外の値に設定されている場合、相関を正しく動作させるために、適切なログ処理パイプラインにトレースリマッパーを追加する必要があるかもしれません。

注: 自動ログ挿入は、JSON でフォーマット化されたログのみに機能します。また、カスタムパースルールを使用することもできます。