Compartilhar via


Registro em log e diagnóstico no ASP.NET Core SignalR

Por Andrew Stanton-Nurse

Este artigo fornece diretrizes para você coletar os diagnósticos do seu aplicativo ASP.NET Core SignalR para ajudar a solucionar problemas.

Log do lado do servidor

Warning

Os logs do lado do servidor podem conter informações confidenciais do seu aplicativo. Nunca poste logs brutos de aplicativos de produção em fóruns públicos como o GitHub.

Como o SignalR faz parte do ASP.NET Core, ele utiliza o sistema de logs do ASP.NET Core. Na configuração padrão, SignalR registra informações mínimas, mas o nível de log pode ser configurado. Confira a documentação sobre Registro em log do ASP.NET Core para obter detalhes sobre como configurar o registro em log do ASP.NET Core.

SignalR utiliza duas categorias de registradores:

  • Microsoft.AspNetCore.SignalR: Para os logs relacionados aos protocolos do hub, ativação de hubs, invocação de métodos e outras atividades relacionadas ao hub.
  • Microsoft.AspNetCore.Http.Connections: Para os logs relacionados a transportes, como WebSockets, Polling longo, eventos enviados pelo servidor e infraestrutura SignalR de baixo nível.

Para habilitar logs detalhados de SignalR, configure ambos os prefixos mencionados para o nível Debug em seu arquivo appsettings.json, adicionando os seguintes itens à subseção LogLevel em Logging.

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

Os níveis de log para as categorias de SignalR logger também podem ser configurados no código dentro do CreateWebHostBuilder método:

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>();

Se você não estiver utilizando a configuração baseada em JSON, defina os seguintes valores de configuração em seu sistema de configuração:

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

Verifique a documentação do sistema de configuração para determinar como especificar valores de configuração aninhados. Por exemplo, ao usar variáveis de ambiente, dois caracteres _ são usados em vez do : (por exemplo, Logging__LogLevel__Microsoft.AspNetCore.SignalR).

Recomendamos que você utilize o nível Debug ao coletar os diagnósticos mais detalhados para o seu aplicativo. O Trace nível produz diagnósticos de baixo nível e raramente é necessário para diagnosticar problemas em seu aplicativo.

Acessar logs do lado do servidor

A forma como os logs do lado do servidor são acessados depende do ambiente no qual o aplicativo está em execução.

Como um aplicativo de console fora do IIS

Se você estiver executando em um aplicativo de console, o Agente do console deverá ser habilitado por padrão. SignalR os logs aparecem no console.

No IIS Express a partir do Visual Studio

O Visual Studio exibe a saída dos logs na janela Saída. Selecione a opção da lista suspensa Servidor Web ASP.NET Core.

Serviço de Aplicativo do Azure

Habilite a opção Application Logging (Filesystem) na seção Logs de Diagnóstico do portal do Serviço de Aplicativo do Azure e configure o Nível para Verbose. Os logs devem estar disponíveis no serviço Streaming de log e nos logs do sistema de arquivos do Serviço de Aplicativo. Para obter mais informações, confira Streaming de Log do Azure.

Outros ambientes

Para obter mais informações sobre como configurar provedores de log adequados para diferentes ambientes de implantação, como Docker, Kubernetes ou Serviço do Windows, consulte Registro em .NET e ASP.NET Core.

Registrar em log cliente JavaScript

Warning

Os logs do lado do cliente podem conter informações confidenciais do seu aplicativo. Nunca poste logs brutos de aplicativos de produção em fóruns públicos como o GitHub.

Ao utilizar o cliente JavaScript, você pode configurar as opções de registro em log usando o método configureLogging em HubConnectionBuilder:

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

Desabilite o registro em log da estrutura especificando signalR.LogLevel.None no método configureLogging. Observe que alguns registros em log são emitidos diretamente pelo navegador e não podem ser desabilitados por meio da configuração do nível de registro.

A tabela a seguir mostra os níveis de registro em log disponíveis para o cliente JavaScript. Se você definir o nível de log para um desses valores, habilitará o registro em log nesse nível e em todos os níveis acima dele na tabela.

Level Description
None Nenhuma mensagem está registrada em log.
Critical Mensagens que indicam uma falha em todo o aplicativo.
Error Mensagens que indicam uma falha na operação atual.
Warning Mensagens que indicam um problema não fatal.
Information Mensagens informativas.
Debug Mensagens de diagnóstico utilizadas para depuração.
Trace Mensagens de diagnóstico muito detalhadas projetadas para diagnosticar problemas específicos.

Depois que você configurar o detalhamento, os logs serão gravados no Console do Navegador (ou na Saída Padrão em um aplicativo NodeJS).

