Ведение журнала и диагностика в ASP.NET CoreSignalR

Эшли Стэнтон-Медсестра

В этой статье приводятся рекомендации по сбору диагностических данных из вашего приложения ASP.NET Core SignalR, чтобы помочь в устранении неполадок.

Ведение журнала на стороне сервера

Warning

Журналы на стороне сервера могут содержать конфиденциальные сведения из приложения. Никогда не публикуйте необработанные журналы из рабочих приложений на общедоступных форумах, таких как GitHub.

Так как SignalR он входит в состав ASP.NET Core, он использует систему ведения журнала ASP.NET Core. В конфигурации SignalR по умолчанию журналы записывают минимальные сведения, но можно настроить уровень ведения журнала. Подробные сведения о настройке ведения журналов в ASP.NET Core см. в документации по ведению журналов в ASP.NET Core.

SignalR использует две категории регистраторов:

  • Microsoft.AspNetCore.SignalR: Для журналов, связанных с протоколами Hub, активацией Hub, вызовом методов и другими действиями, связанными с Hub.
  • Microsoft.AspNetCore.Http.Connections: для журналов, связанных с транспортами, такими как WebSockets, Long Polling, Server-Sent Events и низкоуровневая SignalR инфраструктура.

Чтобы включить подробные журналы, настройте оба предыдущих префикса SignalRна Debug уровень в appsettings.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

Обратитесь к документации для вашей системы конфигурации, чтобы узнать, как указать вложенные значения конфигурации. Так, при использовании переменных среды вместо символа _ применяются два символа : (например, Logging__LogLevel__Microsoft.AspNetCore.SignalR).

При сборе подробных диагностических данных для приложения мы рекомендуем использовать уровень Debug. Уровень Trace создает низкоуровневую диагностику и редко требуется для диагностики проблем в приложении.

Доступ к журналам на стороне сервера

Доступ к журналам на стороне сервера зависит от среды, в которой работает приложение.

Как консольное приложение за пределами IIS

Если приложение выполняется в консоли, регистратор Console должен быть включён по умолчанию. SignalR журналы отображаются в консоли.

В IIS Express из Visual Studio

Visual Studio отображает выходные данные журнала в окне вывода . Выберите пункт раскрывающегося списка ASP.NET Core Web Server.

Служба приложений Azure

Включите параметр ведения журнала приложений (файловая система) в разделе журналов диагностики на портале службы приложение Azure и настройте уровень на Verbose. Журналы должны быть доступны в службе потоковой передачи журналов и в журналах в файловой системе App Service. Дополнительные сведения см. в статье "Потоковая передача журналов Azure".

Другие среды

Дополнительные сведения о настройке поставщиков ведения журналов, подходящих для различных сред развертывания, таких как Docker, Kubernetes или служба Windows, см. в разделе "Ведение журнала" в .NET и ASP.NET Core.

Ведение журнала клиента JavaScript

Warning

Журналы на стороне клиента могут содержать конфиденциальные сведения из приложения. Никогда не публикуйте необработанные журналы из рабочих приложений на общедоступных форумах, таких как GitHub.

При использовании клиента JavaScript можно настроить параметры ведения журнала с помощью configureLogging метода в HubConnectionBuilder:

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

Отключите ведение журнала платформы, указав signalR.LogLevel.None в методе configureLogging . Обратите внимание, что некоторые журналы создаются непосредственно браузером и не могут быть отключены с помощью настройки уровня журнала.

В следующей таблице показаны уровни журналов, доступные клиенту JavaScript. Установка уровня журнала на одно из этих значений включает журналирование на этом уровне, а также на всех уровнях выше него в таблице.

Level Description
None Сообщения не регистрируются.
Critical Сообщения, указывающие на сбой во всем приложении.
Error Сообщения, указывающие на сбой в текущей операции.
Warning Сообщения, указывающие неустранимую проблему.
Information Информационные сообщения.
Debug Диагностические сообщения, полезные для отладки.
Trace Очень подробные диагностические сообщения, предназначенные для диагностики конкретных проблем.

После настройки детализации журналы будут записаны в консоль браузера (или стандартные выходные данные в приложении NodeJS).

Если вы хотите отправить журналы в настраиваемую систему ведения журнала, можно предоставить объект JavaScript, реализующий ILogger интерфейс. Единственный метод, который необходимо реализовать, — это 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

Warning

Журналы на стороне клиента могут содержать конфиденциальные сведения из приложения. Никогда не публикуйте необработанные журналы из рабочих приложений на общедоступных форумах, таких как GitHub.

Чтобы получить логи из клиента .NET, можно использовать метод ConfigureLogging объекта HubConnectionBuilder. Это работает так же, как метод ConfigureLogging у WebHostBuilder и HostBuilder. Вы можете настроить те же поставщики ведения журналов, которые используются в ASP.NET Core. Однако необходимо вручную установить и включить пакеты NuGet для отдельных поставщиков ведения журнала.

