> ## Content Index
> Fetch the complete content index at: https://www.azurebrasil.cloud/llms.txt
> Use this file to discover other available public pages before exploring further.

# Criando logs com o Serilog - parte 1
- URL: https://www.azurebrasil.cloud/blog/criando-logs-com-serilog-e-seq/
- Published: 2024-02-02T17:07:43.000Z
- Updated: 2024-02-02T17:07:43.000Z
- Author: Talles Valiatti

O [Serilog](https://serilog.net/?ref=azurebrasil.cloud) é uma biblioteca de registro ([logging](https://learn.microsoft.com/pt-br/dotnet/core/extensions/logging?tabs=command-line&ref=azurebrasil.cloud)) para o .[NET](https://dotnet.microsoft.com/pt-br/download/dotnet/8.0?ref=azurebrasil.cloud) que oferece flexibilidade, desempenho e facilidade de uso. Ele é projetado para fornecer uma maneira estruturada de registrar informações em aplicativos .NET. A grande vantagem do Serilog é sua capacidade de lidar com dados estruturados de forma eficiente, o que permite uma análise mais profunda e fácil dos registros. Com sua sintaxe simples e poderosa, torna a configuração e o uso do registro em aplicativos .NET uma tarefa simples e eficaz.

Nesse post, vamos fazer uma introdução ao Serilog, e aos seus [sinks](https://www.nuget.org/packages?q=Tags%3A%22serilog%22&ref=azurebrasil.cloud)! Para isso, vamos precisar que você tenha o [.NET](https://dotnet.microsoft.com/pt-br/download/dotnet/8.0?ref=azurebrasil.cloud) instalado em sua máquina.

Inicialmente iremos criar um diretório raiz para nossa solução.

```
 mkdir LoggingSerilogSeq
```

Após isso, vamos criar um [*gitignore*](https://git-scm.com/docs/gitignore?ref=azurebrasil.cloud)*,* uma [*solution*](https://learn.microsoft.com/pt-br/visualstudio/ide/solutions-and-projects-in-visual-studio?view=vs-2022&ref=azurebrasil.cloud) e um projeto do tipo [web api](https://learn.microsoft.com/pt-br/aspnet/core/tutorials/first-web-api?view=aspnetcore-8.0&tabs=visual-studio&ref=azurebrasil.cloud). 

```
dotnet git ignore
dotnet new sln
dotnet new webapi -n App
dotnet sln add App/App.csproj
```

Precisamos instalar o pacote NuGet [*Serilog.AspNetCore*](https://www.nuget.org/packages/Serilog.AspNetCore?ref=azurebrasil.cloud)*.*

```
dotnet add package Serilog.AspNetCore
```

Criaremos um[*extension method*](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods?ref=azurebrasil.cloud) para configurar o Serilog em nosso projeto. Observe que estamos configurando apenas o *logger* para ser feito no console.

```
using Serilog;
using Serilog.Sinks.SystemConsole.Themes;

namespace App.Logging;

public static class LoggerExtensions
{
    public static WebApplicationBuilder AddCustomLogging(this WebApplicationBuilder builder)
    {
        // Create the logger configuration
        var loggerConfig = new LoggerConfiguration();
        
        // Add console provider
        loggerConfig.WriteTo.Console(theme: SystemConsoleTheme.Colored);

        // Create logger
        var logger = loggerConfig.CreateLogger();
        
        // Clear providers
        builder.Logging.ClearProviders();
        
        // Add Serilog
        builder.Logging.AddSerilog(logger);
        
        return builder;
    }
}
```

Com essa classe estática pronta, vamos refatorar o *Program.cs.*

```
using App.Logging;
using Microsoft.AspNetCore.Http.HttpResults;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// Logging
builder.AddCustomLogging();

var app = builder.Build();

app.UseSwagger();
app.UseSwaggerUI();

app.UseHttpsRedirection();

app.MapGet("/logging", (ILogger<Program> logger) =>
  {
    logger.LogTrace("This is a trace log");
    logger.LogDebug("This is a debug log");
    logger.LogInformation("This is an information log");
    logger.LogWarning("This is a warning log");
    logger.LogError("This is an error log");
    logger.LogCritical("This is a critical log");
    
    return Results.Ok();
  })
.WithName("LoggingEndpoint")
.WithOpenApi();

app.Run();
```

No endpoint */logging,* estamos fazendo vários *logs* com[ diferentes níveis de gravidade](https://learn.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line&ref=azurebrasil.cloud)! 

Vamos executar o *endpoint* e ver o resultado em nosso console:

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-14.24.30.png)

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-14.25.24.png)

Observe que foram gerados vários *logs* por nossa web api*,* eentre eles, os que foram configurados anteriormente.

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-14.27.24.png)

Porém, apenas logs com níveis de gravidades maiores do que *Information* foram gerados. Isso se deve ao *minimum leve*l que pode ser configurado!

Vamos alterar esse valor para *verbose* e repetir o processo*:*

```
  // MinimumLevel
  loggerConfig.MinimumLevel.Verbose();
```

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-14.31.08.png)

Todos os logs foram gerados com sucesso! 

Vamos agora remover todos os logs que não foram escritos por nós, como os mostrados abaixo:

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-14.42.33.png)

Para isso, precisamos definir que para *logs* gerados pelos pacotes iniciados por "*Microsoft*", o level mínimo é *Error.*

```
 // Microsoft minimum log level
loggerConfig.MinimumLevel.Override("Microsoft", LogEventLevel.Error);
```

Podemos repetir o teste e verificar o resultado:

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-14.42.02.png)

Para o *log* de [*exceptions*](https://learn.microsoft.com/pt-br/dotnet/csharp/fundamentals/exceptions/exception-handling?ref=azurebrasil.cloud), podemos implementar o seguinte código:

```
 try
  {
    throw new Exception("*** Error ***");
  }
  catch (Exception e)
  {
    logger.LogCritical(e, "This is an exception!");
  } 
```

É necessário adicionar pacote NuGet [*Serilog.Exceptions*](https://www.nuget.org/packages/Serilog.Exceptions?ref=azurebrasil.cloud)e fazer uma configuração extra ao nosso projeto.

```
dotnet add package Serilog.Exceptions
```

```
  // Set application name
  loggerConfig.Enrich.WithExceptionDetails();
```

Com isso, temos o resultado:

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-16.02.15.png)

Os "[*sinks*](https://github.com/serilog/serilog/wiki/Provided-Sinks?ref=azurebrasil.cloud)" no contexto do Serilog referem-se aos destinos para onde os logs são direcionados após serem gerados pelo aplicativo. Eles são componentes cruciais para o fluxo de registro, permitindo que os registros sejam armazenados, exibidos ou processados de várias maneiras.

Para exemplificar, podemos enviar nossos logs para a ferramenta [Seq](https://datalust.co/seq?ref=azurebrasil.cloud). Para isso, vamos adicionar o seguinte pacote:

```
dotnet add package Serilog.Sinks.Seq
```

Para rodar o Seq localmente, vamos criar um [*docker compose*](https://docs.docker.com/compose/?ref=azurebrasil.cloud) com o seguinte conteúdo

```
version: '3'
services:
  seq:
    image: datalust/seq:latest
    ports:
      - '8090:80'
      - '5341:5341'
    environment:
      - ACCEPT_EULA=Y
```

Podemos executá-lo.

```
docker compose up -d
```

Já na nossa *web api,* precisamos fazer uma nova configuração para que os logs sejam enviados a essa ferramenta corretamente.

```
loggerConfig.WriteTo.Seq("http://localhost:5341");
```

Com a web api rodando, podemos acessar a UI do Seq e verificar que os logs foram gerados corretamente!

```
http://localhost:8090
```

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-16.32.49.png)

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-16.36.26.png)

Podemos ainda adicionar propriedades adicionais na configuração do Serilog. Por exemplo, o nome da nossa aplicação:

```
 loggerConfig.Enrich.WithProperty("Application", "my-web-api");
```

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-16.34.32.png)

Outro exemplo de sink muito utilizado, é [*Serilog.Sinks.File*](https://github.com/serilog/serilog-sinks-file?ref=azurebrasil.cloud)*.* Para utilizá-lo, iremos precisar instalar o seguinte pacote NuGet e adicionar outra configuração ao projeto:

```
dotnet add package Serilog.Sinks.File
```

```
// Add File
loggerConfig.WriteTo.File("log.txt", rollingInterval: RollingInterval.Day);
```

Após a execução do *endpoint*, podemos ver que o log foi gerado em arquivos .txt! 

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2024/01/Screen-Shot-2024-01-29-at-16.56.46.png)

Essa é só a primeiro parte de uma série de posts relacionados ao Serilog e seus sinks!

Não esquece de me seguir no [LinkedIn](https://www.linkedin.com/in/tallesvaliatti/?ref=azurebrasil.cloud)!

Até a próxima, abraços!