AD01 Log de errores - jcpichardo/Progra-II GitHub Wiki

Instalar NLog desde NuGet

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

image

Configuración programática de NLog

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();
        }
    }
}

Inicialización del log de Errores

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}");
         }
     }
 }
⚠️ **GitHub.com Fallback** ⚠️