Se quiser enviar os logs para um sistema de registro personalizado, você poderá fornecer um objeto JavaScript que implemente a interface ILogger. O único método que precisa ser implementado é log, que recebe o nível do evento e a mensagem associada ao evento. Por exemplo:

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();

Registrar em log cliente .NET

Warning

Os logs do lado do cliente podem conter informações confidenciais do seu aplicativo. Nunca poste logs brutos de aplicativos de produção em fóruns públicos como o GitHub.

Para obter os registros em logs do cliente .NET, você pode utilizar o método ConfigureLogging em HubConnectionBuilder. Isso funciona da mesma forma que o método ConfigureLogging em WebHostBuilder e HostBuilder. Você pode configurar os mesmos provedores de registro em log que utiliza no ASP.NET Core. No entanto, você precisará instalar e habilitar manualmente os pacotes NuGet para os provedores de registro em logs individuais.

Para adicionar o registro em log do cliente .NET a um aplicativo Blazor WebAssembly, confira ASP.NET Core Blazor registro em log.

Registro em log do console

Para habilitar o registro em log do Console, adicione o pacote Microsoft.Extensions.Logging.Console. Em seguida, utilize o método AddConsole para configurar o agente do console:

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();

Registro em log da janela de saída da depuração

Os logs podem ser configurados para ir para a janela Saída no Visual Studio. Instale o pacote Microsoft.Extensions.Logging.Debug e utilize o método 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();

Outros provedores de registro em log

O SignalR tem suporte para outros provedores de registro em log, como Serilog, Seq, NLog ou qualquer outro sistema de registro que se integre ao Microsoft.Extensions.Logging. Se o seu sistema de registro em log fornecer um ILoggerProvider, você poderá registrá-lo com 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();

Controlar verbosidade

Ao fazer log de outros locais no aplicativo, alterar o nível padrão para Debug pode ser extra detalhado. Um filtro pode ser usado para configurar o nível de log para SignalR logs. Isso pode ser feito no código, da mesma forma que no servidor:

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();

Rastreamento no SignalR

SignalR o servidor hub e o SignalR cliente fornecem informações sobre SignalR conexões e mensagens usando DiagnosticSource e Activity. SignalR tem um ActivitySource para o servidor hub e o cliente, disponível a partir do .NET 9.

Um ActivitySource é um componente usado no rastreamento distribuído para criar e gerenciar atividades (ou intervalos) que representam operações em seu aplicativo. Essas atividades podem ser usadas para:

  • Acompanhe o fluxo de solicitações e operações entre diferentes componentes e serviços.
  • Forneça informações valiosas sobre o desempenho e o comportamento do aplicativo.

ActivitySource do servidor .NET SignalR

O SignalR ActivitySource denominado Microsoft.AspNetCore.SignalR.Server emite eventos para chamadas de método de hub:

  • Cada método é sua própria atividade, então qualquer coisa que emita uma atividade durante a chamada do método hub está sob a atividade do método hub.
  • As atividades do método hub não têm um pai. Isso significa que eles não são agrupados sob a conexão de SignalR de longa duração.

O exemplo a seguir usa o painel de controle Aspire e os pacotes 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" />

Adicione o seguinte código de inicialização ao arquivo 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();

A seguir, um exemplo de saída do Aspire Painel de Controle:

Lista de atividades para eventos de chamada de método do Hub SignalR

ASP.NET Core também fornece suas próprias métricas na Microsoft.AspNetCore.Hosting origem do evento.

ActivitySource do cliente .NET SignalR

O SignalRActivitySource nomeado Microsoft.AspNetCore.SignalR.Client emite eventos para um SignalR cliente:

  • Invocações de hub criam um intervalo de cliente. Outros SignalR clientes, como o cliente JavaScript, não dão suporte ao rastreamento. Esse recurso será adicionado a mais clientes em versões futuras.
  • Invocações de hub no cliente e no servidor dão suporte à propagação de contexto. A propagação do contexto de rastreamento permite o rastreamento distribuído verdadeiro. Agora é possível ver o fluxo de invocações do cliente para o servidor e de volta.

Veja como são essas novas atividades no Aspire painel:

SignalR rastreamento distribuído no Aspire painel

Rastreamentos de rede

Warning

Um rastreamento de rede contém o conteúdo completo de cada mensagem enviada pelo seu aplicativo. Nunca poste rastreamentos de rede brutos de aplicativos de produção em fóruns públicos, como o GitHub.

Se você encontrar um problema, um rastreamento de rede às vezes poderá fornecer informações valiosas. Isso é especialmente útil ao apresentar um problema em nosso rastreador de problemas.

