O Serilog tem seis níveis de log, do menos para o mais grave: Verbose, Debug, Information, Warning, Error e Fatal. A própria documentação de configuração do Serilog informa o padrão: “se nenhum MinimumLevel for especificado, os eventos de nível Information e superiores serão processados”. Esse também é o padrão sensato para os logs de aplicação em produção.
Neste guia, definimos níveis mínimos globalmente, por namespace e por sink: os três controles que decidem o que de fato é gravado.
Configuração do Serilog
Antes de vermos os diferentes níveis de log, precisamos adicionar o pacote NuGet Serilog.AspNetCore ao projeto ASP.NET Core MVC (dotnet add package Serilog.AspNetCore --version 10.0.0) e configurá-lo para usar o Serilog:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSerilog(options =>
{
options.MinimumLevel.Information()
.WriteTo.Console(LogEventLevel.Information);
});
Este trecho de código pressupõe using Serilog; e using Serilog.Events; no início do arquivo. O primeiro argumento posicional de WriteTo.Console(LogEventLevel.Information) é restrictedToMinimumLevel, e vale a pena nomeá-lo explicitamente porque só apresentamos essa configuração mais adiante neste artigo.
Para se aprofundar no uso do Serilog, não deixe de conferir o artigo sobre logging estruturado no ASP.NET Core com Serilog.
Vamos começar pelos níveis de log.
Quais são os diferentes níveis de log no Serilog?
Os níveis de log permitem classificar a gravidade do evento registrado. O Serilog oferece seis níveis de log:
O Serilog classifica cada evento de log com um dos seis níveis, ordenados por gravidade: Verbose, Debug, Information, Warning, Error e Fatal. Verbose é o que gera mais ruído: fluxo interno e payloads brutos que só ativamos quando estamos investigando um problema específico. Debug traz estado de diagnóstico útil para os desenvolvedores, mas não para a equipe de operações.
Information registra a vida normal da aplicação: requisições atendidas, pedidos feitos, jobs concluídos. Warning sinaliza situações inesperadas, mas contornáveis, como uma nova tentativa ou um fallback. Error significa que uma operação falhou e que alguém deveria analisá-la, enquanto Fatal significa que a própria aplicação não consegue continuar.
O Serilog só grava um evento quando o nível dele é igual ou superior ao mínimo configurado: Information por padrão. Os nomes diferem um pouco dos níveis de ILogger da Microsoft: o Verbose do Serilog corresponde a Trace, e Fatal corresponde a Critical; os outros quatro coincidem um a um.
| Nível do Serilog | Método do ILogger | Para que usar | Registrar em produção? |
|---|---|---|---|
Verbose | LogTrace() | Rastreamento de detalhes internos, loops, payloads | Não |
Debug | LogDebug() | Estado de diagnóstico para desenvolvedores | Não (ative quando precisar) |
Information | LogInformation() | Eventos de negócio, fluxo das requisições | Sim |
Warning | LogWarning() | Situações inesperadas, mas tratadas | Sim |
Error | LogError() | Operações com falha que exigem atenção | Sim |
Fatal | LogCritical() | Quedas da aplicação, estados irrecuperáveis | Sim (com alerta) |
O Serilog não tem um nível Critical nem um nível Trace; Fatal e Verbose são os equivalentes, e o mapeamento acima é exatamente como Serilog.Extensions.Logging os traduz.
À medida que o nível de log sobe de Verbose para Fatal, a importância dele também aumenta.
Geração de mensagens de log em diferentes níveis
O ASP.NET Core oferece a interface ILogger<T> para as situações de logging, qualquer que seja a infraestrutura de logging usada. Basta injetar a interface ILogger<T> no construtor e já podemos começar a registrar logs.
Com isso em mente, vejamos como gerar logs em cada nível de log:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
public IActionResult Index()
{
_logger.LogTrace("Trace Log Message");
_logger.LogDebug("Debug Log Message");
_logger.LogInformation("Information Log Message");
_logger.LogWarning("Warning Log Message");
_logger.LogError("Error Log Message");
_logger.LogCritical("Critical Log Message");
return View();
}
}
Como mencionamos antes, no construtor de HomeController injetamos a interface ILogger<HomeController>, que usamos para inicializar a instância _logger. Depois, no método Index(), usamos _logger para registrar uma mensagem em cada um dos níveis de log disponíveis.

