Log no .NET Core e no ASP.NET Core

Por Kirk Larkin, Juergen Gutsch e Rick Anderson

Este artigo descreve o registro em log no .NET no que diz respeito a aplicativos ASP.NET Core. Para obter informações detalhadas sobre o registro em log no .NET, consulte Registro em log no .NET. Para saber mais sobre o registro em log em aplicativos Blazor, confira Registro em log no ASP.NET CoreBlazor.

Provedores de log

Os provedores de log armazenam logs, exceto pelo provedor Console que exibe logs. Por exemplo, o provedor do Azure Application Insights armazena logs no Azure Application Insights. Vários provedores podem ser habilitados.

A chamada padrão WebApplication.CreateBuilder de modelos de aplicativo Web do ASP.NET Core, que adiciona os seguintes provedores de log:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

O código anterior mostra o arquivo Program.cs criado com os modelos de aplicativo Web do ASP.NET Core. As próximas seções fornecem exemplos com base nos modelos de aplicativo Web do ASP.NET Core.

O seguinte código substitui o conjunto padrão de provedores de registro em log adicionados por WebApplication.CreateBuilder:

var builder = WebApplication.CreateBuilder(args);
builder.Logging.ClearProviders();
builder.Logging.AddConsole();

builder.Services.AddRazorPages();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapRazorPages();

app.Run();

Como alternativa, o código de registro em log anterior pode ser escrito da seguinte maneira:

var builder = WebApplication.CreateBuilder();
builder.Host.ConfigureLogging(logging =>
{
    logging.ClearProviders();
    logging.AddConsole();
});

Para provedores adicionais, consulte:

Criar logs

Para criar logs, use um objeto ILogger<TCategoryName> de DI (injeção de dependência).

O exemplo a seguir:

  • Cria um agente, ILogger<AboutModel>, que usa uma categoria de log do nome totalmente qualificado do tipo AboutModel. A categoria do log é uma cadeia de caracteres associada a cada log.
  • Chama LogInformation para registrar em log no nível Information. O nível de log indica a gravidade do evento registrado.
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("About page visited at {DT}", 
            DateTime.UtcNow.ToLongTimeString());
    }
}

Níveis e categorias serão explicados com mais detalhes posteriormente neste artigo.

Para obter informações sobre Blazor, consulte Registro em log de Blazor no ASP.NET Core.

Configurar o registro em log

A configuração de registro em log normalmente é fornecida pela seção Logging dos arquivos appsettings.{ENVIRONMENT}.json, em que o espaço reservado {ENVIRONMENT} é o ambiente. O seguinte arquivo appsettings.Development.json é gerado pelos modelos de aplicativo Web do ASP.NET Core:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

No JSON anterior:

  • As categorias "Default" e "Microsoft.AspNetCore" são especificadas.
  • A categoria "Microsoft.AspNetCore" se aplica a todas as categorias que começam com "Microsoft.AspNetCore". Por exemplo, essa configuração se aplica à categoria "Microsoft.AspNetCore.Routing.EndpointMiddleware".
  • A categoria "Microsoft.AspNetCore" faz o registro em log no nível Warning e superiores.
  • Não é especificado um provedor de log específico, portanto LogLevel se aplica a todos os provedores de log habilitados, exceto por EventLog do Windows.

A propriedade Logging pode ter LogLevel e as propriedades do provedor de logs. A LogLevel especifica o nível mínimo de log nas categorias selecionadas. No JSON anterior, os níveis de log Information e Warning são especificados. LogLevel indica a severidade do log e varia de 0 a 6:

Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5 e None = 6.

Quando um LogLevel é especificado, o registro em log é habilitado para mensagens no nível especificado e superior. No JSON anterior, a categoria Default é registrada para Information e superior. Por exemplo, mensagens Information, Warning, Error e Critical são registradas em log. Se LogLevel não for especificado, o registro em log usará o nível Information como padrão. Para obter mais informações, confira Níveis de log.

Uma propriedade de provedor pode especificar uma propriedade LogLevel. LogLevel em um provedor especifica os níveis de log desse provedor e substitui as configurações de log que não são do provedor. Considere o seguinte arquivo appsettings.json:

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

Configurações em Logging.{PROVIDER NAME}.LogLevel substituem configurações em Logging.LogLevel, em que o espaço reservado {PROVIDER NAME} é o nome do provedor. No JSON anterior, o nível de log padrão do provedor Debug é definido como Information:

Logging:Debug:LogLevel:Default:Information

A configuração anterior especifica o nível de log Information para todas as categorias de Logging:Debug:, exceto a Microsoft.Hosting. Quando uma categoria específica é listada, ela substitui a categoria padrão. No JSON anterior, as categorias "Microsoft.Hosting" e "Default" de Logging:Debug:LogLevel substituem as configurações em Logging:LogLevel.

O nível mínimo de log pode ser especificado para:

  • Provedores específicos: por exemplo, Logging:EventSource:LogLevel:Default:Information
  • Categorias específicas: por exemplo, Logging:LogLevel:Microsoft:Warning
  • Todos os provedores e todas as categorias: Logging:LogLevel:Default:Warning

Todos os logs abaixo do nível mínimo não são:

  • Passados para o provedor.
  • Registrados nem exibidos.

Para suprimir todos os logs, especifique LogLevel.None. LogLevel.None tem o valor 6, que é superior a LogLevel.Critical (5).

Se um provedor oferecer suporte a escopos de log, IncludeScopes indicará se eles estão habilitados. Para obter mais informações, confira Escopos de log.

O seguinte arquivo appsettings.json contém todos os provedores habilitados por padrão:

{
  "Logging": {
    "LogLevel": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "Default": "Information"
      }
    },
    "EventSource": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "EventLog": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "AzureAppServicesFile": {
      "IncludeScopes": true,
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "AzureAppServicesBlob": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "ApplicationInsights": {
      "LogLevel": {
        "Default": "Information"
      }
    }
  }
}

Na amostra anterior:

  • As categorias e os níveis não são valores sugeridos. O exemplo é fornecido para mostrar todos os provedores padrão.
  • Configurações em Logging.{PROVIDER NAME}.LogLevel substituem configurações em Logging.LogLevel, em que o espaço reservado {PROVIDER NAME} é o nome do provedor. Por exemplo, o nível em Debug.LogLevel.Default substitui o nível em LogLevel.Default.
  • Cada alias de provedor padrão é usado. Cada provedor define um alias que pode ser usado na configuração no lugar do nome de tipo totalmente qualificado. Os aliases dos provedores internos são:
    • Console
    • Debug
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Logon Program.cs

O seguinte exemplo chama Builder.WebApplication.Loggerem Program.cs e registra mensagens informativas:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.Logger.LogInformation("Adding Routes");
app.MapGet("/", () => "Hello World!");
app.Logger.LogInformation("Starting the app");
app.Run();

O seguinte exemplo chama AddConsole em Program.cs e registra o ponto de extremidade /Test:

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddConsole();

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await response.WriteAsync("Testing");
});

app.Run();

O seguinte exemplo chama AddSimpleConsole em Program.cs, desabilita a saída de cor e registra o ponto de extremidade /Test:

using Microsoft.Extensions.Logging.Console;

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddSimpleConsole(i => i.ColorBehavior = LoggerColorBehavior.Disabled);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/Test", async (ILogger<Program> logger, HttpResponse response) =>
{
    logger.LogInformation("Testing logging in Program.cs");
    await response.WriteAsync("Testing");
});

app.Run();

Definir o nível de log por linha de comando, variáveis de ambiente e outras configurações

O nível de log pode ser definido por qualquer um dos provedores de configuração.

O separador : não funciona com chaves hierárquicas de variáveis de ambiente em todas as plataformas. __, o sublinhado duplo, tem:

  • Suporte em todas as plataformas. Por exemplo, o separador : não tem suporte pelo Bash, mas pelo __ tem.
  • Substituição automática por um :

Os seguintes comandos :

  • Defina a chave de ambiente Logging:LogLevel:Microsoft como um valor de Information no Windows.
  • Teste as configurações ao usar um aplicativo criado com os modelos de aplicativo Web do ASP.NET Core. O comando dotnet run precisa ser executado no diretório do projeto após usar set.
set Logging__LogLevel__Microsoft=Information
dotnet run

As configurações de ambiente anteriores:

  • São definidas apenas em processos iniciados na janela de comando em que foram definidos.
  • Não são lidos por navegadores iniciados com o Visual Studio.

O comando setx a seguir também define a chave e o valor do ambiente no Windows. Diferente de set, as configurações setx são persistentes. A opção /M define a variável no ambiente do sistema. Se /M não for usado, uma variável de ambiente do usuário será definida.

setx Logging__LogLevel__Microsoft Information /M

Considere o seguinte arquivo appsettings.json:

"Logging": {
  "Console": {
    "LogLevel": {
      "Microsoft.Hosting.Lifetime": "Trace"
    }
  }
}

O seguinte comando define a configuração anterior no ambiente:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Observação

Ao configurar variáveis de ambiente com nomes que contêm . (pontos) no macOS e no Linux, veja a pergunta "Como exportar uma variável que contém um ponto (.)" no Stack Exchange e a resposta aceita correspondente.

Em Serviço de Aplicativo do Azure, selecione Nova configuração de aplicativo na página Configuração > Configurações. As configurações do aplicativo do Serviço de Aplicativo do Azure são:

  • Criptografadas em repouso e transmitidas por um canal criptografado.
  • Expostas como variáveis de ambiente.

Para obter mais informações, confira Azure Apps: substituir a configuração do aplicativo usando o portal do Azure.

Para obter mais informações sobre como definir valores de configuração do ASP.NET Core usando variáveis de ambiente, confira variáveis de ambiente. Para obter informações sobre como usar outras fontes de configuração, incluindo a linha de comando, o Azure Key Vault, a Configuração de Aplicativos do Azure, outros formatos de arquivo e muito mais, consulte Configuração no ASP.NET Core.

Como as regras de filtragem são aplicadas

Quando um objeto ILogger<TCategoryName> é criado, o objeto ILoggerFactory seleciona uma única regra por provedor para aplicar a esse agente. Todas as mensagens gravadas pela instância ILogger são filtradas com base nas regras selecionadas. A regra mais específica possível para cada par de categoria e provedor é selecionada entre as regras disponíveis.

