Usando Log4Net, una manera rapida

En algunas situaciones, necesitamos implementar rapidamente un mecanismo de trazabilidad o instrumentacion que escriba en un archivo, en otras palabras un log, en mi caso uso bastante Log4Net y varias personas de tiempo en tiempo me preguntan como usarlo en proyectos we. Aunque hay varios ejemplos, articulos y codigo en internet para tal fin, muchos de ellos dan muchas vueltas sobre el tema antes de mostrarlo concretamente, es mi objetivo en este post mostrar como habilitar log4net en unos sencillos pasos a seguir:

Pasos a seguir

1. Descarga Log4Net, preferiblemente usando Nuget

2. Modificar el archivo web.config, agregando las secciones que muestro en las siguientes capturas de pantalla, he utilizado dos capturas en un archivo bastante lago, para que al ver la captura sepan donde insertalas.

Log4Net-1

En la segunda captura de pantalla que muestro a continuacion, he señalado dos puntos importantes de la configuracion. El primero es el nivel de trazabilidad que se requiere, esto se refiere a cuanta informacion queremos obtener en el log, hare un post separado para este tema y el segundo es el nombre del archivo de log que se generara.

Log4Net-2

3. Para utilizar Log4Net, yo utilizo una variacion mas elaborada de esta clase (Logger). La funcion de esta clase es dar acceso a metodos de Log4Net, formateando previamente el texto y tambien instanciar de manera simple el logger.

public static class Logger
    {
        #region Fields

        private static readonly ILog mLog = LogManager.GetLogger(typeof(Logger));

        #endregion Fields

        #region Constructor

        static Logger()
        {
            Debug.WriteLine("Server Logger initializing...");

            log4net.Config.XmlConfigurator.Configure();

            if (mLog != null)
            {
                Debug.WriteLine("Server Logger initialized");
                Debug.WriteLine(string.Format("Debug: {0}, Error: {1}, Info: {2}, Warning {3}", 
mLog.IsDebugEnabled, mLog.IsErrorEnabled, mLog.IsInfoEnabled, mLog.IsWarnEnabled));
            }
            else
            {
                Debug.WriteLine("Failed initializing Server Logger");
            }

        }

        #endregion Constructor

        #region Public Methods

        public static void PublishException(Exception exception)
        {
            if (mLog != null)
                mLog.Error("Exception", exception);
        }

        public static void WriteVerbose(string category, string message)
        {
            if (mLog != null)
                mLog.Debug(FormatMessage(category, message));
        }

        public static void WriteInfo(string category, string message)
        {
            if (mLog != null)
                mLog.Info(FormatMessage(category, message));
        }

        public static void WriteWarning(string category, string message)
        {
            if (mLog != null)
                mLog.Warn(FormatMessage(category, message));
        }

        public static void TraceError(string category, string message)
        {
            if (mLog != null)
                mLog.Error(FormatMessage(category, message));
        }

        public static void Write(TraceLevel level, string category, string message)
        {
            switch (level)
            {
                case TraceLevel.Verbose:
                    WriteVerbose(category, message);
                    break;
                case TraceLevel.Info:
                    WriteInfo(category, message);
                    break;
                case TraceLevel.Warning:
                    WriteWarning(category, message);
                    break;
                case TraceLevel.Error:
                    TraceError(category, message);
                    break;
            }
        }

        #endregion Public Methods

        #region Private Methods

        private const string MessageFormat = "{0} | {1}";
        private const int MaxCategoryNameLength = 25;

        private static string FormatMessage(string category, string message)
        {
            string output = string.Format(MessageFormat, FormatName(category, 
MaxCategoryNameLength), message);
            return output;
        }

        private static string FormatName(string name, int minLength)
        {
            string result;
            string trimName = name != null ? name.Trim() : string.Empty;
            if (trimName.Length >= minLength)
                result = trimName;
            else
                result = trimName.PadRight(minLength);
            return result;
        }
        #endregion Private Methods
    }

4. Finalmente para utilizar la clase, simplemente realizamos invocaciones a los metodos estaticos de la clase Logger, por ejemplo:

Logger.WriteInfo (“Categoria”,”Mensaje…..”);

 

Consideraciones

  • El Log del ejemplo que les presento, se escribira en la carpeta raiz de la aplicacion web, no es la mejor practica, lo mas recomendable es crear una carpeta especial para guardar los logs.
  • La carpeta donde se escriban estos logs, deben tener los permisos adecuados para el usuario sobre el que corre el proceso de IIS, en caso de Windows 2008, podria ser “Network Services”, pero puede variar dependiendo de su sistema operativo, es comun tener muchos problemas por este punto.
  • Esta forma de escribir el log es adecuada para una aplicacion aislada pero para aplicaciones distribuidas puede llegar a convertirse en un dolor de cabeza recolectar cientos de archivos dispersos en varias ubicaciones, lo ideal es guardar esta informacion centralizadamente, probablemente en una base de datos, ultimamente estoy experimentando (en un proyecto fuera de la oficina) con MongoDB y es bastante rapido, obviamente lanzo el log en un proceso asincronico que no bloquea la aplicacion, este tambien es tema de una futura entrada.

Espero que esto les haya sido de utilidad.

3 comentarios en “Usando Log4Net, una manera rapida

  1. Log4Net salió como imitación de su equivalente en Java y como respuesta a la deficiencia que tenia el Framework de .NET en su versión 1.0 y 1.1

    En la versión 2.0 ya se incluyo una librería completa para generar log. La cual permite filtrar a conveniencia, crear lisening e incluso existe una herramienta en el SDK bastante buena.

    No entiendo por que esa creencia de por utilizar otro tipo de librarías y si son de código abierto mejor, cuando el propio Framework ya lo soporta.

  2. Estoy de acuerdo con @andrechi. Actualmente el propio “framework” de .NET ofrece una buena librería para generar “logs” a través de “System.Diagnostics”.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *