Julien Chomarat
Dans cet article nous allons voir comment modifier le template de base d'une application aspnet
pour logger les erreurs au démarrage.
Ci-dessous, vous avez le template proposé dans le Program.cs
avec ses grandes étapes commentées.
// Création du WebApplicationBuilder
var builder = WebApplication.CreateBuilder(args);
// Enregistrement des services
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Création de l'application
var app = builder.Build();
// Enregistrement des middleware et des endpoints
app.UseHttpsRedirection();
app.MapGet("/weatherforecast", () => { /* Code endpoint*/ })
.WithName("GetWeatherForecast")
.WithOpenApi();
// Démarrage de l'application
app.Run();
Comme vous pouvez le voir, le démarrage d'une application aspnet
fait beaucoup de choses et peut donc planter à tout moment.
Si votre application démarre, tout va bien, vous avez un logger qui a été configuré automatiquement en fonction des informations dans votre appsettings.json
et vous aurez des logs qui s'afficheront dans votre console.
En revanche, si elle ne démarre pas, vous n'aurez rien car le logger par défaut n'est pas encore disponible à ce moment.
Nous allons donc modifier ce template pas à pas pour rendre le démarrage un peu plus bavard.
// Les usings nécessaires pour récupérer les informations de base
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
// On crée ici notre logger factory, avec une configuration simple
// Attention: le using ici est très important, il permet de faire un flush des logs
// lors du Dispose
using var factory = LoggerFactory.Create(builder =>
builder.AddSimpleConsole(options =>
{
options.IncludeScopes = false;
options.SingleLine = true;
options.TimestampFormat = "HH:mm:ss ";
}));
// On crée notre logger pour le démarrage
var logger = factory.CreateLogger<Program>();
try
{
var builder = WebApplication.CreateBuilder(args);
// Dans les lignes qui suivent, on affiche ici toutes les informations de base
// de notre application et de l'environnement d'éxecution
logger.LogInformation("-------------------------------------------------");
logger.LogInformation("Starting... {Name}", Assembly.GetEntryAssembly()!.GetName().Name);
logger.LogInformation("FrameworkName: {FrameworkName}",
Assembly.GetEntryAssembly()!.GetCustomAttribute<TargetFrameworkAttribute>()?.FrameworkName);
logger.LogInformation("OSDescription: {OSDescription}", RuntimeInformation.OSDescription);
logger.LogInformation("OSArchitecture: {OSArchitecture}", RuntimeInformation.OSArchitecture);
logger.LogInformation("ProcessArchitecture {ProcessArchitecture}", RuntimeInformation.ProcessArchitecture);
logger.LogInformation("ProcessId: {ProcessId}", Environment.ProcessId);
logger.LogInformation("Urls: {Urls}", builder.WebHost.GetSetting(WebHostDefaults.ServerUrlsKey)?.Replace(";", " "));
logger.LogInformation("-------------------------------------------------");
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseHttpsRedirection();
app.MapGet("/weatherforecast", () => { /* Code endpoint*/ })
.WithName("GetWeatherForecast")
.WithOpenApi();
app.Run();
}
// Si le démarrage se passe mal alors on catch l'Exception et on la log
catch (Exception ex)
{
logger.LogCritical(ex, "Application failed to start");
throw;
}
Maintenant quand vous lancerez votre application vous aurez ces informations de disponibles
15:22:01 info: Program[0] -------------------------------------------------
15:22:01 info: Program[0] Starting... WebApplication1
15:22:01 info: Program[0] FrameworkName: .NETCoreApp,Version=v8.0
15:22:01 info: Program[0] OSDescription: Microsoft Windows 10.0.26100
15:22:01 info: Program[0] OSArchitecture: X64
15:22:01 info: Program[0] ProcessArchitecture X64
15:22:01 info: Program[0] ProcessId: 12572
15:22:01 info: Program[0] Urls: http://localhost:5234
15:22:01 info: Program[0] -------------------------------------------------
Par exemple, si votre application se bloque mais ne plante pas, vous connaissez le PID
à inspecter.
Vous ne connaissez pas le PORT
utilisé, vous avez aussi cette information.
Si votre application renvoie une Exception
et s'arrête immédatiement vous aurez ce type de logs
15:41:44 info: Program[0] -------------------------------------------------
15:41:44 info: Program[0] Starting... WebApplication1
15:41:44 info: Program[0] FrameworkName: .NETCoreApp,Version=v8.0
15:41:44 info: Program[0] OSDescription: Microsoft Windows 10.0.26100
15:41:44 info: Program[0] OSArchitecture: X64
15:41:44 info: Program[0] ProcessArchitecture X64
15:41:44 info: Program[0] ProcessId: 29464
15:41:44 info: Program[0] Urls: http://localhost:5234
15:41:44 info: Program[0] -------------------------------------------------
15:41:44 crit: Program[0] Application failed to start
System.Exception: La configuration est manquante at Program.<Main>$(String[] args)
in C:\dev\WebApplication1\WebApplication1\Program.cs:line 33
Vous disposez du Message
et de la StackTrace
afin de remonter à l'erreur d'origine.
Vous avez maintenant ce qu'il faut pour comprendre pourquoi votre application refuse de se lancer.
Ce qui est important ici est que ce Logger
pour le démarrage est configuré manuellement ET en dur afin d'éviter les problèmes avec des dépendances externes (ex : un fichier de config ou un service distant).
Ce Logger
est utilisé uniquement pendant le démarrage, ce n'est pas celui configuré et utilisé par l'application.
Je l'ai configuré ici pour envoyer les messages dans la console mais vous pouvez adapter ça à vos besoins. Au risque de me répéter, pensez à rester sur quelque chose de basique qui fonctionnera toujours.