次の方法で共有


ASP.NET Core SignalR でのログと診断

提供 : Andrew AndrewTon-Nurse

この記事では、問題のトラブルシューティングに役立つ診断情報を ASP.NET Core SignalR アプリから収集するためのガイダンスを提供します。

サーバー側のログ

警告

サーバー側のログには、アプリからの機密情報が含まれる場合があります。 運用アプリから GitHub などのパブリック フォーラムに未加工のログを投稿しないでください

SignalR は ASP.NET Core の一部であるため、ASP.NET Core のログ システムが使われます。 既定の構成では、最小限 SignalR 情報をログに記録しますが、ログ レベルを構成できます。 ASP.NET Core ログの構成の詳細については、ASP.NET Core ログに関するドキュメントを参照してください。

SignalR では 2 つのロガー カテゴリが使われます。

  • Microsoft.AspNetCore.SignalR: ハブ プロトコル、ハブのアクティブ化、メソッドの呼び出し、その他のハブ関連アクティビティに関連するログの場合。
  • Microsoft.AspNetCore.Http.Connections: WebSocket、長いポーリング、Server-Sent イベント、低レベルの SignalR インフラストラクチャなど、トランスポートに関連するログの場合。

SignalRから詳細なログを有効にするには、Debugappsettings.jsonサブセクションに次の項目を追加して、上記の両方のプレフィックスをLogLevel ファイルのLogging レベルに構成します。

{
    "Logging": {
        "LogLevel": {
            "Default": "Debug",
            "System": "Information",
            "Microsoft": "Information",
            "Microsoft.AspNetCore.SignalR": "Debug",
            "Microsoft.AspNetCore.Http.Connections": "Debug"
        }
    }
}

SignalR ロガー カテゴリのログ 記録レベルは、CreateWebHostBuilder メソッド内のコードで構成することもできます。

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
            logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
        })
        .UseStartup<Startup>();

JSON ベースの構成を使用していない場合は、構成システム内に次の構成値を設定します。

  • Logging:LogLevel:Microsoft.AspNetCore.SignalR = Debug
  • Logging:LogLevel:Microsoft.AspNetCore.Http.Connections = Debug

構成システムのドキュメントを調べて、入れ子になった構成値を指定する方法を確認してください。 たとえば、環境変数の使用時には、_ の代わりに 2 つの : 文字を使用します (例: Logging__LogLevel__Microsoft.AspNetCore.SignalR)。

アプリのより詳細な診断情報を収集する場合は、Debug レベルを使用することが推奨されます。 Trace レベルでは低レベルの診断が生成され、アプリの問題を診断するために必要になることはほとんどありません。

サーバー側ログにアクセスする

サーバー側のログにアクセスする方法は、アプリが実行されている環境によって異なります。

IIS の外部のコンソール アプリとして

コンソール アプリで実行中の場合は、コンソール ロガーを既定で有効にする必要があります。 SignalR ログがコンソールに表示されます。

Visual Studio から IIS Express 内で

Visual Studio の [出力] ウィンドウにログの出力が表示されます。 [ASP.NET Core Web サーバー] ドロップダウン オプションを選びます。

Azure App Service

Azure App Service ポータルの [診断ログ] セクションで [アプリケーション ログ (ファイル システム)] オプションを有効にし、[レベル] を [Verbose] に構成します。 ログは、ログ ストリーミング サービスから、および App Service のファイル システムのログで、使用できます。 詳しくは、「Azure ログのストリーミング」をご覧ください。

その他の環境

Docker、Kubernetes、Windows Service などのさまざまなデプロイ環境に適したログ プロバイダーの構成の詳細については、「 .NET Core と ASP.NET Core でのログ記録」を参照してください。

JavaScript クライアントのログ記録

警告

クライアント側のログには、アプリからの機密情報が含まれる場合があります。 運用アプリから GitHub などのパブリック フォーラムに未加工のログを投稿しないでください

JavaScript クライアントを使用するときは、configureLoggingHubConnectionBuilder メソッドを使ってログ オプションを構成できます。

let connection = new signalR.HubConnectionBuilder()
    .withUrl("/my/hub/url")
    .configureLogging(signalR.LogLevel.Debug)
    .build();

signalR.LogLevel.None メソッドでconfigureLoggingを指定して、フレームワークのログ記録を無効にします。 一部のログはブラウザーによって直接出力され、ログ レベルの設定では無効にできないことに注意してください。