O algoritmo a seguir é usado para cada provedor quando um ILogger é criado para uma determinada categoria:

  • Selecione todas as regras que correspondem ao provedor ou seu alias. Se nenhuma correspondência for encontrada, selecione todas as regras com um provedor vazio.
  • Do resultado da etapa anterior, selecione as regras com o prefixo de categoria de maior correspondência. Se nenhuma correspondência for encontrada, selecione todas as regras que não especificam uma categoria.
  • Se várias regras forem selecionadas, use a última.
  • Se nenhuma regra for selecionada, use MinimumLevel.

Registrar a saída da execução do dotnet e do Visual Studio

Logs criados com os provedores de registro em log padrão são exibidos:

  • No Visual Studio
    • Na janela de saída de Depuração ao depurar.
    • Na janela do servidor Web do ASP.NET Core.
  • Na janela do console quando o aplicativo é executado com dotnet run.

Logs que começam com as categorias "Microsoft" são de código da estrutura ASP.NET Core. O ASP.NET Core e o código do aplicativo usam a mesma API de registro em log e os mesmos provedores.

Categoria do log

Quando um objeto ILogger é criado, uma categoria é especificada. Essa categoria é incluída em cada mensagem de log criada por essa instância de ILogger. A cadeia de caracteres da categoria é arbitrária, mas a convenção é usar o nome de classe totalmente qualificado. Por exemplo, em um controlador, o nome pode ser "TodoApi.Controllers.TodoController". Os aplicativos Web do ASP.NET Core usam ILogger<T> para obter automaticamente uma instância de ILogger que usa o nome de tipo totalmente qualificado como a categoria T:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

Se mais categorização for desejada, a convenção é usar um nome hierárquico anexando uma subcategoria ao nome de classe totalmente qualificado e especificar explicitamente a categoria usando ILoggerFactory.CreateLogger:

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("TodoApi.Pages.ContactModel.MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }

Chamar CreateLogger com um nome fixo pode ser útil quando usado em vários métodos para que os eventos possam ser organizados por categoria.

ILogger<T> é equivalente a chamar CreateLogger com o nome de tipo totalmente qualificado de T.

Nível de log

A seguinte tabela lista os valores de LogLevel, o método de extensão de conveniência Log{LogLevel} e o uso sugerido:

LogLevel Valor Método Descrição
Trace 0 LogTrace Contêm as mensagens mais detalhadas. Essas mensagens podem conter dados confidenciais do aplicativo. Essas mensagens são desabilitadas por padrão e não devem ser habilitadas em um ambiente de produção.
Debug 1 LogDebug Para depuração e desenvolvimento. Use com cuidado em produção devido ao alto volume.
Information 2 LogInformation Rastreia o fluxo geral do aplicativo. Pode ter um valor de longo prazo.
Warning 3 LogWarning Para eventos anormais ou inesperados. Geralmente, inclui erros ou condições que não fazem com que o aplicativo falhe.
Error 4 LogError Para erros e exceções que não podem ser manipulados. Essas mensagens indicam uma falha na operação ou na solicitação atual, não uma falha em todo o aplicativo.
Critical 5 LogCritical Para falhas que exigem atenção imediata. Exemplos: cenários de perda de dados, espaço em disco insuficiente.
None 6 Especifica que uma categoria de log não deve gravar mensagens.

Na tabela anterior, o LogLevel é listado da severidade menor para a maior.

O primeiro parâmetro do método Log, LogLevel, indica a severidade do log. Em vez de chamar Log(LogLevel, ...), a maioria dos desenvolvedores chama os métodos de extensão Log{LOG LEVEL}, em que o espaço reservado {LOG LEVEL} é o nível de log. Por exemplo, estas duas chamadas de log são equivalentes em funcionalidades e produzem o mesmo log:

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem é a ID do evento. MyLogEvents faz parte do aplicativo de exemplo e é exibido na seção ID do evento de log.

MyDisplayRouteInfo e ToCtxString são fornecidos pelo pacote NuGet Rick.Docs.Samples.RouteInfo. Os métodos exibem as informações de rota de Controller e Razor Page.

O código a seguir cria os logs Information e Warning:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

No código anterior, o primeiro parâmetro de Log{LOG LEVEL}, MyLogEvents.GetItem, é a ID do evento de log. O segundo parâmetro é um modelo de mensagem com espaços reservados para valores de argumento fornecidos pelos parâmetros de método restantes. Os parâmetros de método serão explicados com posteriormente neste documento, na seção de modelos de mensagem.

Chame o método Log{LOG LEVEL} adequado para controlar a quantidade de saída de log gravada em uma mídia de armazenamento específica. Por exemplo:

  • Em produção:
    • O registro em log nos níveis Trace, Debug ou Information produz um grande volume de mensagens de log detalhadas. Para controlar os custos e não exceder os limites de armazenamento de dados, registre as mensagens de nível Trace, Debug ou Information em um repositório de dados de alto volume e baixo custo. Considere a possibilidade de limitar Trace, Debug ou Information a categorias específicas.
    • O registro em log nos níveis Warning a Critical deve produzir poucas mensagens de log.
      • Os custos e os limites de armazenamento geralmente não são preocupantes.
      • Poucos logs permitem mais flexibilidade nas opções de armazenamento de dados.
  • Em desenvolvimento:
    • Defina como Warning.
    • Adicione mensagens Trace, Debug ou Information ao solucionar problemas. Para limitar a saída, defina Trace, Debug ou Information somente para as categorias sob investigação.

O ASP.NET Core grava logs para eventos de estrutura. Por exemplo, considere a saída de log para:

  • Um aplicativo Razor Pages criado com os modelos do ASP.NET Core.
  • Registro em log definido como Logging:Console:LogLevel:Microsoft:Information.
  • Navegação até a página Privacy:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

O seguinte JSON define Logging:Console:LogLevel:Microsoft:Information:

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

ID de evento de log

Cada log pode especificar uma ID do evento. O aplicativo de exemplo usa a classe MyLogEvents para definir IDs de evento:

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Uma ID de evento associa um conjunto de eventos. Por exemplo, todos os logs relacionados à exibição de uma lista de itens em uma página podem ser 1001.

O provedor de logs pode armazenar a ID do evento em um campo de ID na mensagem de log ou não armazenar. O provedor de Depuração não mostra IDs de eventos. O provedor de console mostra IDs de evento entre colchetes após a categoria:

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

Alguns provedores de log armazenam a ID do evento em um campo, o que permite a filtragem na ID.

Modelo de mensagem de log

Cada API de log usa um modelo de mensagem. O modelo de mensagem pode conter espaços reservados para os quais são fornecidos argumentos. Use nomes para os espaços reservados, não números.

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

A ordem dos parâmetros, não seus nomes de espaço reservado, determina quais parâmetros são usados para fornecer valores de espaço reservado nas mensagens de log. No seguinte código, os nomes de parâmetro estão fora da sequência nos espaços reservados do modelo de mensagem:

var apples = 1;
var pears = 2;
var bananas = 3;

_logger.LogInformation("Parameters: {Pears}, {Bananas}, {Apples}", apples, pears, bananas);

No entanto, os parâmetros são atribuídos aos espaços reservados na ordem: apples, pears, bananas. A mensagem de log reflete a ordem dos parâmetros:

Parameters: 1, 2, 3

Essa abordagem permite que os provedores de log implementem o log semântico ou estruturado. Os próprios argumentos são passados para o sistema de registro em log, não apenas o modelo de mensagem formatado. Essas informações permitem que os provedores de log armazenem os valores de parâmetro como campos. Por exemplo, considere o seguinte método de agente:

_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);

Por exemplo, ao registrar em log no Armazenamento de Tabelas do Azure:

  • Cada entidade da Tabela do Azure pode ter as propriedades ID e RequestTime.
  • As tabelas com propriedades simplificam as consultas nos dados registrados. Por exemplo, uma consulta pode encontrar todos os logs em um determinado intervalo de RequestTime sem precisar analisar o tempo limite da mensagem de texto.

Registrar exceções em log

Os métodos do agente têm sobrecargas que usam um parâmetro de exceção:

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

MyDisplayRouteInfo e ToCtxString são fornecidos pelo pacote NuGet Rick.Docs.Samples.RouteInfo. Os métodos exibem as informações de rota de Controller e Razor Page.

O log de exceções é específico do provedor.

Nível de log padrão

Se o nível de log padrão não for definido, o valor do nível de log padrão será Information.

Por exemplo, considere o seguinte aplicativo Web:

  • Criado com os modelos de aplicativo Web ASP.NET.
  • appsettings.json e appsettings.Development.json excluído ou renomeado.

Com a configuração anterior, o acesso à página de privacidade ou à home page gera várias mensagens Trace, Debug e Information com Microsoft no nome da categoria.

O seguinte código define o nível de log padrão quando ele não está definido na configuração:

var builder = WebApplication.CreateBuilder();
builder.Logging.SetMinimumLevel(LogLevel.Warning);

Geralmente, os níveis de log devem ser especificados na configuração, e não no código.

Função Filter

Uma função de filtro é invocada para todos os provedores e as categorias que não têm regras atribuídas por configuração ou no código:

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter((provider, category, logLevel) =>
{
    if (provider.Contains("ConsoleLoggerProvider")
        && category.Contains("Controller")
        && logLevel >= LogLevel.Information)
    {
        return true;
    }
    else if (provider.Contains("ConsoleLoggerProvider")
        && category.Contains("Microsoft")
        && logLevel >= LogLevel.Information)
    {
        return true;
    }
    else
    {
        return false;
    }
});

O código anterior exibe logs de console quando a categoria contém Controller ou Microsoft e o nível de log é Information ou superior.

Geralmente, os níveis de log devem ser especificados na configuração, e não no código.

ASP.NET Core e categorias EF Core

A seguinte tabela contém algumas categorias usadas pelo ASP.NET Core e pelo Entity Framework Core, com anotações sobre os logs:

