Consignation de toutes les requêtes de base de données dans Asp.Net Boilerplate 4.3 .Net Core 2.1

Souvent, dans le projet, il y a une erreur incompréhensible pour laquelle la journalisation maximale de toutes les requêtes dans la base de données est nécessaire . L'article aidera ceux qui écrivent (déploient sur le serveur) l'un de leurs premiers projets sur la plaque de chaudière Asp.Net .

Cet article est écrit pour les nouveaux utilisateurs de la technologie Asp.Net Boilerplate qui ont rencontré une erreur étrange liée à la base de données. Lors de l'utilisation de PostgreSQL, il peut s'agir, par exemple, du premier projet. La motivation de la rédaction de l'article était que la solution à ce problème n'est pas si facile à trouver sur Internet, même en anglais, sans parler du fait que les solutions trouvées ne répondent pas pleinement à toutes les questions sur ce problème.

Version du produit: Asp.Net Boilerplate 4.3, .NET Core 2.1

Si vous procédez comme suit : Dans votre fichier journal principal, vous verrez toutes les demandes à la base de données connectées.

Étape 1


Vous devez créer un enregistreur. Il existe déjà un enregistreur interne configuré sur la plate-forme Boilerplate. Il peut s'agir de Log4Net en standard. Il n'est pas nécessaire de faire de manipulations avec lui. Au lieu de cela, il suffit de créer une classe de journalisation que vous enregistrez en tant que gestionnaire de tous les messages de journal de la base de données.

Étape 1.1


Projet * .EntityFrameworkCore. Ici, nous devons créer 2 classes. D'une part, un enregistreur qui ne fera qu'une seule chose est de sortir tous les messages de la base de données vers le journal système. Appelons cela MyLogger. Et le fournisseur de cet enregistreur qui va créer MyLogger. Le fournisseur s'appelle MyLoggerProvider.

Nous créons un fichier avec le code suivant (un fichier pour simplifier, bien que, bien sûr, chaque fichier doive avoir une 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); } } } 

Si vous regardez attentivement, vous pouvez voir comment un autre enregistreur est transmis à MyLoggerProvider, puis à MyLogger. Il s'avère déjà le troisième! L'essentiel est que ce troisième est la classe du niveau de l'infrastructure de journalisation, qui doit être obtenue à partir des entrailles de la chaudière à l'aide de laquelle les messages seront enregistrés dans le journal. Voir ci-dessous.

Étape 2


Dans le cadre du même projet * .EntityFrameworkCore, accédez au fichier * DbContextConfigurer.cs et apportez les modifications suivantes dans les deux méthodes Configure ():

2.1) Ajouter un paramètre loggerfactory de type LoggerFactory

2.2) Ajoutez deux lignes au corps de la méthode:

 builder.UseLoggerFactory(loggerFactory); builder.EnableSensitiveDataLogging(true); 

La signification de UseLoggerFactory est de permettre l'utilisation de loggerFactory, qui est passé dans les paramètres de journalisation de la base de données. Il est très important de se rappeler que nous activons ici la journalisation de la base de données.

La signification de EnableSensitiveDataLogging est d'activer la journalisation non seulement des requêtes de base de données, mais également d'enregistrer toutes les données de ces requêtes. Sans ce paramètre, vous ne pourrez pas voir les données dans les requêtes - elles seront remplacées par des points d'interrogation.

Étape 3


Dans le cadre du même projet * .EntityFrameworkCore, nous allons dans le fichier * DbContextFactory.cs.

3.1) Ajoutez une nouvelle méthode:

 private LoggerFactory GetDbLoggerFactory() { return new LoggerFactory(new[] { new MyLoggerProvider(NullLogger.Instance) }); } 

3.2) Dans la méthode CreateDbContext ():
Parce que Puisque nous avons précédemment ajouté un nouveau paramètre aux deux implémentations de Configure (), une erreur devrait s'afficher ici. Il est temps de spécifier ce nouveau paramètre - nous enregistrons GetDbLoggerFactory () avec une virgule. C'est-à-dire la valeur du nouveau paramètre loggerFactory doit être renvoyée par la nouvelle méthode de l'article 3.1.

Étape 4


Dans le cadre du même projet * .EntityFrameworkCore, nous allons dans le fichier * EntityFrameworkModule.cs.

4.1) Ajoutez une nouvelle méthode:

 private LoggerFactory GetDbLoggerFactory() { return new LoggerFactory(new[] { new MyLoggerProvider(Logger) }); } 

4.2) Dans la méthode PreInitialize ():

Parce que Puisque nous avons précédemment ajouté un nouveau paramètre aux deux implémentations de Configure (), une erreur devrait également s'afficher ici. Nous spécifions un nouveau paramètre de manière similaire à la section 3.2 - nous enregistrons GetDbLoggerFactory () avec une virgule. C'est-à-dire la valeur du nouveau paramètre loggerFactory doit être renvoyée par la nouvelle méthode de l'article 4.1.

Résultat


Dans le fichier journal principal (par défaut Logs.txt), vous verrez toutes les requêtes précédées de la séquence de caractères DB-REQUEST (c'est là que vous pouvez rechercher des données de journal).

Compréhension générale de la solution


Alors maintenant, je vais expliquer ce que nous avons fait. Une explication est donnée à la fin de l'article, car souvent, les lecteurs sont intéressés à commencer à faire quelque chose de spécifique déjà.

Dans la classe * DbContextFactory, ainsi que * EntityFrameworkModule, nous créons notre LoggerFactory, dans les paramètres dont nous indiquons le MyLoggerProvider créé. Mais en tant que classe d'infrastructure qui se connectera directement dans le premier cas (* DbContextFactory), nous transmettons le stub NullLogger.Instance pour qu'il n'y ait aucune entrée. Dans le second cas (* EntityFrameworkModule) nous passons le logger, qui est déjà dans le module Abp. Il s'agit du champ Logger. Il est déjà initialisé et peut être enregistré avec lui. Par conséquent, notre MyLogger pourra écrire dans le fichier Logs.txt en utilisant cette classe.

Toute la logique est que cette fabrique loggerFactory est installée comme fabrique de journaux pour travailler avec la base de données. Dès qu'un enregistreur est nécessaire, il est créé par l'usine. Et c'est notre MyLogger, qui, à son tour, enregistre tout ce qui vient à Logs.txt (ou la source sur laquelle la sortie de vos journaux principaux est configurée).

Comme vous pouvez le constater, tout n'est pas si simple et les niveaux d'abstractions se figent parfois, surtout pour les débutants! Posez vos questions dans les commentaires.

Remarque:

- La solution a été créée afin d'allumer l'enregistreur, de comprendre quelle est l'erreur et de l'éteindre. Il n'est pas conçu pour une utilisation à long terme.

Source: https://habr.com/ru/post/fr444660/


All Articles