C#

31 ago, 2021

Como gerar um arquivo log na sua aplicação Web API

100 visualizações
Publicidade

Olá pessoal, hoje eu vou falar e mostrar sobre como gerar um arquivo log na sua aplicação API (Web API) em um determinado local e ao mesmo tempo capturar todos os logs do ILogger e colocar dentro do arquivo. Quero dizer que, todo o log da aplicação usando o ILogger vai colocar o dado dentro do arquivo .txt por exemplo. Lembro que todo o SELECT feito pelo EntityFramework também será logado dentro do arquivo .txt.

Veja o que eu vou utilizar:

1. Ferramenta Visual Studio

2. Linguagem C#

3. Tecnologia Web API

4. Framework .NETCore 5

5. Framework Serilog

Tudo que estou utilizando aqui é grátis e pode ser usado gratuitamente, isto é, sem mensalidade e sem pagar nada.

Log no Web API

Eu já começo pensando que você já conhece o Visual Studio, já saiba o que é C# e tenha já trabalhado com Web API. Depois disso, o primeiro passo é fazer download pelo NuGet Package do framework Serilog e suas extensões, veja quais são:

1. Serilog (2.10.0)

2. Serilog.Extensions.Logging (3.0.1)

3. Serilog.Sinks.File (4.1.0)

4. Serilog.Sinkgs.RollingFile (3.3.0)

Todos os pacotes do Serilog que estou usando está na lista acima seguido da versão utilizada dentro da minha aplicação.

Antes de começar com o código na aplicação, a imagem 1 mostra como está separada a minha aplicação. Eu irei usar basicamente poucos arquivos nesse artigo para te mostrar como colocar o ILogger funcionando e registrando tudo, é só para você saber.

Imagem 1 – Estrutura do projeto WebAPI

Agora, eu vou abordar o código depois de instalar o framework Serilog na aplicação.

Eu vou editar o arquivo Program.cs, mais especificamente o método CreateHostBuilder, veja o código 1.1.

Program.cs

Código 1.1 – Editando o arquivo Program.cs

 

//imports

using Microsoft.AspNetCore.Hosting;

using Microsoft.Extensions.Configuration;

using Microsoft.Extensions.Hosting;

using Microsoft.Extensions.Logging;

using Microsoft.Extensions.Logging.EventLog;

using Serilog;

public static IHostBuilder CreateHostBuilder(string[] args) =>

Host.CreateDefaultBuilder(args)

.ConfigureAppConfiguration((hostingContext, config) =>

{

var env = hostingContext.HostingEnvironment;

config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

config.AddEnvironmentVariables();

})

.ConfigureLogging((hostingContext, logging) => //using logger as file

{

if (hostingContext.Configuration.GetSection("LoggerFileEnabled").Value.Equals(Constants.LoggerFileEnabled))

{

logging.ClearProviders();

logging.AddSerilog();

}

})

.ConfigureWebHostDefaults(webBuilder =>

{

webBuilder.UseStartup<Startup>();

});

 

O primeiro passo é adicionar o arquivo de configuração appsettings.json fazendo o arquivo enxergar as configurações colocadas dentro do arquivo. Veja o código 1.2.

Código 1.2 – Adicionando o arquivo de configuração

 

.ConfigureAppConfiguration((hostingContext, config) =>

{

var env = hostingContext.HostingEnvironment;

config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

config.AddEnvironmentVariables();

})

 

Dessa maneira eu consigo ver e pegar todos os dados dentro do arquivo appsettings.json.

O próximo passo é usar o hostingContext para pegar a seção configurável dentro do arquivo de configuração. Veja o código 1.3.

Código 1.3 – Configurando o Log

 

.ConfigureLogging((hostingContext, logging) => //using logger as file

{

if (hostingContext.Configuration.GetSection("LoggerFileEnabled").Value.Equals(Constants.LoggerFileEnabled))

{

logging.ClearProviders();

logging.AddSerilog();

}

})

 

O código 1.3 eu verifico basicamente se a section LoggerFileEnabled tem o valor igual à minha constante, por exemplo: 1. Essa section está dentro do arquivo de configuração que vamos ver logo mais. Depois disso basta fazer um clean e adicionar o Serilog ao log com o comando logging.AddSerilog().

Agora vou mostrar o arquivo de configuração, veja o código 1.4.

AppSettings.json

Código 1.4 – Arquivo de configuração

"LoggerFileEnabled": 1,

"LogFileLocalAddress": "C:/Apps/API/Log/",

"Logging": {

"LogLevel": {

"Default": "Information",

"Microsoft": "Warning",

"Microsoft.Hosting.Lifetime": "Information"

}

}

 

