Splunk Observability Cloud 用 .NET Azure WebJobs をインストルメンテーションする
OpenTelemetry .NET SDK を使用して、Azure WebJobs 上で実行されているアプリケーションまたはサービスをインストルメンテーションすることができます。開始するには、次の手順を実行します。
OpenTelemetry .NET SDK を使用して、Azure WebJobs 上で実行されているアプリケーションまたはサービスをインストルメンテーションすることができます。開始するには、次の手順を実行します。
環境変数の定義
アプリケーションに必要な環境変数を設定します。
-
Azure Web App でアプリケーションを選択します。
-
に進みます。
-
New application setting を選択し、以下の設定を追加します:
Name
値
SPLUNK_ACCESS_TOKENSplunk アクセストークン。アクセストークンを取得するには、「Splunk Observability Cloud を使用したユーザー API アクセストークンの取得と管理」を参照してください。
SPLUNK_REALMSplunk Observability Cloud のレルム(
us0など)。レルムを見つけるには、「 Configure SSO integrations for Splunk Observability Cloud」を参照してください。 -
その他必要な設定を追加します。「Splunk Distribution of OpenTelemetry .NET を設定する」を参照してください。
NuGetを使って必要なライブラリを追加する
Visual Studio の NuGet パッケージマネージャを使用して、以下のライブラリを追加します。
分離されたワーカープロセス機能
-
Include prerelease 設定をアクティブ化します。
-
以下のライブラリの最新版をインストールします:
コード内でOpenTelemetryを初期化する
- 依存関係を追加したら、アプリケーション用の OpenTelemetry ヘルパーを作成します:
using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Host; using Microsoft.Extensions.DependencyInjection; using OpenTelemetry.Exporter; using OpenTelemetry.Metrics; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using System.Diagnostics; namespace <YourNamespaceHere>.Helpers; internal static class SplunkOpenTelemetry { private static readonly string AccessToken; private static readonly string Realm; static SplunkOpenTelemetry() { 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 IWebJobsBuilder AddSplunkOpenTelemetry(this IWebJobsBuilder builder) { // Get environment variables from function configuration // You need a valid Splunk Observability Cloud access token and realm var serviceName = Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME") ?? "Unknown"; var enableTraceResponseHeaderValue = Environment.GetEnvironmentVariable("SPLUNK_TRACE_RESPONSE_HEADER_ENABLED")?.Trim(); builder.Services.AddOpenTelemetry() .ConfigureResource(cfg => cfg // See https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/main/src/OpenTelemetry.Resources.Azure // for other types of Azure detectors .AddAzureAppServiceDetector() .AddService(serviceName: serviceName, serviceVersion: "1.0.0")) .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; }) // Use AddSource to add your custom DiagnosticSource source names //.AddSource("My.Source.Name") // Automatically creates the root span with function start .AddSource(SplunkFunctionAttribute.ActivitySourceName) .SetSampler(new AlwaysOnSampler()) .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 .AddHttpClientInstrumentation() .AddRuntimeInstrumentation() .AddProcessInstrumentation() .AddOtlpExporter(opts => { opts.Endpoint = new Uri($"https://ingest.{Realm}.signalfx.com/v2/datapoint/otlp"); opts.Headers = $"X-SF-TOKEN={AccessToken}"; })); return builder; } } internal class SplunkFunctionAttribute : FunctionInvocationFilterAttribute { public const string ActivitySourceName = "Splunk.Azure.WebJob"; private static readonly ActivitySource ActivitySource = new(ActivitySourceName); private Activity? _currentActivity; public override Task OnExecutingAsync(FunctionExecutingContext executingContext, CancellationToken cancellationToken) { _currentActivity = ActivitySource.StartActivity(executingContext.FunctionName, ActivityKind.Server); _currentActivity?.AddTag("faas.name", executingContext.FunctionName); _currentActivity?.AddTag("faas.instance", executingContext.FunctionInstanceId); return base.OnExecutingAsync(executingContext, cancellationToken); } public override Task OnExecutedAsync(FunctionExecutedContext executedContext, CancellationToken cancellationToken) { if (!executedContext.FunctionResult.Succeeded) { if (executedContext.FunctionResult.Exception != null) { _currentActivity?.SetStatus(Status.Error.WithDescription(executedContext.FunctionResult.Exception.Message)); _currentActivity?.RecordException(executedContext.FunctionResult.Exception); } else { _currentActivity?.SetStatus(Status.Error); } } _currentActivity?.Stop(); return base.OnExecutedAsync(executedContext, cancellationToken); } } - Program.cs ファイルで作成したヘルパーを使用します:
var builder = new HostBuilder() .ConfigureWebJobs(context => { context.AddSplunkOpenTelemetry(); }) - SplunkFunctionAttribute は、定義されたすべての WebJobs 関数で使用します。関数に適切に属性を設定する方法の例を参照してください。
public class Functions { [SplunkFunction] public void ProcessTimer([TimerTrigger("1/5 * * * * *")] TimerInfo timerInfo, ILogger logger) { logger.LogInformation("Hello World!"); } }
データが入力されていることを確認する
関数を実行し、Splunk APM でスパンを検索します。詳細については、「トレース内でのスパンの表示およびフィルタリング」を参照してください。
トラブルシューティング
__ ___ ___ _ ______ _____________ _____ ________ ___ ___ ___ ____ __ ___ ____ ____ __ ______ _____________ ______ ___ ___ ___ ____ __ ___ _________ _____
_________ __ ______ _____________ _____ _________
-
______ _ ____ __ ___ ______ _______ _______
-
_______ ______ ________
_________ __ ___________ _________ ___ ____ _____ _____
-
___ _ ________ ___ ___ _______ _______ _________ _______ __ ______ ________
-
____ ___ ______ ______________ ____ _____ _____ _______ __ ___________ ____ __________ _________ ___ ______ _________ __________ __ _____ ___ ____ _______