Freqüentemente, no projeto, há um erro incompreensível para o qual é necessário o
registro máximo de todas as consultas no banco de dados. O artigo ajudará aqueles que escrevem (implantam no servidor) um de seus primeiros projetos no
Boilerplate Asp.Net .
Este artigo foi escrito para aqueles que são novos na tecnologia Asp.Net Boilerplate que encontraram algum erro estranho relacionado ao banco de dados. Ao usar o PostgreSQL, este pode ser, por exemplo, o primeiro projeto. A motivação para escrever o artigo foi que a solução para essa questão não é tão fácil de encontrar na Internet, mesmo em inglês, sem mencionar o fato de que as soluções encontradas não respondem totalmente a todas as perguntas sobre esse problema.
Versão do produto: Asp.Net Boilerplate 4.3, .NET Core 2.1
Se você concluir estas etapas : No seu arquivo de log principal, você verá todas as solicitações efetuadas no banco de dados.
Etapa 1
Você deve criar um criador de logs. Já existe um registrador interno configurado na plataforma Boilerplate. Pode ser o Log4Net como padrão. Não há necessidade de fazer nenhuma manipulação com ele. Em vez disso, basta criar uma classe de logger que você registra como processador de todas as mensagens de log do banco de dados.
Etapa 1.1
Projeto * .EntityFrameworkCore. Aqui precisamos criar 2 classes. Por um lado, um criador de logs que fará apenas uma coisa é enviar todas as mensagens do banco de dados para o log do sistema. Vamos chamá-lo de
MyLogger. E o provedor desse criador de logs que criará o MyLogger. O provedor é chamado
MyLoggerProvider.Criamos um arquivo com o seguinte código (um arquivo para simplificação, embora, é claro, cada arquivo deva ter uma classe):
public class MyLoggerProvider : ILoggerProvider { private Castle.Core.Logging.ILogger _logger; public MyLoggerProvider(Castle.Core.Logging.ILogger logger) { _logger = logger; } public ILogger CreateLogger(string categoryName) { return new MyLogger(_logger); } public void Dispose() { } } public class MyLogger : ILogger { private Castle.Core.Logging.ILogger _logger; public MyLogger(Castle.Core.Logging.ILogger logger) { _logger = logger; } public IDisposable BeginScope<TState>(TState state) { return null; } public bool IsEnabled(LogLevel logLevel) { return true; } public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter) { if (IsEnabled(logLevel)) { var msg = formatter(state, exception); _logger.Info("DB-REQUEST: " + msg); } } }
Se você observar com atenção, poderá ver como outro logger é encaminhado para o MyLoggerProvider e, em seguida, para o MyLogger. Acontece já o terceiro! A conclusão é que este terceiro é a classe do nível de infraestrutura de registro, que deve ser obtido das entranhas do Boilerplate com a ajuda da qual as mensagens serão salvas no registro. Veja abaixo.
Etapa 2
Na estrutura do mesmo projeto * .EntityFrameworkCore, vá para o arquivo * DbContextConfigurer.cs e faça as seguintes alterações nos dois métodos Configure ():
2.1) Adicione um parâmetro loggerfactory do tipo LoggerFactory
2.2) Adicione duas linhas ao corpo do método:
builder.UseLoggerFactory(loggerFactory); builder.EnableSensitiveDataLogging(true);
O significado de
UseLoggerFactory é permitir o uso de loggerFactory, que é passado nos parâmetros para registrar o banco de dados. É muito importante lembrar que aqui habilitamos o log do banco de dados.
O significado de
EnableSensitiveDataLogging é habilitar o log não apenas de consultas ao banco de dados, mas também registrar todos os dados nessas consultas. Sem essa configuração, você não poderá ver os dados nas consultas - eles serão substituídos por pontos de interrogação.
Etapa 3
Dentro da estrutura do mesmo projeto * .EntityFrameworkCore, vamos para o arquivo * DbContextFactory.cs.
3.1) Adicione um novo método:
private LoggerFactory GetDbLoggerFactory() { return new LoggerFactory(new[] { new MyLoggerProvider(NullLogger.Instance) }); }
3.2) No método CreateDbContext ():
Porque Como adicionamos anteriormente um novo parâmetro às implementações do Configure (), um erro deve ser exibido aqui. Está na hora de especificar esse novo parâmetro - registramos GetDbLoggerFactory () com uma vírgula. I.e. o valor do novo parâmetro loggerFactory deve ser retornado pelo novo método da cláusula 3.1.
Etapa 4
Dentro da estrutura do mesmo projeto * .EntityFrameworkCore, vamos para o arquivo * EntityFrameworkModule.cs.
4.1) Adicione um novo método:
private LoggerFactory GetDbLoggerFactory() { return new LoggerFactory(new[] { new MyLoggerProvider(Logger) }); }
4.2) No método PreInitialize ():
Porque Como adicionamos anteriormente um novo parâmetro às implementações do Configure (), um erro também deve ser exibido aqui. Nós especificamos um novo parâmetro semelhante à Seção 3.2 - registramos GetDbLoggerFactory () com uma vírgula. I.e. o valor do novo parâmetro loggerFactory deve ser retornado pelo novo método da cláusula 4.1.
Resultado
No arquivo de log principal (por padrão Logs.txt), você verá todas as consultas precedidas pela sequência de caracteres DB-REQUEST (é a partir disso que você pode procurar dados no log).
Compreensão geral da solução
Então, agora vou explicar o que fizemos. Uma explicação é dada no final do artigo, porque muitas vezes, os leitores estão interessados em começar a fazer algo específico já.
Na classe * DbContextFactory, bem como * EntityFrameworkModule, criamos nosso LoggerFactory, nos parâmetros dos quais indicamos o MyLoggerProvider criado. Mas, como uma classe de infraestrutura que efetuará logon diretamente no primeiro caso (* DbContextFactory), passamos o stub NullLogger.Instance para que não haja entradas. No segundo caso (* EntityFrameworkModule), passamos o logger, que já está no módulo Abp. Este é o campo Logger. Ele já foi inicializado e pode ser registrado com ele. Assim, nosso MyLogger poderá gravar no arquivo Logs.txt usando essa classe.
Toda a lógica é que esta fábrica loggerFactory seja instalada como uma fábrica de log para trabalhar com o banco de dados. Assim que um registrador é necessário, ele é criado pela fábrica. E este é o MyLogger, que, por sua vez, registra tudo o que vem com o Logs.txt (ou a fonte na qual a saída dos seus logs principais está configurada).
Como você pode ver, nem tudo é tão simples e, às vezes, os níveis de abstração congelam, especialmente para iniciantes! Faça suas perguntas nos comentários.
Nota:- A solução foi criada para ligar o criador de logs, entender qual é o erro e desativá-lo. Não foi projetado para uso a longo prazo.