Serilog e .NET Framework com C#
Postado em : 06/10/2023
Serilog e .NET Framework com C
Serilog é uma biblioteca de registro estruturado para .NET. Ele é fácil de configurar, possui uma API limpa e é portátil entre várias plataformas. Vamos ver como configurar o Serilog para um projeto .NET Framework usando C#.
Vantagens do Serilog
O Serilog oferece várias vantagens em relação a outras bibliotecas de registro:
-
Registro Estruturado: Ao contrário do registro de texto tradicional, o registro estruturado permite que você capture mais informações em um formato que é mais fácil de processar e analisar.
-
Sinks: Serilog suporta uma ampla variedade de sinks, permitindo que você envie seus logs para quase qualquer lugar, desde arquivos locais até serviços de log remotos.
-
Integração Fácil: Serilog pode ser facilmente integrado com .NET Framework e .NET Core, e suporta muitos dos mesmos padrões de registro.
-
Desempenho: Serilog é projetado para ser rápido e eficiente, minimizando o impacto no desempenho do seu aplicativo.
Configuração Inicial
Primeiro, você precisa instalar o pacote NuGet Serilog. Você pode fazer isso através do Gerenciador de Pacotes NuGet ou através da Linha de Comando do Gerenciador de Pacotes com o seguinte comando:
Install-Package Serilog
Depois de instalado, você pode configurar o Serilog no seu arquivo Program.cs
ou Startup.cs
, dependendo da natureza do seu projeto.
using Serilog; public class Program { public static void Main() { Log.Logger = new LoggerConfiguration() .WriteTo.Console() .CreateLogger(); Log.Information("Hello, Serilog!"); Log.CloseAndFlush(); } }
Neste exemplo, estamos configurando o Serilog para registrar mensagens no console. A chamada Log.CloseAndFlush()
garante que todos os eventos pendentes sejam liberados antes que o aplicativo seja encerrado.
Registro Estruturado
Uma das principais vantagens do Serilog é o suporte para registro estruturado. Isso significa que você pode registrar eventos complexos com várias propriedades e o Serilog será capaz de formatá-los de maneira legível ou serializá-los como JSON para armazenamento e análise.
var position = new { Latitude = 25, Longitude = 134 }; var elapsedMs = 34; Log.Information("Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs);
Neste exemplo, @Position
e {Elapsed:000}
são propriedades estruturadas. O uso do sinal @
instrui o Serilog a serializar a propriedade Position
como um objeto estruturado em vez de convertê-lo em uma string.
Sink
Serilog usa algo chamado "sinks" para determinar onde as mensagens de log serão enviadas. No exemplo anterior, usamos o sink do console, mas muitos outros estão disponíveis para coisas como arquivos de texto, bancos de dados SQL e serviços de log remotos.
Para usar um sink diferente, você precisará instalar o pacote NuGet apropriado e então poderá adicioná-lo à sua configuração.
Install-Package Serilog.Sinks.File
Log.Logger = new LoggerConfiguration() .WriteTo.File("log.txt") .CreateLogger();
Neste exemplo, estamos usando o sink do arquivo para gravar mensagens de log em um arquivo chamado log.txt
.
Aqui está um exemplo de como você pode configurar o Serilog para registrar logs em um arquivo ao chamar um endpoint de uma API usando o Serilog.Sinks.File
Configure o Serilog no método Startup
do seu aplicativo:
public class Startup { public Startup(IHostingEnvironment env) { Log.Logger = new LoggerConfiguration() .WriteTo.File("Logs/MeusLogs.txt", rollingInterval: RollingInterval.Day) .CreateLogger(); } }
Aqui, estamos configurando o Serilog para registrar mensagens em um arquivo chamado MeusLogs.txt
na pasta Logs
. O parâmetro rollingInterval: RollingInterval.Day
faz com que o Serilog crie um novo arquivo de log a cada dia.
Agora, você pode usar o Serilog para registrar informações em qualquer lugar do seu aplicativo. Por exemplo, aqui está como você pode registrar informações ao chamar um endpoint de API:
[Route("api/[controller]")] public class MyController : Controller { [HttpGet] public IActionResult Get() { Log.Information("GET request received for MyController"); return Ok(); } }
Neste exemplo, estamos registrando uma mensagem de informação sempre que o endpoint GET do MyController
é chamado. As mensagens de log serão escritas no arquivo myapp.txt
.
Lembre-se de chamar Log.CloseAndFlush()
no método Dispose
ou Shutdown
do seu aplicativo para garantir que todos os eventos de log pendentes sejam liberados antes que o aplicativo seja encerrado.
Agora, vamos supor que você fez uma solicitação GET para este endpoint. O conteúdo do arquivo de log MeusLogs.txt
seria algo assim:
2023-10-06 14:32:21.123 +00:00 [INF] GET request received for MyController
Aqui está um exemplo de como você pode configurar o Serilog para registrar automaticamente as exceções em um aplicativo C# e gravá-las em um arquivo de texto. Além disso, este exemplo mostra como capturar o payload e o cabeçalho da requisição na entrada do endpoint de uma API.
Configure o Serilog no método Startup
do seu aplicativo:
public class Startup { public void Configuration(IAppBuilder app) { Log.Logger = new LoggerConfiguration() .Enrich.FromLogContext() .WriteTo.File("Logs/MeusLogs.txt", rollingInterval: RollingInterval.Day) .CreateLogger(); app.Use(async (context, next) => { // Captura o payload da requisição context.Request.EnableRewind(); var buffer = new byte[Convert.ToInt32(context.Request.ContentLength)]; await context.Request.Body.ReadAsync(buffer, 0, buffer.Length); var requestBody = Encoding.UTF8.GetString(buffer); context.Request.Body.Position = 0; // Captura o cabeçalho da requisição var requestHeaders = context.Request.Headers; Log.Information("Request Headers: {@Headers}", requestHeaders); Log.Information("Request Body: {@Body}", requestBody); await next.Invoke(); }); // Restante da configuração do aplicativo aqui } }
Neste exemplo, estamos usando um middleware personalizado com app.Use
para capturar o payload e o cabeçalho da requisição. As informações capturadas são então registradas usando o Serilog.
Aqui está um exemplo prático de como você pode usar a propriedade {@Client}
com o Serilog para serializar um objeto:
public class Client { public int ClientId { get; set; } public string Name { get; set; } } public class Program { public static void Main() { Log.Logger = new LoggerConfiguration() .WriteTo.Console() .CreateLogger(); var client = new Client { ClientId = 1, Name = "John Doe" }; Log.Information("Processed {@Client}", client); Log.CloseAndFlush(); } }
Neste exemplo, temos uma classe Client
com propriedades ClientId
e Name
. Criamos uma instância dessa classe e a passamos para o método Log.Information
com a propriedade estruturada {@Client}
.
Quando este código é executado, ele produzirá uma saída semelhante a esta:
2023-10-06 14:32:21.123 +00:00 [INF] Processed {"ClientId": 1, "Name": "John Doe"}
Como você pode ver, a propriedade {@Client}
instrui o Serilog a serializar o objeto client
como um objeto estruturado em vez de convertê-lo em uma string. Isso permite que você capture mais informações em seus logs e as analise mais facilmente mais tarde.
Aqui está um exemplo de como você pode usar o Serilog para capturar o rastreamento de uma exceção:
try { // Código que pode lançar uma exceção aqui } catch (Exception ex) { Log.Error(ex, "Ocorreu uma exceção."); }
Neste exemplo, qualquer exceção lançada dentro do bloco try
será capturada e passada para o método Log.Error
. O Serilog automaticamente incluirá o rastreamento da exceção no log.
A saída do log será semelhante a isto:
2023-10-06 14:32:21.123 +00:00 [ERR] Ocorreu uma exceção. System.NullReferenceException: Object reference not set to an instance of an object. at Program.Main() in C:\path\to\your\program.cs:line 14
Como você pode ver, a saída inclui a mensagem de erro, o tipo de exceção, a mensagem da exceção e o rastreamento da pilha, que mostra onde a exceção ocorreu no código.
Global.asax
Para configurar o Serilog em Global.asax
, capturar o cabeçalho e o payload da requisição, e registrar as mensagens em um arquivo chamado MeusLogs.txt
, você pode fazer o seguinte:
Configure o Serilog no método Application_Start
do seu aplicativo:
public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { Log.Logger = new LoggerConfiguration() .WriteTo.File("MeusLogs.txt") .CreateLogger(); Log.Information("Aplicação iniciada."); } }
Aqui, estamos configurando o Serilog para registrar mensagens em um arquivo chamado MeusLogs.txt
.
Para capturar o cabeçalho e o payload da requisição, você pode adicionar um middleware personalizado ao pipeline do seu aplicativo. Aqui está um exemplo de como você pode fazer isso:
public class MvcApplication : System.Web.HttpApplication { protected void Application_BeginRequest() { var request = HttpContext.Current.Request; var headers = request.Headers; var inputStream = request.InputStream; inputStream.Position = 0; var payload = new StreamReader(inputStream).ReadToEnd(); Log.Information("Headers: {@Headers}", headers); Log.Information("Payload: {@Payload}", payload); inputStream.Position = 0; // Redefina a posição do InputStream para o início para processamento adicional nas etapas subsequentes do pipeline. } }
Neste exemplo, estamos capturando o cabeçalho e o payload da requisição no evento BeginRequest
e registrando-os usando o Serilog.
Finalmente, certifique-se de chamar Log.CloseAndFlush()
no método Application_End
para garantir que todos os eventos pendentes sejam liberados antes que o aplicativo seja encerrado.
protected void Application_End() { Log.Information("Aplicação encerrada."); Log.CloseAndFlush(); }
Métodos
Serilog fornece uma série de métodos para registrar mensagens de log em diferentes níveis. Aqui estão alguns dos mais comuns:
-
Log.Verbose()
: Este método é usado para registrar mensagens que são detalhadas e geralmente apenas úteis durante o desenvolvimento e depuração². Por exemplo,Log.Verbose("This is a verbose message.");
registrará a mensagem "This is a verbose message." no nível Verbose². -
Log.Debug()
: Este método é usado para registrar mensagens que são úteis para depuração². Por exemplo,Log.Debug("This is a debug message.");
registrará a mensagem "This is a debug message." no nível Debug². -
Log.Information()
: Este método é usado para registrar mensagens informativas que descrevem o fluxo normal de operação de um aplicativo². Por exemplo,Log.Information("This is an information message.");
registrará a mensagem "This is an information message." no nível Information². -
Log.Warning()
: Este método é usado para registrar mensagens que indicam uma situação potencialmente prejudicial². Por exemplo,Log.Warning("This is a warning message.");
registrará a mensagem "This is a warning message." no nível Warning². -
Log.Error()
: Este método é usado para registrar mensagens que indicam um erro que impede o aplicativo de funcionar corretamente². Por exemplo,Log.Error("This is an error message.");
registrará a mensagem "This is an error message." no nível Error². -
Log.Fatal()
: Este método é usado para registrar mensagens que indicam um erro crítico que resulta na parada do aplicativo². Por exemplo,Log.Fatal("This is a fatal error message.");
registrará a mensagem "This is a fatal error message." no nível Fatal².
Espero que isso ajude! Se você tiver mais perguntas, sinta-se à vontade para perguntar.
Referência
- Serilog Tutorial - Structured Blog. https://blog.datalust.co/serilog-tutorial/.
- Serilog Tutorial for .NET Logging: 16 Best Practices and Tips - Stackify. https://stackify.com/serilog-tutorial-net-logging/.
- Serilog C# (CSharp) Code Examples - HotExamples. https://csharp.hotexamples.com/examples/-/Serilog/-/php-serilog-class-examples.html.
- How To Start Logging With Serilog | Better Stack Community. https://betterstack.com/community/guides/logging/how-to-start-logging-with-serilog/.
Espero que este artigo tenha lhe dado uma boa introdução ao uso do Serilog em um projeto .NET Framework com C#. O Serilog é uma ferramenta poderosa e flexível que pode tornar seu registro muito mais útil e gerenciável.
Links Relacionados
- Arquitetura CQRS
- Arrays em C#(CSharp)
- C#(CSharp) Converter inteiro para Hexadecimal e Hexadecimal para Inteiro
- C#(CSharp) Exemplo de Conversão de um List<> de uma classe qualquer para um DataTable.
- C#(CSharp) Função para verificar se um determinado número é Primo
- Calcular Idade C# (CSharp), diferença anos entre duas datas
- Classe com Métodos de extensão C# (CSharp)
- Classe para Ler e Gravar Cookies - Asp.Net MVC 4 com C# (CSharp)
- Classe para tratar valores nulos vindos de nossa Query SQL, C#(CSharp).
- Classes anônimas em C#(CSharp)
- Comando nameof() C#(CSharp)
- Comando NULLIF no SQLServer.
- Compare duas strings ignorando maiúsculas e minúsculas C#(CSharp).
- Configurar tempo de uma sessão em Asp.Net MVC
- Consulta SQLServer com paginação
- Criar Classes Dinâmicas usando DynamicObject e ExpandoObject em C# (CSharp)
- Definir o dia em um DateTime.
- DELETE CASCADE no SqlServer
- Desvendando o Poder da Função STRING_AGG no SQL Server para concatenação de dados
- Diferença entre parâmetros REF e OUT em C#(CSharp)
- DROP TABLE IF EXISTS no SQL Server.
- Emitir sons pelo auto-falante do computador em C# (CSharp)
- Estrangulando um monólito C#(CSharp)
- Exemplo de acesso a dados com SQL Server em C#.
- Exemplo de consulta em SqlServer para encontrar uma chave Estrangeira
- Explorando Tipos de Dados Personalizados no SqlServer: Utilidade e Impacto na Performance
- Extensões para DataReader, tratando valores de suas consultas SQL (DataReaderExtensions) C#(CSharp)
- Formatar CEP em C# (CSharp)
- Função para devolver data do próximo dia da semana informado C#(CSharp).
- Gerando números randômicos para sorteio de jogos de azar C#(CSharp)
- Grafana Loki e .NET Framework com C#
- Incrementando e decrementando variáveis em C#(CSharp)
- Injeção de dependência
- Ler string de conexão (connectionStrings) do arquivo Web.config Asp.Net MVC co C#(CSharp)
- Métodos de extensão C#
- O que é Camel Case e Pascal Case ?
- Ordenando um array com o comando OrderBy C#(CSharp)
- Padrão MVC
- Parar um loop foreach usando o comando break C#(CSharp).
- Recuperar a URL da página anterior em Asp.Net C# (CSharp)
- Recuperar a URL da página atual em Asp.Net C# (CSharp)
- Recuperar para código C# (CSharp) o valor de um componente de nossa página
- Retorna o IP da conexão do Cliente em Asp.Net MVC com C# (CSharp)
- Retorna os dados do Navegador do Cliente em Asp.Net MVC com C# (CSharp)
- Salvando CSV com cabeçalho no SQL Server Management Studio
- Separar String de caracteres C#(CSharp)
- Tipos de dados em C# (CSharp)
- Tipos de dados primitivos em C#(CSharp)
- Validando Valores nulos vindos de nosso Banco de Dados C#(CSharp)
- Validar Modelos com Data Annotation e Windows Form Application C#(CSharp)
- Verificar se uma string é um digito em C# (CSharp)