Cómo implementar un registrador simple en C #

A menudo, querrá registrar eventos o errores a medida que ocurren en su aplicación .Net. Para hacer esto, puede aprovechar uno de los muchos marcos de registro populares disponibles, o puede diseñar y desarrollar su propio marco de registro. En este artículo veremos cómo podemos diseñar y desarrollar nuestro propio marco de registro con facilidad, y seguiremos los pasos para crear un registrador simple en C #.

En primer lugar, deberá comprender los objetivos del registro: los distintos lugares donde se pueden registrar los datos. Supongamos que registraremos los datos en archivos planos, una base de datos y el registro de eventos. La siguiente enumeración define los objetivos de registro que usaríamos en este marco simple.

public enum LogTarget

    {

        File, Database, EventLog

    }

Clases de registrador de C #

El siguiente paso es diseñar e implementar las clases. Vamos a utilizar tres clases distintas -a saber, FileLogger, DBLogger, y EventLogger: para registrar los datos en un archivo, una base de datos, y el registro de eventos, respectivamente. Todas estas clases deberían heredar la clase base abstracta denominada LogBase. Así es como se organizan estas clases.

    public abstract class LogBase

    {

        public abstract void Log(string message);

    }

    public class FileLogger : LogBase

     {

        public string filePath = @”D:\Log.txt”;

        public override void Log(string message)

        {

            using (StreamWriter streamWriter = new StreamWriter(filePath))

            {

                streamWriter.WriteLine(message);

                streamWriter.Close();

            }           

        }

    }

public class DBLogger : LogBase

    {

        string connectionString = string.Empty;

        public override void Log(string message)

        {

            //Code to log data to the database

        }

    }

    public class EventLogger: LogBase

    {

        public override void Log(string message)

        {

            EventLog eventLog = new EventLog(“”);

            eventLog.Source;

            eventLog.WriteEntry(message);

        }

    }                                

He dejado la DBLoggerclase incompleta. Dejaré que usted complete el código apropiado para registrar sus mensajes en la base de datos.

Como se puede ver, los tres de las clases - FileLogger, EventLoggery DBLogger- extender la clase base abstracta LogBase. La clase base abstracta LogBasedeclara el método abstracto llamado Log(). El Log() método acepta una cadena como parámetro; esta cadena es lo que se registrará en un archivo o una base de datos o en el registro de eventos. 

La clase C # LogHelper

Ahora creemos una clase auxiliar que se puede usar para invocar el registrador respectivo en función del parámetro pasado. Esta clase auxiliar se utilizará para simplificar las llamadas al Log()método en cada una de las clases del registrador. El siguiente fragmento de código ilustra esta clase auxiliar.

public static class LogHelper

    {

        private static LogBase logger = null;

        public static void Log(LogTarget target, string message)

        {

            switch(target)

            {

                case LogTarget.File:

                    logger = new FileLogger();

                    logger.Log(message);

                    break;

                case LogTarget.Database:

                    logger = new DBLogger();

                    logger.Log(message);

                    break;

                case LogTarget.EventLog:

                    logger = new EventLogger();

                    logger.Log(message);

                    break;

                default:

                    return;

            }

        }

    }

El Log() método de la LogHelperclase acepta una cadena y una instancia de la LogTargetenumeración como parámetros. Luego usa una switch: caseconstrucción para determinar el destino donde se registrará el mensaje de texto.

Sincronizar llamadas al método de registro de C #

¡Ups! Olvidamos sincronizar las llamadas a los Log()métodos respectivos . Para hacer esto, necesitamos usar la palabra clave lock en el Log()método de cada una de las clases del registrador e incorporar el código apropiado para sincronizar esos  Log()métodos. Consulte la LogBaseclase dada a continuación. Hemos incorporado un miembro protegido que se utilizará para aplicar el bloqueo en el Log()método de cada una de las clases derivadas. Aquí están las versiones modificadas de estas clases.

public abstract class LogBase

    {

        protected readonly object lockObj = new object();

        public abstract void Log(string message);

    }

    public class FileLogger : LogBase

    {

        public string filePath = @”D:\Log.txt”;

        public override void Log(string message)

        {

            lock (lockObj)

            {

                using (StreamWriter streamWriter = new StreamWriter(filePath))

                {

                    streamWriter.WriteLine(message);

                    streamWriter.Close();

                }

            }

        }

    }

    public class EventLogger : LogBase

    {

        public override void Log(string message)

        {

            lock (lockObj)

            {

                EventLog m_EventLog = new EventLog(“”);

                m_EventLog.Source;

                m_EventLog.WriteEntry(message);

            }

        }

    }

    public class DBLogger : LogBase

    {

        string connectionString = string.Empty;

        public override void Log(string message)

        {

            lock (lockObj)

            {

                //Code to log data to the database

            }

        }

    }

Ahora puede llamar al Log()método de la LogHelperclase y pasar el destino del registro y el mensaje de texto para registrar como parámetros.

class Program

    {

        static void Main(string[] args)

        {

            LogHelper.Log(LogTarget.File, “Hello”);

        }

    }

Si alguna vez necesita registrar el mensaje de texto en un destino de registro diferente, simplemente pasaría el destino de registro apropiado como parámetro al Log()método de la LogHelperclase.

Hay muchas formas de mejorar este marco de registro. Puede implementar asincronía y una cola para que cuando lleguen una gran cantidad de mensajes, el registrador pueda procesar estos mensajes de forma asincrónica sin tener que bloquear el hilo actual. También es posible que desee implementar niveles de importancia de los mensajes, como mensajes informativos, mensajes de advertencia, mensajes de error, etc.