Categoria Observações
Microsoft.AspNetCore Diagnóstico geral de ASP.NET Core.
Microsoft.AspNetCore.DataProtection Quais chaves foram consideradas, encontradas e usadas.
Microsoft.AspNetCore.HostFiltering Hosts permitidos.
Microsoft.AspNetCore.Hosting Quanto tempo levou para que as solicitações de HTTP fossem concluídas e em que horário foram iniciadas. Quais assemblies de inicialização de hospedagem foram carregados.
Microsoft.AspNetCore.Mvc Diagnóstico de Razor e MVC. Model binding, execução de filtro, compilação de exibição, seleção de ação.
Microsoft.AspNetCore.Routing Informações de correspondência de rotas.
Microsoft.AspNetCore.Server Respostas de início, parada e atividade da conexão. Informações sobre o certificado HTTPS.
Microsoft.AspNetCore.StaticFiles Arquivos atendidos.
Microsoft.EntityFrameworkCore Diagnóstico geral do Entity Framework Core. Atividade e configuração do banco de dados, detecção de alterações, migrações.

Para ver mais categorias na janela do console, defina appsettings.Development.json da seguinte maneira:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Trace",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Escopos de log

Um escopo pode agrupar um conjunto de operações lógicas. Esse agrupamento pode ser usado para anexar os mesmos dados para cada log criado como parte de um conjunto. Por exemplo, todo log criado como parte do processamento de uma transação pode incluir a ID da transação.

Um escopo:

Os seguintes provedores dão suporte a escopos:

Use um escopo por meio do encapsulamento de chamadas de agente em um bloco using:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;
    var transactionId = Guid.NewGuid().ToString();
    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

        todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            _logger.LogWarning(MyLogEvents.GetItemNotFound, 
                "Get({Id}) NOT FOUND", id);
            return NotFound();
        }
    }

    return ItemToDTO(todoItem);
}

Provedores de log internos

O ASP.NET Core inclui os seguintes provedores de log como parte da estrutura compartilhada:

Os provedores de log a seguir são fornecidos pela Microsoft, mas não como parte da estrutura compartilhada. Eles precisam ser instalados como um nuget adicional.

O ASP.NET Core não inclui um provedor de log para gravar logs em arquivos. Para gravar logs em arquivos de um aplicativo ASP.NET Core, considere usar um provedor de log de terceiros.

Para obter informações sobre stdout e o registro em log de depuração com o Módulo do ASP.NET Core, consulte Solucionar problemas do ASP.NET Core no Serviço de Aplicativo do Azure e no IIS e ANCM (Módulo do ASP.NET Core) para IIS.

Console

O provedor Console registra a saída no console. Para obter mais informações sobre como exibir logs de Console em desenvolvimento, consulte Registrar em log a saída da execução do dotnet e do Visual Studio.

Depurar

O provedor de Debug grava a saída de log usando a classe System.Diagnostics.Debug. Chamadas para System.Diagnostics.Debug.WriteLine gravam no provedor de Debug.

No Linux, o local de log do provedor de Debug depende da distribuição e pode ser um dos seguintes:

  • /var/log/message
  • /var/log/syslog

Origem do Evento

O provedor EventSource grava em uma origem do evento multiplataforma com o nome Microsoft-Extensions-Logging. No Windows, o provedor usa ETW.

ferramenta dotnet-trace

A ferramenta dotnet-trace é uma ferramenta global da CLI multiplataforma que permite a coleta de rastreamentos do .NET Core de um processo em execução. A ferramenta coleta dados do provedor Microsoft.Extensions.Logging.EventSource usando um LoggingEventSource.

Para obter instruções de instalação, consulte dotnet-trace.

Use as ferramentas de dotnet-trace para coletar um rastreamento de um aplicativo:

  1. Execute o aplicativo com o comando dotnet run.

  2. Determine o PID (identificador de processo) do aplicativo .NET Core:

    dotnet-trace ps
    

    Localize o PID do processo que tem o mesmo nome que o assembly do aplicativo.

  3. Execute o comando dotnet-trace.

    Sintaxe de comando geral:

    dotnet-trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"
    

    Ao usar um shell de comando do PowerShell, coloque o valor --providers entre aspas simples ('):

    dotnet-trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"'
    

    Em plataformas não Windows, adicione a opção -f speedscope para alterar o formato do arquivo de rastreamento de saída para speedscope.

    A seguinte tabela define a palavra-chave:

    Palavra-chave Descrição
    1 Registrar metaeventos sobre o LoggingEventSource. Não registra eventos de ILogger.
    2 Aciona o evento Message quando ILogger.Log() é chamado. Fornece informações de maneira programática (não formatada).
    4 Aciona o evento FormatMessage quando ILogger.Log() é chamado. Fornece a versão de cadeia de caracteres formatada das informações.
    8 Aciona o evento MessageJson quando ILogger.Log() é chamado. Fornece uma representação JSON dos argumentos.

    A seguinte tabela lista os níveis de erro:

    Nível do provedor Descrição
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    A análise de um nível de categoria pode ser uma cadeia de caracteres ou um número:

    Valor nomeado de categoria Valor numérico
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    O nível do provedor e o nível da categoria:

    • Têm ordem inversa.
    • As constantes de cadeia de caracteres não são todas idênticas.

    Se nenhum FilterSpecs for especificado, a implementação de EventSourceLogger tentará converter o nível do provedor em um nível de categoria e o aplicará a todas as categorias.

    Nível do provedor Nível da categoria
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    Se forem fornecidos FilterSpecs, qualquer categoria incluída na lista usará o nível de categoria codificado e todas as outras categorias serão filtradas.

    Os seguintes exemplos pressupõem que:

    • Um aplicativo esteja em execução e chamando logger.LogDebug("12345").
    • A PID (ID do processo) foi definida por meio de set PID=12345, em que 12345 é a PID real.

    Considere o seguinte código:

    dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    O comando anterior:

    • Captura mensagens de depuração.
    • Não aplica um FilterSpecs.
    • Especifica o nível 5, que mapeia a categoria de Depuração.

    Considere o seguinte código:

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    O comando anterior:

    • Não captura mensagens de depuração porque o nível 5 da categoria é Critical.
    • Fornece um FilterSpecs.

    O comando a seguir captura mensagens de depuração porque o nível 1 da categoria especifica Debug.

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    O comando a seguir captura mensagens de depuração porque a categoria especifica Debug.

    dotnet-trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    Entradas de FilterSpecs para {Logger Category} e {Category Level} representam condições adicionais de filtragem de log. Separe entradas de FilterSpecs com o caractere ponto-e-vírgula ;.

    Exemplo usando um shell de comando do Windows:

    dotnet-trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    O comando anterior ativa:

    • O agente de Origem do Evento para produzir cadeias de caracteres formatadas (4) para erros (2).
    • Registro de Microsoft.AspNetCore.Hosting no nível de registros em log Informational (4).
  4. Pare a ferramentas dotnet-trace pressionando a tecla Enter ou Ctrl+C.

    O rastreamento é salvo com o nome trace.nettrace na pasta em que o comando dotnet-trace é executado.

  5. Abra o rastreamento com Perfview. Abra o arquivo trace.nettrace e explore os eventos de rastreamento.

Se o aplicativo não compilar o host com WebApplication.CreateBuilder, adicione o provedor de Origem do Evento à configuração de log do aplicativo.

Para saber mais, veja:

Perfview

Use o utilitário PerfView para coletar e exibir logs. Há outras ferramentas para exibir os logs do ETW, mas o PerfView proporciona a melhor experiência para trabalhar com os eventos de ETW emitidos pelo ASP.NET Core.

Para configurar o PerfView para coletar eventos registrados por esse provedor, adicione a cadeia de caracteres *Microsoft-Extensions-Logging à lista Provedores Adicionais. Não se esqueça do * no início da cadeia de caracteres.

EventLog do Windows

O provedor EventLog envia a saída de log para o Log de Eventos do Windows. Diferente dos outros provedores, o provedor EventLognão herda as configurações de não provedor padrão. Se as configurações de log EventLog não forem especificadas, elas serão LogLevel.Warning por padrão.

Para registrar eventos inferiores a LogLevel.Warning, defina explicitamente o nível de log. O seguinte exemplo define o nível de log padrão do Log de Eventos como LogLevel.Information:

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

Sobrecargas de AddEventLog podem passar EventLogSettings. Se for null ou não for especificado, as seguintes configurações padrão serão usadas:

  • LogName: "Aplicativo"
  • SourceName: "Runtime do .NET"
  • MachineName: o nome do computador local é usado.

O seguinte código altera o SourceName do valor padrão de ".NET Runtime" para MyLogs:


var builder = WebApplication.CreateBuilder();
builder.Logging.AddEventLog(eventLogSettings =>
{
    eventLogSettings.SourceName = "MyLogs";
});

Serviço de aplicativo do Azure

O pacote do provedor Microsoft.Extensions.Logging.AzureAppServices grava logs em arquivos de texto no sistema de arquivos de um aplicativo do Serviço de Aplicativo do Azure e no armazenamento de blobs em uma conta de Armazenamento do Azure.

O pacote do provedor não está incluído na estrutura compartilhada. Para usar o provedor, adicione o pacote do provedor ao projeto.

Para definir as configurações do provedor, use AzureFileLoggerOptions e AzureBlobLoggerOptions, conforme mostrado no exemplo a seguir:

using Microsoft.Extensions.Logging.AzureAppServices;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddAzureWebAppDiagnostics();
builder.Services.Configure<AzureFileLoggerOptions>(options =>
{
    options.FileName = "azure-diagnostics-";
    options.FileSizeLimit = 50 * 1024;
    options.RetainedFileCountLimit = 5;
});
builder.Services.Configure<AzureBlobLoggerOptions>(options =>
{
    options.BlobName = "log.txt";
});

Quando implantado no Serviço de Aplicativo do Azure, o aplicativo usa as configurações na seção Logs do Serviço de Aplicativo da página Serviço de Aplicativo do portal do Azure. Quando as configurações a seguir são atualizadas, as alterações entram em vigor imediatamente sem a necessidade de uma reinicialização ou reimplantação do aplicativo.

  • Log de aplicativo (Sistema de Arquivos)
  • Log de aplicativo (Blob)

O local padrão dos arquivos de log é a pasta D:\\home\\LogFiles\\Application, e o nome do arquivo padrão é diagnostics-yyyymmdd.txt. O limite padrão de tamanho do arquivo é 10 MB e o número padrão máximo de arquivos mantidos é 2. O nome padrão do blob é {app-name}{timestamp}/yyyy/mm/dd/hh/{guid}-applicationLog.txt.

O provedor registra somente quando o projeto é executado no ambiente do Azure.

Fluxo de log do Azure

O streaming de log do Azure dá suporte à exibição da atividade de log em tempo usando:

  • O servidor de aplicativos
  • Do servidor Web
  • De uma solicitação de rastreio com falha

Para configurar o fluxo de log do Azure:

  • Navegue até a página Logs do Serviço de Aplicativo no portal do aplicativo.
  • Defina Habilitar o log de aplicativo (sistema de arquivos) como Ativada.
  • Escolha o Nível de log. Essa configuração se aplica somente ao streaming de log do Azure.

Navegue até a página Fluxo de Log para exibir os logs. As mensagens são registradas com a interface ILogger.

Azure Application Insights

O pacote do provedor Microsoft.Extensions.Logging.ApplicationInsights grava logs no Azure Application Insights. O Application Insights é um serviço que monitora um aplicativo web e fornece ferramentas para consultar e analisar os dados de telemetria. Se você usar esse provedor, poderá consultar e analisar os logs usando as ferramentas do Application Insights.

O provedor de registro em log é incluído como uma dependência de Microsoft.ApplicationInsights.AspNetCore, que é o pacote que fornece toda a telemetria disponível para o ASP.NET Core. Se você usar esse pacote, não precisará instalar o pacote de provedor.

O pacote Microsoft.ApplicationInsights.Web é para o ASP.NET 4.x, não para o ASP.NET Core.

Para saber mais, consulte os recursos a seguir:

Provedores de log de terceiros

Estruturas de log de terceiros que funcionam com o ASP.NET Core:

Algumas estruturas de terceiros podem fazer o log semântico, também conhecido como registro em log estruturado.

Usar uma estrutura de terceiros é semelhante ao uso de um dos provedores internos:

  1. Adicione um pacote NuGet ao projeto.
  2. Chame um método de extensão ILoggerFactory fornecido pela estrutura de registros.

Para saber mais, consulte a documentação de cada provedor. Não há suporte para provedores de log de terceiros na Microsoft.

Sem métodos de agente assíncronos

O registro em log deve ser tão rápido que não justifique o custo de desempenho de código assíncrono. Se o armazenamento de dados em log estiver lento, não grave diretamente nele. Grave as mensagens de log em um armazenamento rápido primeiro e depois passe-as para um armazenamento lento. Por exemplo, se você estiver enviado logs ao SQL Server, não faça isso diretamente em um método Log, pois os métodos Log são síncronos. Em vez disso, adicione mensagens de log de forma síncrona a uma fila na memória e faça com que uma função de trabalho de plano de fundo efetue pull das mensagens para fora da fila para fazer o trabalho assíncrono de envio de dados por push para o SQL Server. Para saber mais, consulte Diretrizes sobre como fazer logon em uma fila de mensagens para armazenamentos de dados lentos (dotnet/AspNetCore.Docs #11801).

Alterar os níveis de log em um aplicativo em execução

A API de Log não inclui um cenário para alterar os níveis de log enquanto um aplicativo está em execução. No entanto, alguns provedores de configuração conseguem recarregar a configuração, o que entra em vigor imediatamente na configuração de log. Por exemplo, o Provedor de Configuração de Arquivos recarrega a configuração de log por padrão. Se a configuração for alterada no código enquanto um aplicativo estiver em execução, o aplicativo poderá chamar IConfigurationRoot.Reload para atualizar a configuração de log do aplicativo.

ILogger e ILoggerFactory

As interfaces e implementações ILogger<TCategoryName> e ILoggerFactory estão incluídas no SDK do .NET Core. Elas também estão disponíveis nos seguintes pacotes NuGet:

Aplicar regras de filtro de log no código

A abordagem preferencial para definir regras de filtro de log é usar a Configuração.

O exemplo a seguir mostra como registrar regras de filtro no código:

using Microsoft.Extensions.Logging.Console;
using Microsoft.Extensions.Logging.Debug;

var builder = WebApplication.CreateBuilder();
builder.Logging.AddFilter("System", LogLevel.Debug);
builder.Logging.AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information);
builder.Logging.AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace);