O código 1.4 mostra o arquivo de configuração onde eu verifico no código o seguinte: LoggerFileEnabled e LogFileLocalAddress. O primeiro serve para saber se o log está habilitado ou não com o valor 0 e 1. A segunda variável serve para salvar o arquivo no local onde eu desejo, pode ser dentro do servidor ou localmente como eu fiz aqui.

O restante do Logging é normal que já vem no arquivo de configuração quando você cria o projeto.

Agora eu vou trabalhar com o arquivo Startup.cs e configurar algumas coisas dentro.

 

Startup.cs

O primeiro ponto é fazer o import necessário. Veja o código 1.5.

Código 1.5 – Import necessário

using Microsoft.AspNetCore.Builder;

using Microsoft.AspNetCore.Hosting;

using Microsoft.EntityFrameworkCore;

using Microsoft.Extensions.Configuration;

using Microsoft.Extensions.DependencyInjection;

using Microsoft.Extensions.Hosting;

using Microsoft.OpenApi.Models;

using Serilog;

public void ConfigureServices(IServiceCollection services)

{

//configurate database connection string

services.AddDbContext<SqlContext>(options =>

{

options

.UseSqlServer(new CriptConnectionString.Cripto()

.Decrypt(Configuration.GetConnectionString(Constants.SqlConnection),

Configuration.GetSection(Constants.PublicKey).Value,

Constants.PrivateKey))

.EnableSensitiveDataLogging();

});

//configuration file logger


if (Configuration.GetSection("LoggerFileEnabled").Value.Equals(Constants.LoggerFileEnabled))

{

Log.Logger = new LoggerConfiguration()

.Enrich.FromLogContext()

.MinimumLevel.Debug()

.WriteTo.File(@$"{Configuration.GetSection("LogFileLocalAddress").Value}log-web.txt", rollingInterval: RollingInterval.Day)

.CreateLogger();

}

}

 

O código 1.5 mostra primeiro os usings necessários na classe. Depois, eu adicionei o primeiro bloco de código chamado AddDbContext onde utilizo a string de conexão com o banco de dados de forma criptografada, ou seja, usando chave pública e privada; que não é o nosso assunto aqui agora; mas o que eu quero destacar é o método .EnableSensitiveDataLogging() que faz com que todo select feito na base de dados seja logado no arquivo.

O próximo bloco de código é responsável por gerar o arquivo de log, mas antes ele verifica se está habilitado ou não dentro do arquivo de configuração.

Note que eu gero uma configuração criando uma nova instância new LoggerConfiguration() e utilizo o .WriteToFile para salvar o arquivo no endereço colocado também dentro do arquivo de configuração, por isso usei o Configuration.GetSection(“LogFileLocalAddress).Value.

O nome do arquivo será log-web.txt gerado no intervalo diário, ou seja, a cada novo dia é gerado um novo arquivo sem sobrepor porque o arquivo fica com a data na frente, veja: log-web20210816.txt

Pronto, esses foram os passos para deixar funcionando o log dentro da aplicação. O próximo passo é criar uma injeção de dependência dentro da controller para usar o log. Eu tenho uma controller onde faço o log pra você ver. Veja o código 1.6.

 

Código 1.6 – Controller

public class M3ConsumerSyncController : ControllerBase

{

private readonly ILogger<M3ConsumerSyncController> _logger;

public M3ConsumerSyncController(ILogger<M3ConsumerSyncController> logger)

{

this._logger = logger;

}

}

O código 1.6 mostra a criação de uma variável _logger com a interface ILogger<M3ConsumerSyncController>. Depois disso, preciso colocar uma injeção de dependência no construtor do método e dentro dele informar a variável e a instância. Por isso, é necessário o this._logger = logger;

No método Post eu criei dois logs, um dentro do try e outro no catch para quando der erro. Veja o código 1.7.

 

Código 1.7 – Método post e log

public class M3ConsumerSyncController : ControllerBase

{

private readonly ILogger<M3ConsumerSyncController> _logger;

public M3ConsumerSyncController(ILogger<M3ConsumerSyncController> logger)

{

this._logger = logger;

}

}

 

O código 1.7 é bem simples, mas a parte mais importante aqui é fazer o log adicionar os valores dentro do arquivo txt. Na verdade, todo _logger injetado na classe vai escrever de forma automática dentro do arquivo txt.

Dessa maneira eu consigo fazer um tracker de cada passo dentro da aplicação. Eu posso usar isso para pegar o usuário passo a passo e depois verificar de forma automática.

Espero que tenha gostado, eu fico por aqui e você pode entrar em contato comigo pela rede social Instagram  ou pelo meu site pessoal.