次の表は、JavaScript クライアントで使用できるログ レベルです。 ログ レベルをこれらの値のいずれかに設定すると、そのレベルおよび表でそれより上にあるすべてのレベルのログが有効になります。

レベル 説明
None メッセージはログに記録されません。
Critical アプリ全体でのエラーを示すメッセージ。
Error 現在の操作でのエラーを示すメッセージ。
Warning 致命的ではない問題を示すメッセージ。
Information 情報メッセージ。
Debug デバッグに役立つ診断メッセージ。
Trace 特定の問題を診断するために設計された、非常に詳細な診断メッセージ。

詳細さを構成すると、ログがブラウザー コンソール (または NodeJS アプリの標準出力) に書き込まれるようになります。

カスタム ログ システムにログを送信する場合は、ILogger インターフェイスを実装する JavaScript オブジェクトを指定できます。 実装する必要のあるメソッドは、イベントのレベルとイベントに関連付けられたメッセージを受け取る log だけです。 次に例を示します。

import { ILogger, LogLevel, HubConnectionBuilder } from "@microsoft/signalr";

export class MyLogger implements ILogger {
    log(logLevel: LogLevel, message: string) {
        // Use `message` and `logLevel` to record the log message to your own system
    }
}

// later on, when configuring your connection...

let connection = new HubConnectionBuilder()
    .withUrl("/my/hub/url")
    .configureLogging(new MyLogger())
    .build();
import { ILogger, LogLevel, HubConnectionBuilder } from "@aspnet/signalr";

export class MyLogger implements ILogger {
    log(logLevel: LogLevel, message: string) {
        // Use `message` and `logLevel` to record the log message to your own system
    }
}

// later on, when configuring your connection...

let connection = new HubConnectionBuilder()
    .withUrl("/my/hub/url")
    .configureLogging(new MyLogger())
    .build();

.NET クライアントのログ記録

警告

クライアント側のログには、アプリからの機密情報が含まれる場合があります。 運用アプリから GitHub などのパブリック フォーラムに未加工のログを投稿しないでください

.NET クライアントからログを取得するには、ConfigureLoggingHubConnectionBuilder メソッドを使います。 これは、ConfigureLogging および WebHostBuilderHostBuilder メソッドと同じように動作します。 ASP.NET Core で使用するのと同じログ プロバイダーを構成できます。 ただし、個々のログ プロバイダーについて、NuGet パッケージを手動でインストールして有効にする必要があります。

Blazor WebAssembly アプリに .NET クライアント ログを追加するには、「ASP.NET Core Blazor ログ記録」を参照してください。

[コンソールのログ記録]

コンソール ログを有効にするには、Microsoft.Extensions.Logging.Console パッケージを追加します。 次に、AddConsole メソッドを使って、コンソール ロガーを構成します。

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Log to the Console
        logging.AddConsole();

        // This will set ALL logging to Debug level
        logging.SetMinimumLevel(LogLevel.Debug);
    })
    .Build();

デバッグ出力ウィンドウのログ

ログは、Visual Studio の [出力 ] ウィンドウに移動するように構成できます。 Microsoft.Extensions.Logging.Debug パッケージをインストールして、AddDebug メソッドを使います。

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Log to the Output Window
        logging.AddDebug();

        // This will set ALL logging to Debug level
        logging.SetMinimumLevel(LogLevel.Debug)
    })
    .Build();

その他のログ プロバイダー

SignalR では、Serilog、Seq、NLog、または Microsoft.Extensions.Logging と統合される他の任意のログ システムなど、他のログ プロバイダーがサポートされています。 ログシステムに ILoggerProvider が用意されている場合は、それを AddProvider で登録できます。

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Log to your custom provider
        logging.AddProvider(new MyCustomLoggingProvider());

        // This will set ALL logging to Debug level
        logging.SetMinimumLevel(LogLevel.Debug)
    })
    .Build();

制御の詳細度

アプリ内の他の場所からログを記録する場合、既定のレベルを Debug に変更すると、詳細すぎる場合があります。 フィルターを使用して、 SignalR ログのログ レベルを構成できます。 これは、サーバーの場合とほぼ同じ方法で、コードで行うことができます。

var connection = new HubConnectionBuilder()
    .WithUrl("https://example.com/my/hub/url")
    .ConfigureLogging(logging =>
    {
        // Register your providers

        // Set the default log level to Information, but to Debug for SignalR-related loggers.
        logging.SetMinimumLevel(LogLevel.Information);
        logging.AddFilter("Microsoft.AspNetCore.SignalR", LogLevel.Debug);
        logging.AddFilter("Microsoft.AspNetCore.Http.Connections", LogLevel.Debug);
    })
    .Build();

トレース中 SignalR

SignalRハブ サーバーとSignalR クライアントは、SignalRとDiagnosticSourceを使用してActivity接続とメッセージに関する情報を提供します。 SignalR には、ハブ サーバーとクライアントの両方の ActivitySource があり、.NET 9 以降では利用できます。

ActivitySource は、アプリケーション内の操作を表すアクティビティ (またはスパン) を作成および管理するために分散トレースで使用されるコンポーネントです。 これらのアクティビティは、次の用途に使用できます。

  • さまざまなコンポーネントとサービスにわたる要求と操作のフローを追跡します。
  • アプリケーションのパフォーマンスと動作に関する貴重な分析情報を提供します。

.NET SignalR サーバー ActivitySource

SignalR という名前の Microsoft.AspNetCore.SignalR.Server ActivitySource は、ハブ メソッド呼び出しのイベントを出力します。

  • すべてのメソッドは独自のアクティビティであるため、ハブ メソッド呼び出し中にアクティビティを発するものはすべて、ハブ メソッドのアクティビティの下にあります。
  • ハブ メソッド アクティビティには親がありません。 これは、実行時間の長い SignalR 接続の下にバンドルされていないことを意味します。

次の例では、.NET Aspire ダッシュボードOpenTelemetry パッケージを使用します。

<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />

次の起動コードを Program.cs ファイルに追加します。

using OpenTelemetry.Trace;
using SignalRChat.Hubs;

// Set OTEL_EXPORTER_OTLP_ENDPOINT environment variable depending on where your OTEL endpoint is.
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddSignalR();

builder.Services.AddOpenTelemetry()
    .WithTracing(tracing =>
    {
        if (builder.Environment.IsDevelopment())
        {
            // View all traces only in development environment.
            tracing.SetSampler(new AlwaysOnSampler());
        }

        tracing.AddAspNetCoreInstrumentation();
        tracing.AddSource("Microsoft.AspNetCore.SignalR.Server");
    });

builder.Services.ConfigureOpenTelemetryTracerProvider(tracing => tracing.AddOtlpExporter());

var app = builder.Build();

次の出力例は、アスパイア ダッシュボードからの出力です。

SignalR ハブ メソッド呼び出しイベントのアクティビティ一覧

ASP.NET Core では、イベント ソースMicrosoft.AspNetCore.Hostingに対しても独自のメトリックが提供されます。

.NET SignalR クライアント ActivitySource

SignalRという名前のActivitySourceMicrosoft.AspNetCore.SignalR.Clientは、SignalR クライアントのイベントを出力します。

  • ハブ呼び出しによってクライアント スパンが作成されます。 JavaScript クライアントなどの他の SignalR クライアントは、トレースをサポートしていません。 この機能は、今後のリリースでより多くのクライアントに追加される予定です。
  • クライアントとサーバーでのハブ呼び出しでは、コンテキスト伝達がサポートされます。 トレース コンテキストを伝達すると、真の分散トレースが可能になります。 クライアントからサーバーへの呼び出しフローとその逆のフローを確認できるようになりました。

これらの新しいアクティビティは、.NET Aspire ダッシュボードで次のように表示されます。

アスパイア ダッシュボードで SignalR 分散トレースを する

ネットワーク トレース

警告

ネットワーク トレースには、アプリによって送信されるすべてのメッセージの完全な内容が含まれています。 運用アプリから GitHub などのパブリック フォーラムに未加工のネットワーク トレースを投稿しないでください

問題が発生した場合、ネットワーク トレースによって重要な情報が提供されることがあります。 これは、問題トラッカーに問題を提出するときに特に役立ちます。

Fiddler を使用してネットワーク トレースを収集する (推奨オプション)

この方法はすべてのアプリで使用できます。

Fiddler は、HTTP トレースを収集するための強力なツールです。 telerik.com/fiddler からインストールして起動し、アプリを実行して問題を再現します。 Fiddler は Windows で使用でき、macOS と Linux 用のベータ版もあります。

HTTPS を使用して接続する場合は、Fiddler で確実に HTTPS トラフィックの暗号を解除できるようにするための追加の手順がいくつかあります。 詳細については、Fiddler のドキュメントを参照してください。

トレースを収集した後、メニュー バーから [ファイル>保存>すべてのセッション ] を選択してエクスポートします。

