Nouveau : Datasets open source gratuits disponibles !Decouvrir →
📊
Intermediaire 20 min .NET

Logging et monitoring .NET

Pourquoi Logging et monitoring .NET ?

Contexte réel : pourquoi un dev a besoin de ça au quotidien

En tant que développeur, vous allez souvent travailler sur des projets qui évoluent rapidement. Vous serez amené à gérer plusieurs environnements (développement, intégration continue, production), à traiter de grandes quantités de données et à assurer un service continu. Logging et monitoring sont essentiels pour vous aider à diagnostiquer les problèmes, à optimiser le rendement et à garantir la qualité du service.

Un cas d'usage concret en 2-3 phrases

Imaginez que vous travaillez sur une application e-commerce qui gère des milliers de commandes par jour. Vous voulez être capable de détecter rapidement si un problème survient, comme une panne de base de données ou une erreur dans le traitement des paiements. En utilisant logging et monitoring, vous pouvez facilement identifier les anomalies et prendre des mesures correctives immédiatement.

Prerequis

Concepts fondamentaux

Logging

Logging est le processus d'enregistrement des informations sur les événements qui se produisent lors de l'exécution d'un programme. Ces informations peuvent être utilisées pour déboguer, analyser et optimiser les performances de l'application.

Schema mental : Logging

+-------------------+
|     Application   |
|                   |
|  +-------------+  |
|  |    Code     |  |
|  +-------------+  |
|  | LogManager  |  |
|  +-------------+  |
|  | Logger      |  |
|  +-------------+  |
|  | Output      |  |
+-------------------+

Logger.cs

using Microsoft.Extensions.Logging;

public class Logger
{
    private readonly ILogger _logger;

    public Logger(ILoggerFactory loggerFactory)
    {
        _logger = loggerFactory.CreateLogger<Logger>();
    }

    public void LogInformation(string message)
    {
        _logger.LogInformation(message);
    }

    public void LogWarning(string message)
    {
        _logger.LogWarning(message);
    }

    public void LogError(string message)
    {
        _logger.LogError(message);
    }
}

Program.cs

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddSingleton<Logger>();
            })
            .ConfigureLogging(logging =>
            {
                logging.ClearProviders();
                logging.AddConsole();
            });
}

Monitoring

Monitoring est le processus de surveillance et d'analyse des performances et de l'état d'une application en temps réel. Il permet de détecter les problèmes, de générer des alertes et de prendre des décisions éclairées.

Schema mental : Monitoring

+-------------------+
|     Application   |
|                   |
|  +-------------+  |
|  |    Code     |  |
|  +-------------+  |
|  | Metrics     |  |
|  +-------------+  |
|  | Monitor     |  |
|  +-------------+  |
|  | Alert       |  |
+-------------------+

Metrics.cs

using System.Collections.Generic;

public class Metrics
{
    public Dictionary<string, long> GetMetrics()
    {
        return new Dictionary<string, long>
        {
            { "RequestCount", 100 },
            { "ErrorCount", 5 }
        };
    }
}

Monitor.cs

using Microsoft.Extensions.Logging;

public class Monitor
{
    private readonly ILogger _logger;
    private readonly Metrics _metrics;

    public Monitor(ILogger<Monitor> logger, Metrics metrics)
    {
        _logger = logger;
        _metrics = metrics;
    }

    public void CheckMetrics()
    {
        var metrics = _metrics.GetMetrics();
        if (metrics["ErrorCount"] > 0)
        {
            _logger.LogError($"High error count: {metrics["ErrorCount"]}");
        }
    }
}

Program.cs

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureServices((hostContext, services) =>
            {
                services.AddSingleton<Metrics>();
                services.AddSingleton<Monitor>();
            })
            .ConfigureLogging(logging =>
            {
                logging.ClearProviders();
                logging.AddConsole();
            });
}

Mise en pratique : projet fil rouge

