Comment arrêter de deviner et commencer à voir votre code à travers ?
Avez-vous déjà passé une nuit devant votre écran, à scruter des logs qui crient une erreur sans en révéler la cause ? Ou essayé de comprendre pourquoi votre microservice en C# répond en 10 secondes alors qu'hier tout fonctionnait parfaitement ? Cela vous parle ? Bienvenue dans un monde où sans Observabilité, votre code est une boîte noire.
Dans cet article, nous n'allons pas faire de cours ennuyeux. Nous allons décortiquer les trois piliers de l'observabilité : le traçage, les métriques et les logs — et montrer comment les intégrer avec C#. Vous apprendrez à arrêter d'éteindre des incendies et à commencer à les prévenir. C'est parti !
Qu'est-ce que l'Observabilité et pourquoi ce n'est pas juste "de la journalisation" ?
Beaucoup confondent l'observabilité avec la simple collecte de logs. Mais la différence est colossale. L'observabilité est une propriété du système qui vous permet de poser n'importe quelle question sur son état, sans ajouter de nouveau code. Les trois piliers sur lesquels tout repose :
- Logs — des événements discrets. "L'utilisateur a cliqué sur un bouton", "Erreur de connexion". C'est "que s'est-il passé ?".
- Métriques — des données agrégées. "Requêtes par seconde", "Consommation mémoire". C'est "combien et à quelle fréquence ?".
- Traces — le chemin d'une requête à travers le système. "La requête est arrivée, est allée en BDD, puis dans le cache, est revenue". C'est "pourquoi cela prend-il autant de temps ?".
Dans l'écosystème C# .NET, ces trois piliers sont unifiés grâce à des bibliothèques comme OpenTelemetry. Et maintenant, voyons à quoi cela ressemble en code.
Mettons en place une expérience : écrivons une application avec de l'observabilité
Imaginez que nous avons un service simple en ASP.NET Core qui traite des commandes. Nous voulons voir :
- Chaque étape du traitement de la commande (traçage).
- Combien de commandes sont traitées et avec quelle erreur (métriques).
- Les détails des exceptions (logs).
Étape 1 : Configuration de la journalisation avec Serilog
Commençons par ce qu'il y a de plus simple : les logs. Utilisons Serilog (mais NLog fonctionne aussi). Il permet d'écrire des logs structurés, faciles à analyser par la suite.
// NuGet : Serilog, Serilog.AspNetCore, Serilog.Sinks.Consoleusing Serilog;
// Configuration dans Program.csLog.Logger = new LoggerConfiguration() .WriteTo.Console() .WriteTo.File("logs/app.log", rollingInterval: RollingInterval.Day) .Enrich.WithProperty("Application", "OrderService") .CreateLogger();
var builder = WebApplication.CreateBuilder(args);builder.Host.UseSerilog(); // Remplace le logger standard
// Exemple d'utilisation dans un contrôleur[ApiController][Route("api/[controller]")]public class OrderController : ControllerBase{ private readonly ILogger<OrderController> _logger;
public OrderController(ILogger<OrderController> logger) => _logger = logger;
[HttpPost] public IActionResult CreateOrder(Order order) { _logger.LogInformation("Création de la commande {OrderId} pour l'utilisateur {User}", order.Id, order.UserId); // ... logique ... _logger.LogWarning("La commande {OrderId} est retardée en raison de problèmes de stock", order.Id); return Ok(); }}Remarquez : nous utilisons des espaces réservés nommés ({OrderId}). Ce n'est pas juste du texte — ce sont des données structurées. Dans Elasticsearch ou Grafana Loki, vous pourrez rechercher tous les logs pour un OrderId spécifique.
Étape 2 : Métriques avec Prometheus et .NET
Les métriques sont là pour les "chiffres". Combien de requêtes par seconde ? Combien d'erreurs 500 ? En C#, nous utilisons les Meters de System.Diagnostics.Metrics ou la bibliothèque prometheus-net.
Créons un simple compteur de commandes traitées :
// NuGet : prometheus-net.AspNetCoreusing Prometheus;
// Dans Program.cs, ajoutons les métriquesvar builder = WebApplication.CreateBuilder(args);