Сведения о том, как добавить ведение журнала клиента .NET в приложение Blazor WebAssembly, см. в разделе Ведение журнала в BlazorASP.NET Core.

Логирование консоли

Чтобы включить ведение журнала консоли, добавьте пакет 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 ActivitySource с именем Microsoft.AspNetCore.SignalR.Server выпускает события для вызовов методов хаба:

  • Каждый метод является собственной активностью, поэтому все, что выдает активность во время вызова метода концентратора, находится в рамках активности метода концентратора.
  • Действия метода Hub не имеют родительского элемента. Это означает, что они не объединяются в длительное SignalR соединение.

В следующем примере используются 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();

Следующий пример выходных данных взят с панели мониторинга Aspire.

SignalR Hub method call events

ASP.NET Core также предоставляет собственные метрики в Microsoft.AspNetCore.Hosting источнике событий.

.NET SignalR клиент ActivitySource

Элемент SignalRActivitySource, названный Microsoft.AspNetCore.SignalR.Client, испускает события для клиента SignalR.

  • Вызовы концентратора создают диапазон клиента. Другие SignalR клиенты, такие как клиент JavaScript, не поддерживают трассировку. Эта функция будет добавлена для большего числа клиентов в будущих версиях.
  • Вызовы концентратора на клиенте и сервере поддерживают распространение контекста. Распространение контекста трассировки обеспечивает истинную распределенную трассировку. Теперь можно увидеть поток вызовов от клиента к серверу и обратно.

Вот как эти новые действия выглядят в Aspire панели мониторинга:

SignalR распределенная трассировка на Aspire панели мониторинга

Сетевые трассировки

Warning

Сетевая трассировка содержит полное содержимое каждого сообщения, которое отправляет ваше приложение. Никогда не публикуйте необработанные трассировки сети из рабочих приложений на общедоступных форумах, таких как 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 (для стандартного интерфейса Ethernet) или /dev/lo0 (для трафика localhost). Дополнительные сведения см. на tcpdump странице руководства в вашей хост-системе.

Сбор трассировки сети в браузере

Этот метод работает только для приложений на основе браузера.

Большинство консоли средств разработчика браузера имеют вкладку "Сеть", которая позволяет записывать сетевые действия между браузером и сервером. Однако эти трассировки не включают сообщения WebSocket и Server-Sent Events. При работе с этими транспортами рекомендуется использовать такие инструменты, как Fiddler или TcpDump, как описано далее в этой статье.

Microsoft Edge и Internet Explorer

(Инструкции одинаковы для Microsoft Edge и Internet Explorer)

  1. Откройте средства разработки, нажав клавишу F12
  2. Выберите вкладку "Сеть"
  3. Обновите страницу (при необходимости) и воспроизведите проблему
  4. Щелкните значок "Сохранить" на панели инструментов, чтобы экспортировать трассировку в виде ФАЙЛА HAR:

Значок сохранения на вкладке

Google Chrome

  1. Откройте средства разработки, нажав клавишу F12
  2. Выберите вкладку "Сеть"
  3. Обновите страницу (при необходимости) и воспроизведите проблему
  4. Щелкните правой кнопкой мыши в любом месте списка запросов и нажмите кнопку "Сохранить как HAR с содержимым":

Опция

Mozilla Firefox

  1. Откройте средства разработки, нажав клавишу F12
  2. Выберите вкладку "Сеть"
  3. Обновите страницу (при необходимости) и воспроизведите проблему
  4. Щелкните правой кнопкой мыши в любом месте списка запросов и нажмите кнопку "Сохранить все как HAR"

Параметр

Прикрепить диагностические файлы к задачам GitHub

Файлы диагностики можно прикрепить к задачам GitHub, переименовав их, чтобы у них было расширение .txt, а затем перетащив их в задачу.

Note

Пожалуйста, не вставляйте содержимое файлов журналов или сетевых трассировок в обращение на GitHub. Эти логи и трассировки могут быть большими, и GitHub обычно обрезает их.

Перетаскивание файлов журналов в обсуждение на GitHub

Metrics

Метрики представляют собой представление мер данных через интервалы времени. Например, запросы в секунду. Метрики позволяют отслеживать общее состояние приложения. Метрики .NET gRPC публикуются с помощью EventCounter.

SignalR метрики сервера

SignalR Метрики сервера публикуются в источнике событий Microsoft.AspNetCore.Http.Connections.

Name Description
connections-started Всего запущенных подключений
connections-stopped Общее количество остановленных подключений
connections-timed-out Общее количество подключений с тайм-аутом
current-connections Текущие подключения
connections-duration Средняя длительность подключения

Наблюдение за метриками

dotnet-counters — это инструмент для мониторинга производительности, предназначенный для оперативного мониторинга состояния и первичного анализа производительности. Отслеживайте приложение .NET, используя Microsoft.AspNetCore.Http.Connections в качестве имени поставщика. Рассмотрим пример.

> 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

Дополнительные ресурсы