E-book gratuito
Sua Web API está pronta para produção?
33 itens para verificar antes de implantá-la, com a correção de cada um. Um PDF gratuito de 76 páginas para .NET 10.
O e-book está em inglês.
Baixe o checklist gratuitoPDF gratuito. Um único e-mail para enviá-lo. Cancele a inscrição quando quiser.
O Serilog se conecta a essa interface por meio de Serilog.Extensions.Logging; tratamos a relação completa em artigos dedicados, incluindo como usar o Serilog com a API ILogger da Microsoft e como ILogger, ILoggerFactory e ILoggerProvider se encaixam.
Como definir o nível mínimo de log no Serilog?
O Serilog oferece três pontos para controlar o nível mínimo, e eles são aplicados nesta ordem. Primeiro, MinimumLevel.Default (ou MinimumLevel.Information() na API fluente) define o limite mínimo global: os eventos abaixo dele nunca são criados, então quase não custam nada.
Em segundo lugar, MinimumLevel.Override sobrescreve o limite mínimo para namespaces específicos; sobrescrever o nível de Microsoft e System para Warning é a forma padrão de silenciar o ruído do framework sem perder os nossos próprios eventos Information. Em terceiro lugar, restrictedToMinimumLevel filtra por sink, de modo que o console pode mostrar Information enquanto o sink de arquivo registra apenas Warning e níveis superiores.
O nível mínimo global vem antes de tudo: um sink pode ser mais restritivo que o nível global, nunca menos. Para os níveis que queremos mudar em tempo de execução sem reimplantar a aplicação, passamos um LoggingLevelSwitch para MinimumLevel.ControlledBy() e mudamos o valor dele em tempo de execução, a partir de um endpoint administrativo ou de um recarregamento da configuração. Não é preciso reimplantar nem reiniciar, e a mudança vale imediatamente em todos os sinks.
Na prática, o limite mínimo muda conforme o ambiente: Debug durante o desenvolvimento e Information em produção, ambiente em que o Serilog passa a registrar apenas eventos Information, Warning, Error e Fatal.
Vejamos como configurar MinimumLevel no arquivo appSettings.json:
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
}
}
Aqui, instruímos o Serilog a gerar logs da aplicação para os níveis iguais ou superiores ao nível de log Information. Além disso, sobrescrevemos o logging das mensagens de Microsoft e System, garantindo que elas sejam registradas somente quando forem de nível Warning ou superior. Para que o Serilog leia essa seção, chamamos options.ReadFrom.Configuration(builder.Configuration) dentro de AddSerilog().
Agora vamos fazer a mesma configuração pela API fluente em Program.cs:
builder.Services.AddSerilog(options =>
{
options.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("System", LogEventLevel.Warning);
});
Para mudar o nível mínimo em tempo de execução sem reimplantar, envolvemos o nível em um LoggingLevelSwitch (que exige using Serilog.Core; no início do arquivo) e passamos esse objeto para MinimumLevel.ControlledBy(); depois, basta mudar o nível do objeto em qualquer ponto do código que tenha uma referência a ele, como um endpoint administrativo:
var levelSwitch = new LoggingLevelSwitch(LogEventLevel.Information);
builder.Services.AddSerilog(options =>
{
options.MinimumLevel.ControlledBy(levelSwitch)
.WriteTo.Console();
});
// later, at runtime, e.g. from an admin endpoint:
levelSwitch.MinimumLevel = LogEventLevel.Debug;
Observe que só levelSwitch.MinimumLevel muda aqui; a configuração do sink em si continua intacta, e o novo mínimo entra em vigor já na próxima chamada de log, sem reinicialização.
Onde registrar os logs?
Podemos configurar o Serilog para gravar logs em diferentes destinos, ou sinks. No contexto de logging, um sink é o destino das nossas mensagens de log. Estes são alguns dos sinks mais comuns:
- O console da aplicação
- O sistema de arquivos
- Bancos de dados relacionais, como o MS SQL Server
- Bancos de dados não relacionais, como o Elasticsearch ou o MongoDB
A própria documentação de configuração do Serilog explica assim: “Os sinks de eventos de log geralmente gravam os eventos de log em alguma representação externa, normalmente o console, um arquivo ou um armazenamento de dados.” Adicionamos os sinks com o objeto de configuração WriteTo, e todos os sinks disponíveis aceitam um argumento restrictedToMinimumLevel, de modo que cada destino pode ter um limite mínimo próprio, acima do global.
Há uma lista selecionada dos sinks disponíveis aqui. Para se aprofundar nos sinks, confira o artigo sobre logging estruturado no ASP.NET Core com Serilog. Quando o sink é o sistema de arquivos, o artigo sobre logging em arquivos com rotação no Serilog explica em detalhes a rotação por tamanho e por tempo.