logging.AddFilter("System", LogLevel.Debug) especifica a categoria System e o nível de log Debug. O filtro é aplicado a todos os provedores porque um provedor específico não foi configurado.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) especifica:

  • O provedor de log Debug.
  • O nível de log Information e superiores.
  • Todas as categorias começando com "Microsoft".

Registre automaticamente o escopo com SpanId, TraceId, ParentId, Baggage e Tags.

As bibliotecas de log criam implicitamente um objeto de escopo com SpanId, TraceId, ParentId, Baggage e Tags. Esse comportamento é configurado por meio de ActivityTrackingOptions.

var builder = WebApplication.CreateBuilder(args);

builder.Logging.AddSimpleConsole(options =>
{
    options.IncludeScopes = true;
});

builder.Logging.Configure(options =>
{
    options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                       | ActivityTrackingOptions.TraceId
                                       | ActivityTrackingOptions.ParentId
                                       | ActivityTrackingOptions.Baggage
                                       | ActivityTrackingOptions.Tags;
});
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Se o cabeçalho de solicitação http traceparent estiver definido, o ParentId no escopo do log mostrará o W3C parent-id do cabeçalho traceparent de entrada e o SpanId no escopo do log mostrará o parent-id atualizado para a próxima etapa/intervalo de saída. Para obter mais informações, consulte Alterando o campo traceparent.

Criar um agente personalizado

Para criar um agente personalizado, consulte Implementar um provedor de log personalizado no .NET.

Recursos adicionais

Por Kirk Larkin, Juergen Gutsch e Rick Anderson

Este tópico descreve o registro em log no .NET no que diz respeito a aplicativos ASP.NET Core. Para obter informações detalhadas sobre o registro em log no .NET, consulte Registro em log no .NET. Para saber mais sobre o registro em log em aplicativos Blazor, confira Registro em log no ASP.NET CoreBlazor.

Exibir ou baixar um código de exemplo (como baixar).

Provedores de log

Os provedores de log armazenam logs, exceto pelo provedor Console que exibe logs. Por exemplo, o provedor do Azure Application Insights armazena logs no Azure Application Insights. Vários provedores podem ser habilitados.

Os modelos padrão de aplicativo Web ASP.NET Core:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

O código anterior mostra a classe Program criada com os modelos de aplicativo Web do ASP.NET Core. As próximas seções fornecem exemplos baseados nos modelos de aplicativo Web do ASP.NET Core, que usam o Host Genérico. Aplicativos de console não host são discutidos posteriormente neste documento.

Para substituir o conjunto padrão de provedores de log adicionados por Host.CreateDefaultBuilder, chame ClearProviders e adicione os provedores de log necessários. Por exemplo, o código a seguir:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.AddConsole();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Para provedores adicionais, consulte:

Criar logs

Para criar logs, use um objeto ILogger<TCategoryName> de DI (injeção de dependência).

O exemplo a seguir:

  • Cria um agente, ILogger<AboutModel>, que usa uma categoria de log do nome totalmente qualificado do tipo AboutModel. A categoria do log é uma cadeia de caracteres associada a cada log.
  • Chama LogInformation para registrar em log no nível Information. O nível de log indica a gravidade do evento registrado.
public class AboutModel : PageModel
{
    private readonly ILogger _logger;

    public AboutModel(ILogger<AboutModel> logger)
    {
        _logger = logger;
    }
    public string Message { get; set; }

    public void OnGet()
    {
        Message = $"About page visited at {DateTime.UtcNow.ToLongTimeString()}";
        _logger.LogInformation(Message);
    }
}

Níveis e categorias serão explicados com mais detalhes posteriormente neste artigo.

Para obter informações sobre Blazor, consulte Registro em log de Blazor no ASP.NET Core.

Criar logs em Main e na Inicialização mostra como criar logs em Main e Startup.

Configurar o registro em log

A configuração de log geralmente é fornecida pela seção Logging dos arquivos appsettings.{Environment}.json. O seguinte arquivo appsettings.Development.json é gerado pelos modelos de aplicativo Web do ASP.NET Core:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

No JSON anterior:

  • As categorias "Default", "Microsoft" e "Microsoft.Hosting.Lifetime" são especificadas.
  • A categoria "Microsoft" se aplica a todas as categorias que começam com "Microsoft". Por exemplo, essa configuração se aplica à categoria "Microsoft.AspNetCore.Routing.EndpointMiddleware".
  • A categoria "Microsoft" faz o registro em log no nível Warning e superiores.
  • A categoria "Microsoft.Hosting.Lifetime" é mais específica do que a "Microsoft", portanto, a categoria "Microsoft.Hosting.Lifetime" faz o registro em log no nível "Informações" e superiores.
  • Não é especificado um provedor de log específico, portanto LogLevel se aplica a todos os provedores de log habilitados, exceto por EventLog do Windows.

A propriedade Logging pode ter LogLevel e as propriedades do provedor de logs. A LogLevel especifica o nível mínimo de log nas categorias selecionadas. No JSON anterior, os níveis de log Information e Warning são especificados. LogLevel indica a severidade do log e varia de 0 a 6:

Trace = 0, Debug = 1, Information = 2, Warning = 3, Error = 4, Critical = 5 e None = 6.

Quando um LogLevel é especificado, o registro em log é habilitado para mensagens no nível especificado e superior. No JSON anterior, a categoria Default é registrada para Information e superior. Por exemplo, mensagens Information, Warning, Error e Critical são registradas em log. Se LogLevel não for especificado, o registro em log usará o nível Information como padrão. Para obter mais informações, confira Níveis de log.

Uma propriedade de provedor pode especificar uma propriedade LogLevel. LogLevel em um provedor especifica os níveis de log desse provedor e substitui as configurações de log que não são do provedor. Considere o seguinte arquivo appsettings.json:

{
  "Logging": {
    "LogLevel": { // All providers, LogLevel applies to all the enabled providers.
      "Default": "Error", // Default logging, Error and higher.
      "Microsoft": "Warning" // All Microsoft* categories, Warning and higher.
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information", // Overrides preceding LogLevel:Default setting.
        "Microsoft.Hosting": "Trace" // Debug:Microsoft.Hosting category.
      }
    },
    "EventSource": { // EventSource provider
      "LogLevel": {
        "Default": "Warning" // All categories of EventSource provider.
      }
    }
  }
}

As configurações em Logging.{providername}.LogLevel substituem as configurações em Logging.LogLevel. No JSON anterior, o nível de log padrão do provedor Debug é definido como Information:

Logging:Debug:LogLevel:Default:Information

A configuração anterior especifica o nível de log Information para todas as categorias de Logging:Debug:, exceto a Microsoft.Hosting. Quando uma categoria específica é listada, ela substitui a categoria padrão. No JSON anterior, as categorias "Microsoft.Hosting" e "Default" de Logging:Debug:LogLevel substituem as configurações em Logging:LogLevel

O nível mínimo de log pode ser especificado para:

  • Provedores específicos: por exemplo, Logging:EventSource:LogLevel:Default:Information
  • Categorias específicas: por exemplo, Logging:LogLevel:Microsoft:Warning
  • Todos os provedores e todas as categorias: Logging:LogLevel:Default:Warning

Todos os logs abaixo do nível mínimo não são:

  • Passados para o provedor.
  • Registrados nem exibidos.

Para suprimir todos os logs, especifique LogLevel.None. LogLevel.None tem o valor 6, que é superior a LogLevel.Critical (5).

Se um provedor oferecer suporte a escopos de log, IncludeScopes indicará se eles estão habilitados. Para obter mais informações, confira Escopos de log

O seguinte arquivo appsettings.json contém todos os provedores habilitados por padrão:

{
  "Logging": {
    "LogLevel": { // No provider, LogLevel applies to all the enabled providers.
      "Default": "Error",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Warning"
    },
    "Debug": { // Debug provider.
      "LogLevel": {
        "Default": "Information" // Overrides preceding LogLevel:Default setting.
      }
    },
    "Console": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft.AspNetCore.Mvc.Razor.Internal": "Warning",
        "Microsoft.AspNetCore.Mvc.Razor.Razor": "Debug",
        "Microsoft.AspNetCore.Mvc.Razor": "Error",
        "Default": "Information"
      }
    },
    "EventSource": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "EventLog": {
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "AzureAppServicesFile": {
      "IncludeScopes": true,
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "AzureAppServicesBlob": {
      "IncludeScopes": true,
      "LogLevel": {
        "Microsoft": "Information"
      }
    },
    "ApplicationInsights": {
      "LogLevel": {
        "Default": "Information"
      }
    }
  }
}

Na amostra anterior:

  • As categorias e os níveis não são valores sugeridos. O exemplo é fornecido para mostrar todos os provedores padrão.
  • As configurações em Logging.{providername}.LogLevel substituem as configurações em Logging.LogLevel. Por exemplo, o nível em Debug.LogLevel.Default substitui o nível em LogLevel.Default.
  • Cada alias de provedor padrão é usado. Cada provedor define um alias que pode ser usado na configuração no lugar do nome de tipo totalmente qualificado. Os aliases dos provedores internos são:
    • Console
    • Depurar
    • EventSource
    • EventLog
    • AzureAppServicesFile
    • AzureAppServicesBlob
    • ApplicationInsights

Definir o nível de log por linha de comando, variáveis de ambiente e outras configurações

O nível de log pode ser definido por qualquer um dos provedores de configuração.

O separador : não funciona com chaves hierárquicas de variáveis de ambiente em todas as plataformas. __, o sublinhado duplo, tem:

  • Suporte em todas as plataformas. Por exemplo, o separador : não tem suporte pelo Bash, mas pelo __ tem.
  • Substituição automática por um :

Os seguintes comandos :

  • Defina a chave de ambiente Logging:LogLevel:Microsoft como um valor de Information no Windows.
  • Teste as configurações ao usar um aplicativo criado com os modelos de aplicativo Web do ASP.NET Core. O comando dotnet run precisa ser executado no diretório do projeto após usar set.
set Logging__LogLevel__Microsoft=Information
dotnet run

As configurações de ambiente anteriores:

  • São definidas apenas em processos iniciados na janela de comando em que foram definidos.
  • Não são lidos por navegadores iniciados com o Visual Studio.

O comando setx a seguir também define a chave e o valor do ambiente no Windows. Diferente de set, as configurações setx são persistentes. A opção /M define a variável no ambiente do sistema. Se /M não for usado, uma variável de ambiente do usuário será definida.

setx Logging__LogLevel__Microsoft Information /M

Considere o seguinte arquivo appsettings.json:

"Logging": {
    "Console": {
      "LogLevel": {
        "Microsoft.Hosting.Lifetime": "Trace"
      }
    }
}

O seguinte comando define a configuração anterior no ambiente:

setx Logging__Console__LogLevel__Microsoft.Hosting.Lifetime Trace /M

Em Serviço de Aplicativo do Azure, selecione Nova configuração de aplicativo na página Configuração > Configurações. As configurações do aplicativo do Serviço de Aplicativo do Azure são:

  • Criptografadas em repouso e transmitidas por um canal criptografado.
  • Expostas como variáveis de ambiente.

Para saber mais, confira Aplicativos do Azure: substituir a configuração do aplicativo usando o portal do Azure.

Para obter mais informações sobre como definir valores de configuração do ASP.NET Core usando variáveis de ambiente, confira variáveis de ambiente. Para obter informações sobre como usar outras fontes de configuração, incluindo a linha de comando, o Azure Key Vault, a Configuração de Aplicativos do Azure, outros formatos de arquivo e muito mais, consulte Configuração no ASP.NET Core.

Como as regras de filtragem são aplicadas

Quando um objeto ILogger<TCategoryName> é criado, o objeto ILoggerFactory seleciona uma única regra por provedor para aplicar a esse agente. Todas as mensagens gravadas pela instância ILogger são filtradas com base nas regras selecionadas. A regra mais específica possível para cada par de categoria e provedor é selecionada entre as regras disponíveis.

O algoritmo a seguir é usado para cada provedor quando um ILogger é criado para uma determinada categoria:

  • Selecione todas as regras que correspondem ao provedor ou seu alias. Se nenhuma correspondência for encontrada, selecione todas as regras com um provedor vazio.
  • Do resultado da etapa anterior, selecione as regras com o prefixo de categoria de maior correspondência. Se nenhuma correspondência for encontrada, selecione todas as regras que não especificam uma categoria.
  • Se várias regras forem selecionadas, use a última.
  • Se nenhuma regra for selecionada, use MinimumLevel.

Registrar a saída da execução do dotnet e do Visual Studio

Logs criados com os provedores de registro em log padrão são exibidos:

  • No Visual Studio
    • Na janela de saída de Depuração ao depurar.
    • Na janela do servidor Web do ASP.NET Core.
  • Na janela do console quando o aplicativo é executado com dotnet run.

Logs que começam com as categorias "Microsoft" são de código da estrutura ASP.NET Core. O ASP.NET Core e o código do aplicativo usam a mesma API de registro em log e os mesmos provedores.

Categoria do log

Quando um objeto ILogger é criado, uma categoria é especificada. Essa categoria é incluída em cada mensagem de log criada por essa instância de ILogger. A cadeia de caracteres da categoria é arbitrária, mas a convenção é usar o nome de classe. Por exemplo, em um controlador, o nome pode ser "TodoApi.Controllers.TodoController". Os aplicativos Web do ASP.NET Core usam ILogger<T> para obter automaticamente uma instância de ILogger que usa o nome de tipo totalmente qualificado como a categoria T:

public class PrivacyModel : PageModel
{
    private readonly ILogger<PrivacyModel> _logger;

    public PrivacyModel(ILogger<PrivacyModel> logger)
    {
        _logger = logger;
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.PrivacyModel called.");
    }
}

Para especificar explicitamente a categoria, chame ILoggerFactory.CreateLogger:

public class ContactModel : PageModel
{
    private readonly ILogger _logger;

    public ContactModel(ILoggerFactory logger)
    {
        _logger = logger.CreateLogger("TodoApi.Pages.ContactModel.MyCategory");
    }

    public void OnGet()
    {
        _logger.LogInformation("GET Pages.ContactModel called.");
    }

Chamar CreateLogger com um nome fixo pode ser útil quando usado em vários métodos para que os eventos possam ser organizados por categoria.

ILogger<T> é equivalente a chamar CreateLogger com o nome de tipo totalmente qualificado de T.

Nível de log

A seguinte tabela lista os valores de LogLevel, o método de extensão de conveniência Log{LogLevel} e o uso sugerido:

LogLevel Valor Método Descrição
Trace 0 LogTrace Contêm as mensagens mais detalhadas. Essas mensagens podem conter dados confidenciais do aplicativo. Essas mensagens são desabilitadas por padrão e não devem ser habilitadas em um ambiente de produção.
Depurar 1 LogDebug Para depuração e desenvolvimento. Use com cuidado em produção devido ao alto volume.
Informações 2 LogInformation Rastreia o fluxo geral do aplicativo. Pode ter um valor de longo prazo.
Aviso 3 LogWarning Para eventos anormais ou inesperados. Geralmente, inclui erros ou condições que não fazem com que o aplicativo falhe.
Erro 4 LogError Para erros e exceções que não podem ser manipulados. Essas mensagens indicam uma falha na operação ou na solicitação atual, não uma falha em todo o aplicativo.
Crítico 5 LogCritical Para falhas que exigem atenção imediata. Exemplos: cenários de perda de dados, espaço em disco insuficiente.
Nenhum 6 Especifica que uma categoria de log não deve gravar nenhuma mensagem.

Na tabela anterior, o LogLevel é listado da severidade menor para a maior.

O primeiro parâmetro do método Log, LogLevel, indica a severidade do log. Em vez de chamar Log(LogLevel, ...), a maioria dos desenvolvedores chama os métodos de extensão Log{LogLevel}. Os métodos de extensão Log{LogLevel}chamam o método Log e especificam o LogLevel. Por exemplo, estas duas chamadas de log são equivalentes em funcionalidades e produzem o mesmo log:

[HttpGet]
public IActionResult Test1(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);

