Docs » Splunk Observability Cloud でサポートされているインテグレーション » バックエンドアプリケーションをインストルメンテーションして、スパンを Splunk APM に送信する » Splunk Observability Cloud (OpenTelemetry) 用 .NET アプリケーションのインストルメンテーション » Splunk Observability Cloud 用 .NET Azure Web App をインストルメンテーションする

Splunk Observability Cloud 用 .NET Azure Web App をインストルメンテーションする 🔗

OpenTelemetry .NET SDK を使って、Azure Web App Service 上で動作するアプリケーションやサービスをインストルメンテーションすることができます。以下の手順に従ってください。

環境変数の定義 🔗

アプリケーションに必要な環境変数を設定します。

  1. Azure Web App でアプリケーションを選択します。

  2. SettingsConfiguration にアクセスします。

  3. New application setting を選択し、以下の設定を追加します:

    Name

    SPLUNK_ACCESS_TOKEN

    Splunk アクセストークン。アクセストークンを取得するには、Splunk Observability Cloudを使用したユーザー APIアクセストークンの取得と管理 を参照してください。

    SPLUNK_REALM

    Splunk Observability Cloud のレルム、例えば us0。自分のレルムを見つけるには、レルムについての注意 を参照してください。

    SPLUNK_TRACE_RESPONSE_HEADER_ENABLED

    Splunk RUM との統合を有効にするかどうか。デフォルト値は false です。

  4. その他必要な設定を追加してください。Splunk Distribution of OpenTelemetry .NET を設定する を参照してください。

NuGetを使って必要なライブラリを追加する 🔗

Visual Studio の NuGet パッケージマネージャを使用して、以下のライブラリを追加します。

分離されたワーカープロセス機能 🔗

  1. Include prerelease 設定を有効にします。

  2. 以下のライブラリの最新版をインストールします:

コード内でOpenTelemetryを初期化する 🔗

依存関係を追加したら、アプリケーション用の OpenTelemetry ヘルパーを作成します:

using OpenTelemetry.Exporter;
using OpenTelemetry.Metrics;
using OpenTelemetry.ResourceDetectors.Azure;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using System.Diagnostics;

namespace <YourNamespaceHere>.Extensions;

public static class SplunkOpenTelemetry
{
    private static readonly string AccessToken;
    private static readonly string Realm;

    static SplunkOpenTelemetry()
    {
        // Get environment variables from function configuration
        // You need a valid Splunk Observability Cloud access token and realm
        AccessToken = Environment.GetEnvironmentVariable("SPLUNK_ACCESS_TOKEN")?.Trim()
            ?? throw new ArgumentNullException("SPLUNK_ACCESS_TOKEN");

        Realm = Environment.GetEnvironmentVariable("SPLUNK_REALM")?.Trim()
            ?? throw new ArgumentNullException("SPLUNK_REALM");
    }

    public static WebApplicationBuilder AddSplunkOpenTelemetry(this WebApplicationBuilder builder)
    {
        var serviceName = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME") ?? "Unknown";
        var enableTraceResponseHeaderValue = Environment.GetEnvironmentVariable("SPLUNK_TRACE_RESPONSE_HEADER_ENABLED")?.Trim();

        // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.ResourceDetectors.Azure
        // for other types of Azure detectors
        var resourceDetector = new AppServiceResourceDetector();

        builder.Services.AddOpenTelemetry()
            .WithTracing(t => t
                // Use Add[instrumentation-name]Instrumentation to instrument missing services
                // Use Nuget to find different instrumentation libraries
                .AddHttpClientInstrumentation(opts =>
                {
                    // This filter prevents background (parent-less) http client activity
                    opts.FilterHttpWebRequest = req => Activity.Current?.Parent != null;
                    opts.FilterHttpRequestMessage = req => Activity.Current?.Parent != null;
                })
                .AddAspNetCoreInstrumentation(opts =>
                {
                    // Enables Splunk RUM integration when configuration contains SPLUNK_TRACE_RESPONSE_HEADER_ENABLED=True
                    if (bool.TryParse(enableTraceResponseHeaderValue, out bool isEnabled) && isEnabled)
                    {
                        opts.EnrichWithHttpRequest = (activity, request) =>
                        {
                            var response = request.HttpContext.Response;
                            ServerTimingHeader.SetHeaders(activity, response.Headers, (headers, key, value) =>
                            {
                                headers.TryAdd(key, value);
                            });
                        };
                    }
                })
                // Use AddSource to add your custom DiagnosticSource source names
                //.AddSource("My.Source.Name")
                .SetSampler(new AlwaysOnSampler())
                .ConfigureResource(cfg => cfg
                    .AddService(serviceName: serviceName, serviceVersion: "1.0.0")
                    .AddDetector(resourceDetector))
                .AddOtlpExporter(opts =>
                {
                    opts.Endpoint = new Uri($"https://ingest.{Realm}.signalfx.com/v2/trace/otlp");
                    opts.Protocol = OtlpExportProtocol.HttpProtobuf;
                    opts.Headers = $"X-SF-TOKEN={AccessToken}";
                }))
            .WithMetrics(m => m
                // Use Add[instrumentation-name]Instrumentation to instrument missing services
                // Use Nuget to find different instrumentation libraries
                .AddAspNetCoreInstrumentation()
                .AddHttpClientInstrumentation()
                .AddRuntimeInstrumentation()
                .AddProcessInstrumentation()
                .ConfigureResource(cfg => cfg
                    .AddService(serviceName: serviceName, serviceVersion: "1.0.0")
                    .AddDetector(resourceDetector))
                .AddOtlpExporter(opts =>
                {
                    opts.Endpoint = new Uri($"https://ingest.{Realm}.signalfx.com/v2/datapoint/otlp");
                    opts.Headers = $"X-SF-TOKEN={AccessToken}";
                }));

        return builder;
    }

    private static class ServerTimingHeader
    {
        private const string Key = "Server-Timing";
        private const string ExposeHeadersHeaderName = "Access-Control-Expose-Headers";

        public static void SetHeaders<T>(Activity activity, T carrier, Action<T, string, string> setter)
        {
            setter(carrier, Key, ToHeaderValue(activity));
            setter(carrier, ExposeHeadersHeaderName, Key);
        }

        private static string ToHeaderValue(Activity activity)
        {
            var sampled = ((int)activity.Context.TraceFlags).ToString("D2");
            return $"traceparent;desc=\"00-{activity.TraceId}-{activity.SpanId}-{sampled}\"";
        }
    }
}

Program.cs ファイルで作成したヘルパーを使用します:

var builder = WebApplication.CreateBuilder(args);
var app = builder
    .AddSplunkOpenTelemetry()
    .Build()

データが入力されていることを確認する 🔗

関数を実行し、Splunk APM でスパンを検索します。詳細は トレース内でのスパンの表示およびフィルタリング を参照してください。

トラブルシューティング 🔗

Splunk Observability Cloudをご利用のお客様で、Splunk Observability Cloudでデータを確認できない場合は、以下の方法でサポートを受けることができます。

Splunk Observability Cloudをご利用のお客様

見込み客および無料トライアルユーザー様

  • Splunk Answers のコミュニティサポートで質問し、回答を得る

  • Splunk #observability ユーザーグループの Slack チャンネルに参加して、世界中の顧客、パートナー、Splunk 社員とのコミュニケーションを図る。参加するには、Get Started with Splunk Community マニュアルの チャットグループ を参照してください。

This page was last updated on 2024年09月18日.