AD01 Log de errores - jcpichardo/Progra-II GitHub Wiki
Herramienta que utilizaremos para el registro de errores y eventos.
Niveles de logging:
Error: Para errores críticos que afectan la operación Info: Para información general sobre operaciones exitosas Debug: Para información detallada útil durante el desarrollo Trace: Para información muy detallada como valores de parámetros

Vamos a crear una clase llamada **LoggingManager **dentro de nuestra capa Utilities Esta clase nos servirá para configurar el log de errores de nuestro proyecto.
using System;
using System.Diagnostics;
using System.IO;
using Microsoft.VisualBasic.Logging;
using NLog;
using NLog.Config;
using NLog.Targets;
namespace ControlEscolar.Utilities
{
/// <summary>
/// Clase utilitaria para configurar y manejar el logging en el proyecto.
/// </summary>
public static class LoggingManager
{
private static bool _isConfigured = false;
/// <summary>
/// Configura NLog para el proyecto. Este método debe llamarse al inicio de la aplicación.
/// </summary>
public static void ConfigureLogging()
{
// Si ya está configurado, no hacer nada
if (_isConfigured)
return;
try
{
// Crear configuración básica
LoggingConfiguration config = new LoggingConfiguration();
// Crear directorio de logs
string logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs");
if (!Directory.Exists(logDirectory))
{
Directory.CreateDirectory(logDirectory);
}
// Target para todos los logs
FileTarget logFileTarget = new FileTarget
{
Name = "logfile",
FileName = Path.Combine(logDirectory, "app-${shortdate}.log"),
Layout = "${longdate} | ${level:uppercase=true} | ${logger} | ${message} ${exception:format=ToString}"
};
// Target para logs de base de datos
FileTarget dbFileTarget = new FileTarget
{
Name = "dbfile",
FileName = Path.Combine(logDirectory, "db-${shortdate}.log"),
Layout = "${longdate} | ${level:uppercase=true} | ${message} ${exception:format=ToString}"
};
// Reglas para enrutamiento de logs
// Logs de base de datos van a su archivo específico
config.AddRule(LogLevel.Trace, LogLevel.Fatal, dbFileTarget, "ControlEscolar.Data*");
// Todos los demás logs van al archivo general
config.AddRule(LogLevel.Trace, LogLevel.Fatal, logFileTarget);
//Jerarquía de niveles de log en NLog
//En NLog, los niveles de log de menor a mayor severidad son:
//Trace(el más detallado)
//Debug
//Info
//Warn
//Error
//Fatal(el más severo)
// Aplicar la configuración
LogManager.Configuration = config;
_isConfigured = true;
// Registrar que se ha configurado correctamente
Logger logger = LogManager.GetLogger("LoggingManager");
logger.Info("Sistema de logging configurado correctamente");
}
catch (Exception ex)
{
// Si falla la configuración, escribir a un archivo simple
try
{
string errorMsg = $"Error al configurar el sistema de logging: {ex.Message}";
string emergencyLog = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log_error.txt");
File.AppendAllText(emergencyLog, $"{DateTime.Now}: {errorMsg}\n{ex}\n\n");
}
catch
{
// No podemos hacer mucho más si esto falla
}
}
}
/// <summary>
/// Obtiene un logger con el nombre especificado
/// </summary>
/// <param name="loggerName">Nombre del logger</param>
/// <returns>Una instancia de Logger</returns>
public static Logger GetLogger(string loggerName)
{
if (!_isConfigured)
ConfigureLogging();
return LogManager.GetLogger(loggerName);
}
/// <summary>
/// Obtiene un logger para la clase llamadora
/// </summary>
/// <returns>Una instancia de Logger</returns>
public static Logger GetCurrentClassLogger()
{
if (!_isConfigured)
ConfigureLogging();
return LogManager.GetCurrentClassLogger();
}
}
}
Colocar las siguientes lineas en la clase Program.cs
Namespaces
using NLog;
using ControlEscolar.Utilities;
Variable global
// Logger para el programa principal
private static Logger? _logger;
Inicialización dentro del Main()
// Inicializar el sistema de logging
_logger = LoggingManager.GetLogger("ControlEscolar.Program");
_logger.Info("Aplicación iniciada");
Corremos la aplicación y vemos la creación de los LOGS
Vamos a probar mas opciones de log en la ventana de Login.
using NLog;
private static readonly Logger _logger = LoggingManager.GetLogger("ControlEscolar.View.frmLogin");
private void Login_Load(object sender, EventArgs e)
{
_logger.Info("Usuario accedio ha iniciar sesión");
_logger.Warn("Espacio en disco bajo");
try
{
// Aquí provocamos una primera excepción
try
{
int divisor = 0;
int resultado = 10 / divisor; // Esto generará una DivideByZeroException
}
catch (DivideByZeroException ex)
{
// Capturamos la primera excepción y la envolvemos en otra
throw new ApplicationException("Error al realizar el cálculo en la aplicación", ex);
}
}
catch (Exception ex)
{
// Aquí puedes manejar la excepción que contiene la inner exception
_logger.Error(ex, "Se produjo un error en la operación");
// O registrar específicamente usando la inner exception
if (ex.InnerException != null)
{
_logger.Fatal(ex, $"Error crítico con detalle interno: {ex.InnerException.Message}");
}
}
}