    _logger.Log(LogLevel.Information, MyLogEvents.TestItem, routeInfo);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    return ControllerContext.MyDisplayRouteInfo();
}

MyLogEvents.TestItem é a ID do evento. MyLogEvents faz parte do aplicativo de exemplo e é exibido na seção ID do evento de log.

MyDisplayRouteInfo e ToCtxString são fornecidos pelo pacote NuGet Rick.Docs.Samples.RouteInfo. Os métodos exibem as informações de rota de Controller e Razor Page.

O código a seguir cria os logs Information e Warning:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

No código anterior, o primeiro parâmetro de Log{LogLevel}, MyLogEvents.GetItem, é a ID do evento de log. O segundo parâmetro é um modelo de mensagem com espaços reservados para valores de argumento fornecidos pelos parâmetros de método restantes. Os parâmetros de método serão explicados com posteriormente neste documento, na seção de modelos de mensagem.

Chame o método Log{LogLevel} adequado para controlar a quantidade de saída de log gravada em uma mídia de armazenamento específica. Por exemplo:

  • Em produção:
    • O log nos níveis Trace ou Information produz um alto volume de mensagens de log detalhadas. Para controlar os custos e não exceder os limites de armazenamento de dados, registre mensagens nos níveis Trace e Information em um armazenamento de dados de alto volume e baixo custo. Considere limitar Trace e Information a categorias específicas.
    • O registro em log nos níveis Warning a Critical deve produzir poucas mensagens de log.
      • Os custos e os limites de armazenamento geralmente não são preocupantes.
      • Poucos logs permitem mais flexibilidade nas opções de armazenamento de dados.
  • Em desenvolvimento:
    • Defina como Warning.
    • Adicione mensagens de Trace ou Information ao solucionar problemas. Para limitar a saída, defina Trace ou Information somente para as categorias em investigação.

O ASP.NET Core grava logs para eventos de estrutura. Por exemplo, considere a saída de log para:

  • Um aplicativo Razor Pages criado com os modelos do ASP.NET Core.
  • Registro em log definido como Logging:Console:LogLevel:Microsoft:Information
  • Navegação até a página Privacy:
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
      Request starting HTTP/2 GET https://localhost:5001/Privacy
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint '/Privacy'
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[3]
      Route matched with {page = "/Privacy"}. Executing page /Privacy
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[101]
      Executing handler method DefaultRP.Pages.PrivacyModel.OnGet - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[102]
      Executed handler method OnGet, returned result .
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[103]
      Executing an implicit handler method - ModelState is Valid
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[104]
      Executed an implicit handler method, returned result Microsoft.AspNetCore.Mvc.RazorPages.PageResult.
info: Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker[4]
      Executed page /Privacy in 74.5188ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint '/Privacy'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
      Request finished in 149.3023ms 200 text/html; charset=utf-8

O seguinte JSON define Logging:Console:LogLevel:Microsoft:Information:

{
  "Logging": {      // Default, all providers.
    "LogLevel": {
      "Microsoft": "Warning"
    },
    "Console": { // Console provider.
      "LogLevel": {
        "Microsoft": "Information"
      }
    }
  }
}

ID de evento de log

Cada log pode especificar uma ID do evento. O aplicativo de exemplo usa a classe MyLogEvents para definir IDs de evento:

public class MyLogEvents
{
    public const int GenerateItems = 1000;
    public const int ListItems     = 1001;
    public const int GetItem       = 1002;
    public const int InsertItem    = 1003;
    public const int UpdateItem    = 1004;
    public const int DeleteItem    = 1005;

    public const int TestItem      = 3000;

    public const int GetItemNotFound    = 4000;
    public const int UpdateItemNotFound = 4001;
}
[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

Uma ID de evento associa um conjunto de eventos. Por exemplo, todos os logs relacionados à exibição de uma lista de itens em uma página podem ser 1001.

O provedor de logs pode armazenar a ID do evento em um campo de ID na mensagem de log ou não armazenar. O provedor de Depuração não mostra IDs de eventos. O provedor de console mostra IDs de evento entre colchetes após a categoria:

info: TodoApi.Controllers.TodoItemsController[1002]
      Getting item 1
warn: TodoApi.Controllers.TodoItemsController[4000]
      Get(1) NOT FOUND

Alguns provedores de log armazenam a ID do evento em um campo, o que permite a filtragem na ID.

Modelo de mensagem de log

Cada API de log usa um modelo de mensagem. O modelo de mensagem pode conter espaços reservados para os quais são fornecidos argumentos. Use nomes para os espaços reservados, não números.

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, "Get({Id}) NOT FOUND", id);
        return NotFound();
    }

    return ItemToDTO(todoItem);
}

A ordem dos parâmetros, não seus nomes de espaço reservado, determina quais parâmetros são usados para fornecer valores de espaço reservado nas mensagens de log. No seguinte código, os nomes de parâmetro estão fora da sequência nos espaços reservados do modelo de mensagem:

var apples = 1;
var pears = 2;
var bananas = 3;

_logger.LogInformation("Parameters: {pears}, {bananas}, {apples}", apples, pears, bananas);

No entanto, os parâmetros são atribuídos aos espaços reservados na ordem: apples, pears, bananas. A mensagem de log reflete a ordem dos parâmetros:

Parameters: 1, 2, 3

Essa abordagem permite que os provedores de log implementem o log semântico ou estruturado. Os próprios argumentos são passados para o sistema de registro em log, não apenas o modelo de mensagem formatado. Essas informações permitem que os provedores de log armazenem os valores de parâmetro como campos. Por exemplo, considere o seguinte método de agente:

_logger.LogInformation("Getting item {Id} at {RequestTime}", id, DateTime.Now);

Por exemplo, ao registrar em log no Armazenamento de Tabelas do Azure:

  • Cada entidade da Tabela do Azure pode ter as propriedades ID e RequestTime.
  • As tabelas com propriedades simplificam as consultas nos dados registrados. Por exemplo, uma consulta pode encontrar todos os logs em um determinado intervalo de RequestTime sem precisar analisar o tempo limite da mensagem de texto.

Registrar exceções em log

Os métodos do agente têm sobrecargas que usam um parâmetro de exceção:

[HttpGet("{id}")]
public IActionResult TestExp(int id)
{
    var routeInfo = ControllerContext.ToCtxString(id);
    _logger.LogInformation(MyLogEvents.TestItem, routeInfo);

    try
    {
        if (id == 3)
        {
            throw new Exception("Test exception");
        }
    }
    catch (Exception ex)
    {
        _logger.LogWarning(MyLogEvents.GetItemNotFound, ex, "TestExp({Id})", id);
        return NotFound();
    }

    return ControllerContext.MyDisplayRouteInfo();
}

MyDisplayRouteInfo e ToCtxString são fornecidos pelo pacote NuGet Rick.Docs.Samples.RouteInfo. Os métodos exibem as informações de rota de Controller e Razor Page.

O log de exceções é específico do provedor.

Nível de log padrão

Se o nível de log padrão não for definido, o valor do nível de log padrão será Information.

Por exemplo, considere o seguinte aplicativo Web:

  • Criado com os modelos de aplicativo Web ASP.NET.
  • appsettings.json e appsettings.Development.json excluído ou renomeado.

Com a configuração anterior, o acesso à página de privacidade ou à home page gera várias mensagens Trace, Debug e Information com Microsoft no nome da categoria.

O seguinte código define o nível de log padrão quando ele não está definido na configuração:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging => logging.SetMinimumLevel(LogLevel.Warning))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Geralmente, os níveis de log devem ser especificados na configuração, e não no código.

Função Filter

Uma função de filtro é invocada para todos os provedores e as categorias que não têm regras atribuídas por configuração ou no código:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddFilter((provider, category, logLevel) =>
                {
                    if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Controller")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else if (provider.Contains("ConsoleLoggerProvider")
                        && category.Contains("Microsoft")
                        && logLevel >= LogLevel.Information)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

O código anterior exibe logs de console quando a categoria contém Controller ou Microsoft e o nível de log é Information ou superior.

Geralmente, os níveis de log devem ser especificados na configuração, e não no código.

ASP.NET Core e categorias EF Core

A seguinte tabela contém algumas categorias usadas pelo ASP.NET Core e pelo Entity Framework Core, com anotações sobre os logs:

Categoria Observações
Microsoft.AspNetCore Diagnóstico geral de ASP.NET Core.
Microsoft.AspNetCore.DataProtection Quais chaves foram consideradas, encontradas e usadas.
Microsoft.AspNetCore.HostFiltering Hosts permitidos.
Microsoft.AspNetCore.Hosting Quanto tempo levou para que as solicitações de HTTP fossem concluídas e em que horário foram iniciadas. Quais assemblies de inicialização de hospedagem foram carregados.
Microsoft.AspNetCore.Mvc Diagnóstico de Razor e MVC. Model binding, execução de filtro, compilação de exibição, seleção de ação.
Microsoft.AspNetCore.Routing Informações de correspondência de rotas.
Microsoft.AspNetCore.Server Respostas de início, parada e atividade da conexão. Informações sobre o certificado HTTPS.
Microsoft.AspNetCore.StaticFiles Arquivos atendidos.
Microsoft.EntityFrameworkCore Diagnóstico geral do Entity Framework Core. Atividade e configuração do banco de dados, detecção de alterações, migrações.

Para ver mais categorias na janela do console, defina appsettings.Development.json da seguinte maneira:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Trace",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Escopos de log

Um escopo pode agrupar um conjunto de operações lógicas. Esse agrupamento pode ser usado para anexar os mesmos dados para cada log criado como parte de um conjunto. Por exemplo, todo log criado como parte do processamento de uma transação pode incluir a ID da transação.

Um escopo:

Os seguintes provedores dão suporte a escopos:

Use um escopo por meio do encapsulamento de chamadas de agente em um bloco using:

[HttpGet("{id}")]
public async Task<ActionResult<TodoItemDTO>> GetTodoItem(long id)
{
    TodoItem todoItem;
    var transactionId = Guid.NewGuid().ToString();
    using (_logger.BeginScope(new List<KeyValuePair<string, object>>
        {
            new KeyValuePair<string, object>("TransactionId", transactionId),
        }))
    {
        _logger.LogInformation(MyLogEvents.GetItem, "Getting item {Id}", id);

        todoItem = await _context.TodoItems.FindAsync(id);

        if (todoItem == null)
        {
            _logger.LogWarning(MyLogEvents.GetItemNotFound, 
                "Get({Id}) NOT FOUND", id);
            return NotFound();
        }
    }

    return ItemToDTO(todoItem);
}

Provedores de log internos

O ASP.NET Core inclui os seguintes provedores de log como parte da estrutura compartilhada:

Os provedores de log a seguir são fornecidos pela Microsoft, mas não como parte da estrutura compartilhada. Eles precisam ser instalados como um nuget adicional.

O ASP.NET Core não inclui um provedor de log para gravar logs em arquivos. Para gravar logs em arquivos de um aplicativo ASP.NET Core, considere usar um provedor de log de terceiros.

Para obter informações sobre stdout e o registro em log de depuração com o Módulo do ASP.NET Core, consulte Solucionar problemas do ASP.NET Core no Serviço de Aplicativo do Azure e no IIS e ANCM (Módulo do ASP.NET Core) para IIS.

Console

O provedor Console registra a saída no console. Para obter mais informações sobre como exibir logs de Console em desenvolvimento, consulte Registrar em log a saída da execução do dotnet e do Visual Studio.

Depurar

O provedor de Debug grava a saída de log usando a classe System.Diagnostics.Debug. Chamadas para System.Diagnostics.Debug.WriteLine gravam no provedor de Debug.

No Linux, o local de log do provedor de Debug depende da distribuição e pode ser um dos seguintes:

  • /var/log/message
  • /var/log/syslog

Origem do Evento

O provedor EventSource grava em uma origem do evento multiplataforma com o nome Microsoft-Extensions-Logging. No Windows, o provedor usa ETW.

Ferramentas de rastreamento dotnet

A ferramenta dotnet-trace é uma ferramenta global multiplataforma da CLI que permite a coleta pelo .NET Core de rastreamentos de um processo em execução. A ferramenta coleta dados do provedor Microsoft.Extensions.Logging.EventSource usando um LoggingEventSource.

Consulte dotnet-trace para obter instruções de instalação.

Use as ferramentas de rastreamento do dotnet para coletar um rastreamento de um aplicativo:

  1. Execute o aplicativo com o comando dotnet run.

  2. Determine o PID (identificador de processo) do aplicativo .NET Core:

    dotnet trace ps
    

    Localize o PID do processo que tem o mesmo nome que o assembly do aplicativo.

  3. Execute o comando dotnet trace.

    Sintaxe de comando geral:

    dotnet trace collect -p {PID} 
        --providers Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"
    

    Ao usar um shell de comando do PowerShell, coloque o valor --providers entre aspas simples ('):

    dotnet trace collect -p {PID} 
        --providers 'Microsoft-Extensions-Logging:{Keyword}:{Provider Level}
            :FilterSpecs=\"
                {Logger Category 1}:{Category Level 1};
                {Logger Category 2}:{Category Level 2};
                ...
                {Logger Category N}:{Category Level N}\"'
    

    Em plataformas não Windows, adicione a opção -f speedscope para alterar o formato do arquivo de rastreamento de saída para speedscope.

    A seguinte tabela define a palavra-chave:

    Palavra-chave Descrição
    1 Registrar metaeventos sobre o LoggingEventSource. Não registra eventos de ILogger.
    2 Aciona o evento Message quando ILogger.Log() é chamado. Fornece informações de maneira programática (não formatada).
    4 Aciona o evento FormatMessage quando ILogger.Log() é chamado. Fornece a versão de cadeia de caracteres formatada das informações.
    8 Aciona o evento MessageJson quando ILogger.Log() é chamado. Fornece uma representação JSON dos argumentos.

    A seguinte tabela lista os níveis de erro:

    Nível do provedor Descrição
    0 LogAlways
    1 Critical
    2 Error
    3 Warning
    4 Informational
    5 Verbose

    A análise de um nível de categoria pode ser uma cadeia de caracteres ou um número:

    Valor nomeado de categoria Valor numérico
    Trace 0
    Debug 1
    Information 2
    Warning 3
    Error 4
    Critical 5

    O nível do provedor e o nível da categoria:

    • Têm ordem inversa.
    • As constantes de cadeia de caracteres não são todas idênticas.

    Se nenhum FilterSpecs for especificado, a implementação de EventSourceLogger tentará converter o nível do provedor em um nível de categoria e o aplicará a todas as categorias.

    Nível do provedor Nível da categoria
    Verbose(5) Debug(1)
    Informational(4) Information(2)
    Warning(3) Warning(3)
    Error(2) Error(4)
    Critical(1) Critical(5)

    Se forem fornecidos FilterSpecs, qualquer categoria incluída na lista usará o nível de categoria codificado e todas as outras categorias serão filtradas.

    Os seguintes exemplos pressupõem que:

    • Um aplicativo esteja em execução e chamando logger.LogDebug("12345").
    • A PID (ID do processo) foi definida por meio de set PID=12345, em que 12345 é a PID real.

    Considere o seguinte código:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:5
    

    O comando anterior:

    • Captura mensagens de depuração.
    • Não aplica um FilterSpecs.
    • Especifica o nível 5, que mapeia a categoria de Depuração.

    Considere o seguinte código:

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:5\"
    

    O comando anterior:

    • Não captura mensagens de depuração porque o nível 5 da categoria é Critical.
    • Fornece um FilterSpecs.

    O comando a seguir captura mensagens de depuração porque o nível 1 da categoria especifica Debug.

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:1\"
    

    O comando a seguir captura mensagens de depuração porque a categoria especifica Debug.

    dotnet trace collect -p %PID%  --providers Microsoft-Extensions-Logging:4:5:\"FilterSpecs=*:Debug\"
    

    Entradas de FilterSpecs para {Logger Category} e {Category Level} representam condições adicionais de filtragem de log. Separe entradas de FilterSpecs com o caractere ponto-e-vírgula ;.

    Exemplo usando um shell de comando do Windows:

    dotnet trace collect -p %PID% --providers Microsoft-Extensions-Logging:4:2:FilterSpecs=\"Microsoft.AspNetCore.Hosting*:4\"
    

    O comando anterior ativa:

    • O agente de Origem do Evento para produzir cadeias de caracteres formatadas (4) para erros (2).
    • Registro de Microsoft.AspNetCore.Hosting no nível de registros em log Informational (4).
  4. Interrompa as ferramentas de rastreamento do dotnet pressionando a tecla Enter ou Ctrl+C.

    O rastreamento é salvo com o nome trace.nettrace na pasta em que o comando dotnet trace é executado.

  5. Abra o rastreamento com Perfview. Abra o arquivo trace.nettrace e explore os eventos de rastreamento.

Se o aplicativo não compilar o host com CreateDefaultBuilder, adicione o provedor de Origem do Evento à configuração de log do aplicativo.

Para saber mais, veja:

Perfview

Use o utilitário PerfView para coletar e exibir logs. Há outras ferramentas para exibir os logs do ETW, mas o PerfView proporciona a melhor experiência para trabalhar com os eventos de ETW emitidos pelo ASP.NET Core.

Para configurar o PerfView para coletar eventos registrados por esse provedor, adicione a cadeia de caracteres *Microsoft-Extensions-Logging à lista Provedores Adicionais. Não se esqueça do * no início da cadeia de caracteres.

EventLog do Windows

O provedor EventLog envia a saída de log para o Log de Eventos do Windows. Diferente dos outros provedores, o provedor EventLognão herda as configurações de não provedor padrão. Se as configurações de log EventLog não forem especificadas, elas serão LogLevel.Warning por padrão.

Para registrar eventos inferiores a LogLevel.Warning, defina explicitamente o nível de log. O seguinte exemplo define o nível de log padrão do Log de Eventos como LogLevel.Information:

"Logging": {
  "EventLog": {
    "LogLevel": {
      "Default": "Information"
    }
  }
}

Sobrecargas de AddEventLog podem passar em EventLogSettings. Se for null ou não for especificado, as seguintes configurações padrão serão usadas:

  • LogName: "Aplicativo"
  • SourceName: "Runtime do .NET"
  • MachineName: o nome do computador local é usado.

O seguinte código altera o SourceName do valor padrão de ".NET Runtime" para MyLogs:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
            {
                logging.AddEventLog(eventLogSettings =>
                {
                    eventLogSettings.SourceName = "MyLogs"; 
                });
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Serviço de aplicativo do Azure

O pacote de provedor Microsoft.Extensions.Logging.AzureAppServices grava logs em arquivos de texto no sistema de arquivos de um aplicativo do Serviço de Aplicativo do Azure e no armazenamento de blobs em uma conta de Armazenamento do Azure.

O pacote do provedor não está incluído na estrutura compartilhada. Para usar o provedor, adicione o pacote do provedor ao projeto.

Para definir as configurações do provedor, use AzureFileLoggerOptions e AzureBlobLoggerOptions, conforme mostrado no exemplo a seguir:

public class Scopes
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging(logging => logging.AddAzureWebAppDiagnostics())
                .ConfigureServices(serviceCollection => serviceCollection
                    .Configure<AzureFileLoggerOptions>(options =>
                    {
                        options.FileName = "azure-diagnostics-";
                        options.FileSizeLimit = 50 * 1024;
                        options.RetainedFileCountLimit = 5;
                    })
                    .Configure<AzureBlobLoggerOptions>(options =>
                    {
                        options.BlobName = "log.txt";
                    }))
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

Quando implantado no Serviço de Aplicativo do Azure, o aplicativo usa as configurações na seção Logs do Serviço de Aplicativo da página Serviço de Aplicativo do portal do Azure. Quando as configurações a seguir são atualizadas, as alterações entram em vigor imediatamente sem a necessidade de uma reinicialização ou reimplantação do aplicativo.

  • Log de aplicativo (Sistema de Arquivos)
  • Log de aplicativo (Blob)

O local padrão para arquivos de log é na pasta D:\home\LogFiles\Application e o nome de arquivo padrão é diagnostics-yyyymmdd.txt. O limite padrão de tamanho do arquivo é 10 MB e o número padrão máximo de arquivos mantidos é 2. O nome de blob padrão é {app-name}{timestamp}/aaaa/mm/dd/hh/{guid}-applicationLog.txt.

O provedor registra somente quando o projeto é executado no ambiente do Azure.

Fluxo de log do Azure

O streaming de log do Azure dá suporte à exibição da atividade de log em tempo usando:

  • O servidor de aplicativos
  • Do servidor Web
  • De uma solicitação de rastreio com falha

Para configurar o fluxo de log do Azure:

  • Navegue até a página Logs do Serviço de Aplicativo no portal do aplicativo.
  • Defina Habilitar o log de aplicativo (sistema de arquivos) como Ativada.
  • Escolha o Nível de log. Essa configuração se aplica somente ao streaming de log do Azure.

Navegue até a página Fluxo de Log para exibir os logs. As mensagens são registradas com a interface ILogger.

Azure Application Insights

O pacote de provedor Microsoft.Extensions.Logging.ApplicationInsights grava os logs no Azure Application Insights. O Application Insights é um serviço que monitora um aplicativo web e fornece ferramentas para consultar e analisar os dados de telemetria. Se você usar esse provedor, poderá consultar e analisar os logs usando as ferramentas do Application Insights.

O provedor de registro em log está incluído como uma dependência de Microsoft.ApplicationInsights.AspNetCore, que é o pacote que fornece toda a telemetria disponível para o ASP.NET Core. Se você usar esse pacote, não precisará instalar o pacote de provedor.

O pacote Microsoft.ApplicationInsights.Web é voltado para o ASP.NET 4.x, não para o ASP.NET Core.

Para saber mais, consulte os recursos a seguir:

Provedores de log de terceiros

Estruturas de log de terceiros que funcionam com o ASP.NET Core:

Algumas estruturas de terceiros podem fazer o log semântico, também conhecido como registro em log estruturado.

Usar uma estrutura de terceiros é semelhante ao uso de um dos provedores internos:

  1. Adicione um pacote NuGet ao projeto.
  2. Chame um método de extensão ILoggerFactory fornecido pela estrutura de registros.

Para saber mais, consulte a documentação de cada provedor. Não há suporte para provedores de log de terceiros na Microsoft.

Aplicativo de console sem host

Para obter um exemplo de como usar o Host Genérico em um aplicativo de console não Web, consulte o arquivo Program.cs do Aplicativo de exemplo Tarefas em Segundo Plano (Tarefas em segundo plano com serviços hospedados no ASP.NET Core).

O código de registro em log para os aplicativos sem Host Genérico difere na forma como os provedores são adicionados e os agentes são criados.

Provedores de log

Em um aplicativo de console não host, chame o método de extensão Add{provider name} do provedor ao criar um LoggerFactory:

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

Criar logs

Para criar logs, use um objeto ILogger<TCategoryName>. Use o LoggerFactory para criar um ILogger.

O exemplo a seguir cria um agente da categoria LoggingConsoleApp.Program.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

No exemplo a seguir, o agente é usado para criar logs de nível Information. O nível de log indica a gravidade do evento registrado.

class Program
{
    static void Main(string[] args)
    {
        using var loggerFactory = LoggerFactory.Create(builder =>
        {
            builder
                .AddFilter("Microsoft", LogLevel.Warning)
                .AddFilter("System", LogLevel.Warning)
                .AddFilter("LoggingConsoleApp.Program", LogLevel.Debug)
                .AddConsole()
                .AddEventLog();
        });
        ILogger logger = loggerFactory.CreateLogger<Program>();
        logger.LogInformation("Example log message");
    }
}

Níveis e categorias serão explicados com mais detalhes neste documento.

Log durante a construção do host

Não há suporte para o registro em log durante a construção do host. No entanto, um agente separado pode ser usado. No exemplo a seguir, um agente Serilog é usado para registrar em CreateHostBuilder. AddSerilog usa a configuração estática especificada em Log.Logger:

using System;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args)
    {
        var builtConfig = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json")
            .AddCommandLine(args)
            .Build();

        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .WriteTo.File(builtConfig["Logging:FilePath"])
            .CreateLogger();

        try
        {
            return Host.CreateDefaultBuilder(args)
                .ConfigureServices((context, services) =>
                {
                    services.AddRazorPages();
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddConfiguration(builtConfig);
                })
                .ConfigureLogging(logging =>
                {   
                    logging.AddSerilog();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host builder error");

            throw;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}

Configurar um serviço que depende do ILogger

A injeção de construtor de um agente em Startup funciona em versões anteriores do ASP.NET Core porque um contêiner de DI separado é criado para o host da Web. Para obter informações sobre por que apenas um contêiner é criado para o host genérico, consulte o anúncio de alteração da falha.

Para configurar um serviço que depende de ILogger<T>, use a injeção de construtor ou forneça um método de fábrica. A abordagem do método de fábrica é recomendada somente se não há nenhuma outra opção. Por exemplo, considere um serviço que precisa de uma instância de ILogger<T> fornecida pelo DI:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddRazorPages();

    services.AddSingleton<IMyService>((container) =>
    {
        var logger = container.GetRequiredService<ILogger<MyService>>();
        return new MyService() { Logger = logger };
    });
}

O código realçado anterior é um Func<T,TResult> que é executado na primeira vez que o contêiner de DI precisa construir uma instância de MyService. Você pode acessar qualquer um dos serviços registrados dessa maneira.

Criar logs em Main

O seguinte código registra logs em Main obtendo uma instância de ILogger da DI após a criação do host:

public static void Main(string[] args)
{
    var host = CreateHostBuilder(args).Build();

    var logger = host.Services.GetRequiredService<ILogger<Program>>();
    logger.LogInformation("Host created.");

    host.Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Criar logs na inicialização

O seguinte código grava logs Startup.Configure:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env,
                      ILogger<Startup> logger)
{
    if (env.IsDevelopment())
    {
        logger.LogInformation("In Development.");
        app.UseDeveloperExceptionPage();
    }
    else
    {
        logger.LogInformation("Not Development.");
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
        endpoints.MapRazorPages();
    });
}

A gravação de logs antes da conclusão da configuração do contêiner de DI no método Startup.ConfigureServices não é uma ação compatível:

  • A injeção de agente no construtor Startup não é uma ação compatível.
  • A injeção de agente na assinatura do método Startup.ConfigureServices não é uma ação compatível

O motivo para essa restrição é que o registro em log depende da DI e da configuração, a qual por sua vez depende da DI. O contêiner de DI não é configurado até ConfigureServices ser concluído.

Para obter informações sobre como configurar um serviço que depende ILogger<T> ou sobre por que a injeção de construtor de um agente em Startup funcionava em versões anteriores, consulte Configurar um serviço que depende do ILogger

Sem métodos de agente assíncronos

O registro em log deve ser tão rápido que não justifique o custo de desempenho de código assíncrono. Se o armazenamento de dados em log estiver lento, não grave diretamente nele. Grave as mensagens de log em um armazenamento rápido primeiro e depois passe-as para um armazenamento lento. Por exemplo, se você estiver enviado logs ao SQL Server, não faça isso diretamente em um método Log, pois os métodos Log são síncronos. Em vez disso, adicione mensagens de log de forma síncrona a uma fila na memória e faça com que uma função de trabalho de plano de fundo efetue pull das mensagens para fora da fila para fazer o trabalho assíncrono de envio de dados por push para o SQL Server. Saiba mais neste tópico do GitHub.

Alterar os níveis de log em um aplicativo em execução

A API de Log não inclui um cenário para alterar os níveis de log enquanto um aplicativo está em execução. No entanto, alguns provedores de configuração conseguem recarregar a configuração, o que entra em vigor imediatamente na configuração de log. Por exemplo, o Provedor de Configuração de Arquivos recarrega a configuração de log por padrão. Se a configuração for alterada no código enquanto um aplicativo estiver em execução, o aplicativo poderá chamar IConfigurationRoot.Reload para atualizar a configuração de log do aplicativo.

ILogger e ILoggerFactory

As interfaces e implementações ILogger<TCategoryName> e ILoggerFactory estão incluídas no SDK do .NET Core. Elas também estão disponíveis nos seguintes pacotes NuGet:

Aplicar regras de filtro de log no código

A abordagem preferencial para definir regras de filtro de log é usar a Configuração.

O exemplo a seguir mostra como registrar regras de filtro no código:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureLogging(logging =>
               logging.AddFilter("System", LogLevel.Debug)
                  .AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information)
                  .AddFilter<ConsoleLoggerProvider>("Microsoft", LogLevel.Trace))
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

logging.AddFilter("System", LogLevel.Debug) especifica a categoria System e o nível de log Debug. O filtro é aplicado a todos os provedores porque um provedor específico não foi configurado.

AddFilter<DebugLoggerProvider>("Microsoft", LogLevel.Information) especifica:

  • O provedor de log Debug.
  • O nível de log Information e superiores.
  • Todas as categorias começando com "Microsoft".

Escopo de log automático com SpanId, TraceId e ParentId

As bibliotecas de log criam implicitamente um objeto de escopo com SpanId, TraceId e ParentId. Esse comportamento é configurado por meio de ActivityTrackingOptions.

  var loggerFactory = LoggerFactory.Create(logging =>
  {
      logging.Configure(options =>
      {
          options.ActivityTrackingOptions = ActivityTrackingOptions.SpanId
                                              | ActivityTrackingOptions.TraceId
                                              | ActivityTrackingOptions.ParentId;
      }).AddSimpleConsole(options =>
      {
          options.IncludeScopes = true;
      });
  });

Se o cabeçalho de solicitação http traceparent estiver definido, o ParentId no escopo do log mostrará o W3C parent-id do cabeçalho traceparent de entrada e o SpanId no escopo do log mostrará o parent-id atualizado para a próxima etapa/intervalo de saída. Para obter mais informações, consulte Alterando o campo traceparent.

Criar um agente personalizado

Para criar um agente personalizado, consulte Implementar um provedor de log personalizado no .NET.

Recursos adicionais