Registro en aplicaciones C#: mejores prácticas
El registro no es solo escribir mensajes en un archivo. En las aplicaciones modernas de .NET, es una herramienta críticamente importante para monitoreo, depuración y auditoría. Un registro bien configurado permite encontrar rápidamente las causas de fallos, analizar el rendimiento y garantizar el cumplimiento de los requisitos de seguridad. En este artículo, analizaremos las mejores prácticas de registro en C# que le ayudarán a construir un sistema confiable de recopilación de información de diagnóstico.
Elección de la biblioteca de registro: Serilog vs NLog vs ILogger integrado
En .NET existen varias soluciones populares. Analicemos sus fortalezas y debilidades.
- Microsoft.Extensions.Logging (ILogger) — interfaz abstracta integrada. Adecuada para proyectos simples. No soporta registro estructurado «de fábrica».
- Serilog — líder en popularidad. Se destaca por su facilidad de configuración, potente soporte para registros estructurados y un amplio conjunto de sinks (receptores de datos).
- NLog — framework maduro con configuración flexible a través de XML o código. Ideal para sistemas heredados y escenarios complejos de enrutamiento.
Para un proyecto nuevo, se recomienda Serilog. Se integra fácilmente con ILogger y proporciona una API concisa. Ejemplo de conexión:
// Instalación: dotnet add package Serilog.AspNetCoreusing Serilog;
Log.Logger = new LoggerConfiguration() .MinimumLevel.Information() .WriteTo.Console() .WriteTo.File("logs/app-.log", rollingInterval: RollingInterval.Day) .CreateLogger();
var builder = WebApplication.CreateBuilder(args);builder.Host.UseSerilog(); // Reemplazo del registrador estándarUso correcto de los niveles de registro
No mezcle todos los mensajes en un solo nivel. Utilice la siguiente gradación:
- Trace (0) — información máximamente detallada para depuración. Incluye detalles de ejecución de cada función. Actívelo solo en entorno de desarrollo.
- Debug (1) — datos útiles para el desarrollador: valores de variables, resultado de ejecución de métodos.
- Information (2) — eventos de negocio: «El usuario inició sesión», «Pedido creado». Deben ser comprensibles no solo para el programador.
- Warning (3) — anomalías que no interrumpen el trabajo: tiempo de ejecución excedido, reintentos de conexión.
- Error (4) — excepciones y fallos que requieren intervención. Siempre registre la pila de llamadas completa.
- Critical (5) — errores fatales: pérdida de conexión con la base de datos, desbordamiento de memoria. Requieren notificación inmediata.
Ejemplo de registro correcto en un controlador:
[ApiController][Route("api/orders")]public class OrdersController : ControllerBase{ private readonly ILogger<OrdersController> _logger;
public OrdersController(ILogger<OrdersController> logger) { _logger = logger; }
[HttpPost] public IActionResult CreateOrder(OrderDto order) { _logger.LogInformation("Creación del pedido {OrderId} para el usuario {UserId}", order.Id, order.UserId); try { // lógica de negocio _logger.LogInformation("Pedido {OrderId} creado exitosamente", order.Id); return Ok(); } catch (Exception ex) { _logger.LogError(ex, "Error al crear el pedido {OrderId}", order.Id); return StatusCode(500); } }}Registro estructurado y contexto
Evite la concatenación de cadenas en los registros. En lugar de Log.Information("User: " + user.Name) use plantillas con parámetros:
_logger.LogInformation("Usuario {UserName} realizó