E-book gratuito
Sua Web API está pronta para produção?
33 itens para verificar antes de implantá-la, com a correção de cada um. Um PDF gratuito de 76 páginas para .NET 10.
O e-book está em inglês.
Baixe o checklist gratuitoPDF gratuito. Um único e-mail para enviá-lo. Cancele a inscrição quando quiser.
Podemos configurar os sinks do Serilog no arquivo appSettings.json ou pela API fluente no arquivo Program.cs.
Configuração dos sinks no appsettings.json
Vamos configurar um sink de console e um sink de arquivo pelo appSettings.json:
"Serilog": {
"Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Console" ],
"WriteTo": [
{
"Name": "Console",
"Args": {
"restrictedToMinimumLevel": "Information",
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "logs/log-.txt",
"rollOnFileSizeLimit": true,
"rollingInterval": "Day",
"fileSizeLimitBytes": "1000000",
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}",
"restrictedToMinimumLevel": "Warning"
}
}
]
}
Primeiro, especificamos os assemblies dos sinks por meio da opção Using. Depois, configuramos cada sink pela opção WriteTo. Ela recebe um array de sinks com as respectivas configurações.
Configuração dos sinks pela API fluente
Agora vejamos como configurar os sinks de logging usando a API fluente em Program.cs:
builder.Services.AddSerilog(options =>
{
options.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("System", LogEventLevel.Warning)
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Information,
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}")
.WriteTo.File("logs/log-.txt",
rollOnFileSizeLimit: true,
rollingInterval: RollingInterval.Day,
fileSizeLimitBytes: 1000000,
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}",
restrictedToMinimumLevel: LogEventLevel.Warning);
});
Diferenciação dos sinks de log conforme o nível de log
Dependendo dos requisitos e do ambiente da aplicação, talvez seja preciso configurar o Serilog para gravar determinados níveis de log em determinados sinks. Por exemplo, podemos querer gravar no console os logs com nível mínimo Information, mas, em um arquivo, os logs com nível mínimo Warning. Nessas circunstâncias, usamos a configuração restrictedToMinimumLevel. Ela permite que o Serilog diferencie os destinos dos logs com base no nível mínimo de log.
Podemos aplicar a configuração restrictedToMinimumLevel pelo appSettings.json:
"Serilog": {
"Using": [ "Serilog.Sinks.File", "Serilog.Sinks.Console" ],
"WriteTo": [
{
"Name": "Console",
"Args": {
"restrictedToMinimumLevel": "Information"
}
},
{
"Name": "File",
"Args": {
"path": "logs/log-.txt",
"restrictedToMinimumLevel": "Warning"
}
}
]
}
Da mesma forma, podemos configurar restrictedToMinimumLevel pela API fluente:
builder.Services.AddSerilog(options =>
{
options.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Information)
.WriteTo.File("logs/log-.txt",
restrictedToMinimumLevel: LogEventLevel.Warning);
});
Conclusão
Neste artigo, vimos os níveis de log do Serilog e como usá-los em uma aplicação. Definimos o limite mínimo com a configuração MinimumLevel, configuramos os sinks tanto pelo arquivo appSettings.json quanto pela API fluente e usamos restrictedToMinimumLevel para dar a cada sink um limite próprio.
Para um conjunto mais amplo de boas práticas de logging com Serilog, que vai além da escolha dos níveis, apresentamos o panorama completo em um guia dedicado.
Testado com o .NET 10.0.10, o Serilog 4.4.0 e o Serilog.AspNetCore 10.0.0.