Construisons un gestionnaire de tâches simple (TaskManager)

  1. Créez un nouveau projet ASP.NET Core

    dotnet new webapi -n TaskManager
    cd TaskManager
    
  2. Ajoutez les packages nécessaires

    dotnet add package Microsoft.Extensions.Logging.Abstractions
    dotnet add package Serilog.AspNetCore
    dotnet add package Serilog.Sinks.Console
    
  3. Configurez Serilog dans Program.cs

    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Serilog;
    
    public class Program
    {
        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(Configuration)
                .Enrich.FromLogContext()
                .WriteTo.Console()
                .CreateLogger();
    
            try
            {
                Log.Information("Starting web host");
                CreateHostBuilder(args).Build().Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Host terminated unexpectedly");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseSerilog()
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddControllers();
                });
    }
    
  4. Créez un service pour gérer les tâches

    TaskService.cs

    using System.Collections.Generic;
    using Microsoft.Extensions.Logging;
    
    public class TaskService
    {
        private readonly ILogger<TaskService> _logger;
        private List<string> _tasks = new List<string>();
    
        public TaskService(ILogger<TaskService> logger)
        {
            _logger = logger;
        }
    
        public void AddTask(string task)
        {
            _logger.LogInformation($"Adding task: {task}");
            _tasks.Add(task);
        }
    
        public List<string> GetTasks()
        {
            return _tasks;
        }
    }
    
  5. Configurez le service dans Program.cs

    using Microsoft.Extensions.DependencyInjection;
    
    public class Program
    {
        public static void Main(string[] args)
        {
            Log.Logger = new LoggerConfiguration()
                .ReadFrom.Configuration(Configuration)
                .Enrich.FromLogContext()
                .WriteTo.Console()
                .CreateLogger();
    
            try
            {
                Log.Information("Starting web host");
                CreateHostBuilder(args).Build().Run();
            }
            catch (Exception ex)
            {
                Log.Fatal(ex, "Host terminated unexpectedly");
            }
            finally
            {
                Log.CloseAndFlush();
            }
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .UseSerilog()
                .ConfigureServices((hostContext, services) =>
                {
                    services.AddControllers();
                    services.AddScoped<TaskService>();
                });
    }
    
  6. Créez un contrôleur pour gérer les tâches

    TasksController.cs

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    
    [ApiController]
    [Route("api/[controller]")]
    public class TasksController : ControllerBase
    {
        private readonly TaskService _taskService;
        private readonly ILogger<TasksController> _logger;
    
        public TasksController(TaskService taskService, ILogger<TasksController> logger)
        {
            _taskService = taskService;
            _logger = logger;
        }
    
        [HttpPost]
        public IActionResult AddTask([FromBody] string task)
        {
            if (string.IsNullOrEmpty(task))
            {
                _logger.LogWarning("Task cannot be empty");
                return BadRequest("Task cannot be empty");
            }
    
            _taskService.AddTask(task);
            _logger.LogInformation($"Task added: {task}");
            return Ok();
        }
    
        [HttpGet]
        public IActionResult GetTasks()
        {
            var tasks = _taskService.GetTasks();
            _logger.LogInformation($"Returning {tasks.Count} tasks");
            return Ok(tasks);
        }
    }
    
  7. Testez l'application

    dotnet run
    

    Ouvrez un navigateur et accédez à http://localhost:5000/api/tasks. Vous devriez être capable d'ajouter des tâches et de les récupérer.

Erreurs fréquentes et debugging

1. Erreur : Object reference not set to an instance of an object

Code incorrect

public void AddTask(string task)
{
    _tasks.Add(task); // _tasks est null
}

Code correct

public void AddTask(string task)
{
    if (_tasks == null)
        _tasks = new List<string>();

    _tasks.Add(task);
}

2. Erreur : System.ArgumentNullException: Value cannot be null.

Code incorrect

[HttpPost]
public IActionResult AddTask([FromBody] string task)
{
    _taskService.AddTask(task); // task est null
    return Ok();
}

Code correct

[HttpPost]
public IActionResult AddTask([FromBody] string task)
{
    if (string.IsNullOrEmpty(task))
    {
        return BadRequest("Task cannot be empty");
    }

    _taskService.AddTask(task);
    return Ok();
}

3. Erreur : System.InvalidOperationException: Sequence contains no elements

Code incorrect

[HttpGet]
public IActionResult GetTasks()
{
    var tasks = _taskService.GetTasks();
    var count = tasks.Count; // Si tasks est vide, Count lève une exception
    return Ok(tasks);
}

Code correct

[HttpGet]
public IActionResult GetTasks()
{
    var tasks = _taskService.GetTasks();
    var count = tasks.Count;
    if (count == 0)
    {
        return NotFound("No tasks found");
    }

    return Ok(tasks);
}

Pour aller plus loin

1. Utilisation de structured logging

Structured logging permet d'enregistrer les informations sous forme structurée, facilitant ainsi l'analyse et le traitement des journaux.

2. Intégration avec Prometheus et Grafana

Prometheus est un système de monitoring open source, tandis que Grafana est une plateforme d'analyse et de visualisation des données.

3. Utilisation de Application Insights

Application Insights est un service de surveillance d'applications Azure qui permet d'analyser les performances, la disponibilité et le comportement des applications.

Défi pratique

Défi :

Créez un service de logging personnalisé qui utilise Azure Log Analytics. Implémentez une fonction pour enregistrer les informations d'erreur et afficher ces journaux dans le portail Azure.

Besoin d'aide sur .NET ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment configurer le logging pour une application .NET?
Pour configurer le logging dans une application .NET, vous pouvez utiliser le framework intégré .NET Core Logging qui prend en charge plusieurs fournisseurs de journalisation comme la console, les fichiers, l'EventSource, etc. Vous devez créer un fichier de configuration (appsettings.json) pour spécifier le niveau de gravité et le type de fournisseur de journalisation à utiliser.
Quels sont les avantages de l'utilisation du monitoring en développement .NET?
L'utilisation du monitoring en développement .NET offre plusieurs avantages tels que la dététection précoce des erreurs, l'optimisation des performances et l'amélioration de la qualité de l'application. Il permet également d'analyser le comportement de l'application en temps réel et de prendre des décisions éclairées sur les améliorations nécessaires.
Comment intégrer des métriques dans une application .NET pour faciliter le monitoring?
Pour intégrer des métriques dans une application .NET, vous pouvez utiliser des bibliothèques comme Prometheus.NET ou Metrics.NET. Ces bibliothèques permettent de créer et d'exposer des métriques telles que les taux de requêtes, la durée des appels, le nombre d'erreurs, etc., qui peuvent ensuite être collectées et analysées par un système de monitoring.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.