Colete um rastreamento de rede com o Fiddler (opção preferencial)

Esse método funciona para todos os aplicativos.

O Fiddler é uma ferramenta poderosa para coletar rastreamentos HTTP. Instale-o do telerik.com/fiddler, inicialize e, em seguida, execute seu aplicativo e reproduza o problema. O Fiddler está disponível para Windows e há versões beta para macOS e Linux.

Se você se conectar usando HTTPS, haverá algumas etapas adicionais para garantir que o Fiddler possa descriptografar o tráfego HTTPS. Saiba mais na documentação do Fiddler.

Depois de coletar o rastreamento, exporte-o selecionando Salvar>>Todas as Sessões da barra de menus

Exportando todas as sessões do Fiddler

Coletar um rastreamento de rede com tcpdump (somente macOS e Linux)

Esse método funciona para todos os aplicativos.

Capturas TCP brutas podem ser coletadas usando tcpdump ao executar o comando a seguir em um terminal de comando. Talvez seja necessário ser root ou prefixar o comando com sudo se você receber um erro de permissões:

tcpdump -i [interface] -w trace.pcap

Substitua [interface] pela interface de rede que você deseja capturar. Normalmente, isso é algo como /dev/eth0 (para uma interface Ethernet padrão) ou /dev/lo0 (para tráfego localhost). Para obter mais informações, consulte a tcpdump página manual em seu sistema de host.

Coletar um rastreamento de rede no navegador

Esse método só funciona com aplicativos baseados em navegador.

A maioria dos consoles de ferramentas de desenvolvedor do navegador tem uma guia "Rede" que permite que a atividade de rede seja capturada entre o navegador e o servidor. No entanto, esses rastreamentos não incluem mensagens WebSocket e Server-Sent Event. Ao usar esses transportes, usar uma ferramenta como Fiddler ou TcpDump é uma abordagem melhor, conforme descrito posteriormente neste artigo.

Microsoft Edge e Internet Explorer

(As instruções são as mesmas para o Microsoft Edge e o Internet Explorer)

  1. Abra as Ferramentas de Desenvolvimento pressionando F12
  2. Selecione a guia Rede
  3. Atualize a página (se necessário) e reproduza o problema
  4. Selecione o ícone Salvar na barra de ferramentas para exportar o rastreamento como um arquivo "HAR":

O ícone Salvar na guia Rede das Ferramentas de Desenvolvimento do Microsoft Edge

Google Chrome

  1. Abra as Ferramentas de Desenvolvimento pressionando F12
  2. Selecione a guia Rede
  3. Atualize a página (se necessário) e reproduza o problema
  4. Clique com o botão direito do mouse em qualquer lugar da lista de solicitações e escolha "Salvar como HAR com conteúdo":

Opção

Mozilla Firefox

  1. Abra as Ferramentas de Desenvolvimento pressionando F12
  2. Selecione a guia Rede
  3. Atualize a página (se necessário) e reproduza o problema
  4. Clique com o botão direito do mouse em qualquer lugar da lista de solicitações e escolha "Salvar Tudo Como HAR"

Opção

Anexar os arquivos de diagnóstico aos problemas do GitHub

Os arquivos de diagnóstico podem ser anexados a issues do GitHub renomeando-os para que tenham uma extensão .txt e, em seguida, arrastando-os e soltando-os na issue.

Note

Não cole o conteúdo dos arquivos de log ou dos rastreamentos de rede em um problema do GitHub. Esses logs e rastreamentos podem ser grandes, e o GitHub geralmente os trunca.

Arrastar os arquivos de logs para um problema do GitHub

Metrics

As métricas são uma representação de medidas de dados em intervalos de tempo. Por exemplo, solicitações por segundo. Os dados de métricas permitem a observação do estado de um aplicativo em um alto nível. As métricas gRPC do .NET são emitidas usando EventCounter.

Métricas do servidor SignalR

As métricas do servidor SignalR são relatadas na fonte de eventos Microsoft.AspNetCore.Http.Connections.

Name Description
connections-started Total de conexões iniciadas
connections-stopped Total de conexões interrompidas
connections-timed-out Total de conexões com tempo limite expirado
current-connections Conexões atuais
connections-duration Duração média da conexão

Observar métricas

dotnet-counters é uma ferramenta de monitoramento de desempenho para monitoramento de integridade ad hoc e investigação de desempenho de primeiro nível. Monitore um aplicativo .NET com Microsoft.AspNetCore.Http.Connections como o nome do provedor. Por exemplo:

> 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

Recursos adicionais