From 9938a99e07978aa7e17b3ba8d66615d82b08c3cd Mon Sep 17 00:00:00 2001 From: "b.nodon" Date: Wed, 1 Apr 2026 16:24:58 +0200 Subject: [PATCH 1/3] =?UTF-8?q?#180=20Middleware=20pour=20mesurer=20le=20t?= =?UTF-8?q?emps=20de=20r=C3=A9ponse=20des=20requ=C3=AAtes=20HTTP.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LogTempsExecutionMiddleware.cs | 39 +++++++++++++++++++ Webzine.WebApplication/Program.cs | 2 + 2 files changed, 41 insertions(+) create mode 100644 Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs diff --git a/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs b/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs new file mode 100644 index 0000000..f871044 --- /dev/null +++ b/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs @@ -0,0 +1,39 @@ +namespace Webzine.WebApplication.Middlewares +{ + using System.Diagnostics; + + public class LogTempsExecutionMiddleware + { + /// + /// log à chaque requete http. + /// + // _next représente le maillon suivant dans la chaîne (le prochain middleware ou le contrôleur) + private readonly RequestDelegate next; + private readonly ILogger logger; + + // Le constructeur récupère "_next" et le Logger + public LogTempsExecutionMiddleware(RequestDelegate next, ILogger logger) + { + this.next = next; + this.logger = logger; + } + + // méthode appelée à chaque requête HTTP + public async Task InvokeAsync(HttpContext context) + { + // (Avant le contrôleur) + var chronometre = Stopwatch.StartNew(); // lance le chrono + + // C'est ici que le reste de l'application s'exécute (autres middlewares et Contrôleur) + await this.next(context); + + // (Après le contrôleur) + chronometre.Stop(); // arrête le chrono + var tempsEcoule = chronometre.ElapsedMilliseconds; + + // écrit dans les logs l'URL de la page et le temps qu'elle a pris + var urlPage = context.Request.Path; + this.logger.LogInformation($"[MIDDLEWARE] La page {urlPage} a mis {tempsEcoule} ms à charger."); + } + } +} \ No newline at end of file diff --git a/Webzine.WebApplication/Program.cs b/Webzine.WebApplication/Program.cs index 916d86e..cf6fa9e 100644 --- a/Webzine.WebApplication/Program.cs +++ b/Webzine.WebApplication/Program.cs @@ -73,6 +73,8 @@ try var app = builder.Build(); + app.UseMiddleware(); + if (repositoryType == RepositoryType.Db) { using (var scope = app.Services.CreateScope()) From a4bc260e338b9f2bc5123f3213566ce796d0a603 Mon Sep 17 00:00:00 2001 From: "b.nodon" Date: Thu, 2 Apr 2026 14:23:14 +0200 Subject: [PATCH 2/3] =?UTF-8?q?#188=20syst=C3=A8me=20de=20logs=20IN=20et?= =?UTF-8?q?=20OUT=20d'une=20requ=C3=AAte=20HTTP.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LogTempsExecutionMiddleware.cs | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs b/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs index f871044..7a6e64a 100644 --- a/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs +++ b/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs @@ -19,21 +19,45 @@ } // méthode appelée à chaque requête HTTP + + /// + /// Middleware qui log pour suivre la vie d'une requete. + /// + /// + /// A representing the asynchronous operation. public async Task InvokeAsync(HttpContext context) { // (Avant le contrôleur) var chronometre = Stopwatch.StartNew(); // lance le chrono - // C'est ici que le reste de l'application s'exécute (autres middlewares et Contrôleur) + // --- IN --- + var methode = context.Request.Method; + var endpoint = context.Request.Path; + var traceId = context.TraceIdentifier; // Identifiant unique généré par .NET + + this.logger.LogInformation($"[IN] TraceId: {traceId} | Méthode: {methode} | Endpoint: {endpoint}"); + await this.next(context); // (Après le contrôleur) chronometre.Stop(); // arrête le chrono var tempsEcoule = chronometre.ElapsedMilliseconds; - // écrit dans les logs l'URL de la page et le temps qu'elle a pris - var urlPage = context.Request.Path; - this.logger.LogInformation($"[MIDDLEWARE] La page {urlPage} a mis {tempsEcoule} ms à charger."); + var httpCode = context.Response.StatusCode; // exemple: 200, 404, 500 + + // --- OUT --- + if (httpCode >= 500) + { + this.logger.LogError($"[OUT] TraceId: {traceId} | HTTP {httpCode} | Temps: {tempsEcoule} ms | Endpoint: {endpoint}"); + } + else if (httpCode >= 400) + { + this.logger.LogWarning($"[OUT] TraceId: {traceId} | HTTP {httpCode} | Temps: {tempsEcoule} ms | Endpoint: {endpoint}"); + } + else + { + this.logger.LogInformation($"[OUT] TraceId: {traceId} | HTTP {httpCode} | Temps: {tempsEcoule} ms | Endpoint: {endpoint}"); + } } } } \ No newline at end of file From 0d5ddc7009c51412657305cbebc8c15343f14da4 Mon Sep 17 00:00:00 2001 From: "b.nodon" Date: Thu, 2 Apr 2026 14:28:48 +0200 Subject: [PATCH 3/3] #188 fix : - log - commentaire. --- .../Middlewares/LogTempsExecutionMiddleware.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs b/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs index 7a6e64a..1b86308 100644 --- a/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs +++ b/Webzine.WebApplication/Middlewares/LogTempsExecutionMiddleware.cs @@ -21,10 +21,10 @@ // méthode appelée à chaque requête HTTP /// - /// Middleware qui log pour suivre la vie d'une requete. + /// Middleware chargé de journaliser le cycle de vie d'une requête HTTP (entrée, exécution, sortie et temps de réponse). /// - /// - /// A representing the asynchronous operation. + /// Le contexte HTTP encapsulant toutes les informations de la requête et de la réponse. + /// Une tâche () représentant l'opération asynchrone. public async Task InvokeAsync(HttpContext context) { // (Avant le contrôleur) @@ -35,7 +35,7 @@ var endpoint = context.Request.Path; var traceId = context.TraceIdentifier; // Identifiant unique généré par .NET - this.logger.LogInformation($"[IN] TraceId: {traceId} | Méthode: {methode} | Endpoint: {endpoint}"); + this.logger.LogInformation("[IN] TraceId: {traceId} | Méthode: {methode} | Endpoint: {endpoint}", traceId, methode, endpoint); await this.next(context); @@ -48,15 +48,15 @@ // --- OUT --- if (httpCode >= 500) { - this.logger.LogError($"[OUT] TraceId: {traceId} | HTTP {httpCode} | Temps: {tempsEcoule} ms | Endpoint: {endpoint}"); + this.logger.LogError("[OUT] TraceId: {traceId} | HTTP {httpCode} | Temps: {tempsEcoule} ms | Endpoint: {endpoint}", traceId, httpCode, tempsEcoule, endpoint); } else if (httpCode >= 400) { - this.logger.LogWarning($"[OUT] TraceId: {traceId} | HTTP {httpCode} | Temps: {tempsEcoule} ms | Endpoint: {endpoint}"); + this.logger.LogWarning("[OUT] TraceId: {traceId} | HTTP {httpCode} | Temps: {tempsEcoule} ms | Endpoint: {endpoint}", traceId, httpCode, tempsEcoule, endpoint); } else { - this.logger.LogInformation($"[OUT] TraceId: {traceId} | HTTP {httpCode} | Temps: {tempsEcoule} ms | Endpoint: {endpoint}"); + this.logger.LogInformation("[OUT] TraceId: {traceId} | HTTP {httpCode} | Temps: {tempsEcoule} ms | Endpoint: {endpoint}", traceId, httpCode, tempsEcoule, endpoint); } } }