Comment implémenter un simple logger en C #

Vous souhaiterez souvent enregistrer les événements ou les erreurs lorsqu'ils se produisent dans votre application .Net. Pour ce faire, vous pouvez tirer parti de l'un des nombreux frameworks de journalisation disponibles, ou vous pouvez concevoir et développer votre propre framework de journalisation. Dans cet article, nous verrons comment nous pouvons concevoir et développer facilement notre propre cadre de journalisation et parcourir les étapes pour créer un enregistreur simple en C #.

Tout d'abord, vous devrez comprendre les cibles du journal - les différents endroits où les données pourraient être enregistrées. Supposons que nous enregistrons les données dans des fichiers plats, une base de données et le journal des événements. L'énumération suivante définit les cibles de journal que nous utiliserions dans ce cadre simple.

public enum LogTarget

    {

        File, Database, EventLog

    }

Classes de journalisation C #

L'étape suivante consiste à concevoir et à implémenter les classes. Nous utiliserons trois classes distinctes , à savoir, FileLogger, DBLoggeret EventLogger-pour enregistrer les données dans un fichier, une base de données et le journal des événements respectivement. Toutes ces classes doivent hériter de la classe de base abstraite nommée LogBase. Voici comment ces classes sont organisées.

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

        }

    }                                

J'ai laissé le DBLoggercours incomplet. Je vous laisse le soin de renseigner le code approprié pour enregistrer vos messages dans la base de données.

Comme vous pouvez le voir, les trois classes - FileLogger, EventLoggeret DBLogger- étendre la classe de base abstraite LogBase. La classe de base abstraite LogBasedéclare la méthode abstraite appelée Log(). La Log() méthode accepte une chaîne comme paramètre; cette chaîne est ce qui sera consigné dans un fichier ou une base de données ou le journal des événements. 

La classe C # LogHelper

Créons maintenant une classe d'assistance qui peut être utilisée pour appeler le journal respectif en fonction du paramètre passé. Cette classe d'assistance sera utilisée pour simplifier les appels à la Log()méthode dans chacune des classes de journalisation. L'extrait de code suivant illustre cette classe d'assistance.

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;

            }

        }

    }

La Log() méthode de la LogHelperclasse accepte une chaîne et une instance de l' LogTargeténumération comme paramètres. Il utilise ensuite une switch: caseconstruction pour déterminer la cible où le message texte sera consigné.

Synchronisation des appels à la méthode C # Log

Oops! Nous avons oublié de synchroniser les appels aux Log()méthodes respectives . Pour ce faire, nous devons utiliser le mot-clé lock dans la Log()méthode de chacune des classes de journalisation et incorporer le code approprié pour synchroniser ces  Log()méthodes. Référez-vous à la LogBaseclasse donnée ci-dessous. Nous avons incorporé un membre protégé qui sera utilisé pour appliquer le verrou dans la Log()méthode de chacune des classes dérivées. Voici les versions modifiées de ces classes.

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

            }

        }

    }

Vous pouvez maintenant appeler la Log()méthode de la LogHelperclasse et transmettre la cible du journal et le message texte à journaliser en tant que paramètres.

class Program

    {

        static void Main(string[] args)

        {

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

        }

    }

Si jamais vous avez besoin de consigner le message texte dans une autre cible de journal, vous devez simplement transmettre la cible de journal appropriée en tant que paramètre à la Log()méthode de la LogHelperclasse.

Il existe de nombreuses façons d'améliorer ce cadre de journalisation. Vous pouvez implémenter une asynchrone et une file d'attente afin que, lorsqu'un grand nombre de messages arrivent, l'enregistreur puisse traiter ces messages de manière asynchrone sans avoir à bloquer le thread actuel. Vous souhaiterez peut-être également implémenter des niveaux de criticité des messages, tels que des messages d'information, des messages d'avertissement, des messages d'erreur, etc.