Fiddler からのすべてのセッションのエクスポート

tcpdump でネットワーク トレースを収集する (macOS および Linux のみ)

この方法はすべてのアプリで使用できます。

未加工の TCP トレースは、コマンド シェルから次のコマンドを実行することで、tcpdump を使用して収集できます。 アクセス許可エラーが発生した場合は、root になるか、コマンドの前に sudo を入力する必要があることがあります。

tcpdump -i [interface] -w trace.pcap

[interface] は、取り込むネットワーク インターフェイスに置き換えます。 通常、これは /dev/eth0 (標準イーサネット インターフェイスの場合) や /dev/lo0 (localhost トラフィックの場合) のようなものです。 詳細については、ホスト・システムの tcpdump マニュアル・ページを参照してください。

ブラウザーでネットワーク トレースを収集する

この方法は、ブラウザー ベースのアプリに対してのみ機能します。

ほとんどのブラウザー開発者ツール コンソールには、[ネットワーク] タブがあり、ブラウザーとサーバーの間でネットワーク アクティビティをキャプチャできます。 ただし、これらのトレースには、WebSocket とServer-Sent イベントのメッセージは含まれません。 これらのトランスポートを使用する場合は、この記事で後述するように、Fiddler や TcpDump などのツールを使用することをお勧めします。

Microsoft Edge および Internet Explorer

(手順は、Microsoft Edge と Internet Explorer の両方で同じです)

  1. F12 キーを押して開発ツールを開く
  2. [ネットワーク] タブを選択する
  3. (必要に応じて) ページを更新し、問題を再現します
  4. ツール バーの [保存] アイコンを選択して、トレースを "HAR" ファイルとしてエクスポートします。

Microsoft Edge の開発ツールの [ネットワーク] タブの [保存] アイコン

グーグルクローム

  1. F12 キーを押して開発ツールを開く
  2. [ネットワーク] タブを選択する
  3. (必要に応じて) ページを更新し、問題を再現します
  4. 要求の一覧内のどこかを右クリックし、[Save as HAR with content]\(内容を HAR ファイルに保存する\) を選びます。

Google Chrome 開発ツールの [ネットワーク] タブの [Save as HAR with content]\(内容を HAR ファイルに保存する\) オプション

Mozilla Firefox

  1. F12 キーを押して開発ツールを開く
  2. [ネットワーク] タブを選択する
  3. (必要に応じて) ページを更新し、問題を再現します
  4. 要求の一覧内のどこかを右クリックし、[Save All As HAR]\(すべてを HAR として保存\) を選びます

Mozilla Firefox 開発ツールの [ネットワーク] タブの [Save All As HAR]\(すべてを HAR として保存\) オプション

診断ファイルを GitHub のイシューに添付する

診断ファイルを GitHub の問題に添付するには、名前を変更して .txt 拡張子を付け、問題にドラッグ アンド ドロップします。

ログ ファイルまたはネットワーク トレースの内容を、GitHub のイシューに貼り付けないでください。 これらのログとトレースは大きくなる可能性があり、GitHub では通常、それらを切り捨てます。

ログ ファイルを GitHub のイシューにドラッグする

メトリック

指標は、一定期間にわたるデータの測定値の表現です。 たとえば、1 秒あたりの要求数などです。 メトリック データを使用すると、アプリの状態を高レベルで監視できます。 .NET gRPC メトリックは EventCounter を使用して出力されます。

SignalR サーバーのメトリック

SignalR サーバーのメトリックは、Microsoft.AspNetCore.Http.Connections イベント ソースで報告されます。

名前 説明
connections-started 開始された接続の総数
connections-stopped 停止された接続の総数
connections-timed-out タイムアウトした接続の総数
current-connections 現在の接続数
connections-duration 平均接続時間

メトリックを観察する

dotnet-counters は、アドホックな正常性監視と最初のレベルのパフォーマンス調査を目的としたパフォーマンス監視ツールです。 プロバイダー名として Microsoft.AspNetCore.Http.Connections を使って .NET アプリを監視します。 次に例を示します。

> dotnet-counters monitor --process-id 37016 --counters Microsoft.AspNetCore.Http.Connections

Press p to pause, r to resume, q to quit.
    Status: Running
[Microsoft.AspNetCore.Http.Connections]
    Average Connection Duration (ms)       16,040.56
    Current Connections                         1
    Total Connections Started                   8
    Total Connections Stopped                   7
    Total Connections Timed Out                 0

その他のリソース