85 lines
3.5 KiB
C#
85 lines
3.5 KiB
C#
namespace Webzine.WebApplication.Middlewares
|
|
{
|
|
using System.Diagnostics;
|
|
|
|
public class LogTempsExecutionMiddleware
|
|
{
|
|
/// <summary>
|
|
/// log à chaque requete http.
|
|
/// </summary>
|
|
// _next représente le maillon suivant dans la chaîne (le prochain middleware ou le contrôleur)
|
|
private readonly RequestDelegate next;
|
|
private readonly ILogger<LogTempsExecutionMiddleware> logger;
|
|
|
|
// Le constructeur récupère "_next" et le Logger
|
|
public LogTempsExecutionMiddleware(RequestDelegate next, ILogger<LogTempsExecutionMiddleware> logger)
|
|
{
|
|
this.next = next;
|
|
this.logger = logger;
|
|
}
|
|
|
|
// méthode appelée à chaque requête HTTP
|
|
|
|
/// <summary>
|
|
/// Middleware chargé de journaliser le cycle de vie d'une requête HTTP (entrée, exécution, sortie et temps de réponse).
|
|
/// </summary>
|
|
/// <param name="context">Le contexte HTTP encapsulant toutes les informations de la requête et de la réponse.</param>
|
|
/// <returns>Une tâche (<see cref="Task"/>) représentant l'opération asynchrone.</returns>
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
// (Avant le contrôleur)
|
|
var chronometre = Stopwatch.StartNew(); // lance le chrono
|
|
|
|
// --- IN ---
|
|
var methode = context.Request.Method;
|
|
var endpoint = context.Request.Path;
|
|
var traceId = context.TraceIdentifier; // Identifiant unique généré par .NET
|
|
var exceptionLevee = false;
|
|
|
|
this.logger.LogInformation("[IN] TraceId: {traceId} | Méthode: {methode} | Endpoint: {endpoint}", traceId, methode, endpoint);
|
|
|
|
try
|
|
{
|
|
await this.next(context);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
exceptionLevee = true;
|
|
chronometre.Stop();
|
|
this.logger.LogError(
|
|
exception,
|
|
"[EXCEPTION] TraceId: {traceId} | Temps: {tempsEcoule} ms | Endpoint: {endpoint} | Type: {exceptionType} | Message: {exceptionMessage}",
|
|
traceId,
|
|
chronometre.ElapsedMilliseconds,
|
|
endpoint,
|
|
exception.GetType().FullName,
|
|
exception.Message);
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
if (chronometre.IsRunning)
|
|
{
|
|
chronometre.Stop();
|
|
}
|
|
|
|
var tempsEcoule = chronometre.ElapsedMilliseconds;
|
|
var httpCode = exceptionLevee ? StatusCodes.Status500InternalServerError : context.Response.StatusCode; // exemple: 200, 404, 500
|
|
|
|
// --- OUT ---
|
|
if (httpCode >= 500)
|
|
{
|
|
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}", traceId, httpCode, tempsEcoule, endpoint);
|
|
}
|
|
else
|
|
{
|
|
this.logger.LogInformation("[OUT] TraceId: {traceId} | HTTP {httpCode} | Temps: {tempsEcoule} ms | Endpoint: {endpoint}", traceId, httpCode, tempsEcoule, endpoint);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |