So implementieren Sie einen einfachen Logger in C #

Sie möchten häufig Ereignisse oder Fehler protokollieren, die in Ihrer .NET-Anwendung auftreten. Zu diesem Zweck können Sie eines der vielen gängigen Protokollierungsframeworks nutzen oder ein eigenes Protokollierungsframework entwerfen und entwickeln. In diesem Artikel erfahren Sie, wie Sie problemlos unser eigenes Protokollierungsframework entwerfen und entwickeln und die Schritte zum Erstellen eines einfachen Protokollierers in C # ausführen können.

Zunächst müssen Sie die Protokollziele verstehen - die verschiedenen Stellen, an denen die Daten protokolliert werden könnten. Nehmen wir an, wir protokollieren die Daten in Flatfiles, einer Datenbank und dem Ereignisprotokoll. Die folgende Aufzählung definiert die Protokollziele, die wir in diesem einfachen Framework verwenden würden.

public enum LogTarget

    {

        File, Database, EventLog

    }

C # -Loggerklassen

Der nächste Schritt ist das Entwerfen und Implementieren der Klassen. Wir werden drei verschiedene Klassen, nämlich Verwendung FileLogger, DBLoggerund EventLoggerDaten -bis zu einer Log - Datei, eine Datenbank und das Ereignisprotokoll auf. Alle diese Klassen sollten die benannte abstrakte Basisklasse erben LogBase. So sind diese Klassen organisiert.

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

        }

    }                                

Ich habe die DBLoggerKlasse unvollständig verlassen. Ich überlasse es Ihnen, den entsprechenden Code einzugeben, um Ihre Nachrichten in der Datenbank zu protokollieren.

Wie Sie sehen können, alle drei der Klassen - FileLogger, EventLoggerund DBLogger- erweitern die abstrakte Basisklasse LogBase. Die abstrakte Basisklasse LogBasedeklariert die aufgerufene abstrakte Methode Log(). Die Log() Methode akzeptiert eine Zeichenfolge als Parameter. Diese Zeichenfolge wird in einer Datei, einer Datenbank oder dem Ereignisprotokoll protokolliert. 

Die C # LogHelper-Klasse

Erstellen wir nun eine Hilfsklasse, mit der der jeweilige Logger basierend auf dem übergebenen Parameter aufgerufen werden kann. Diese Hilfsklasse wird verwendet, um die Aufrufe der Log()Methode in jeder der Logger-Klassen zu vereinfachen . Das folgende Codefragment veranschaulicht diese Hilfsklasse.

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;

            }

        }

    }

Die Log() Methode der LogHelperKlasse akzeptiert eine Zeichenfolge und eine Instanz der LogTargetAufzählung als Parameter. Anschließend wird mithilfe eines switch: caseKonstrukts das Ziel bestimmt, an dem die Textnachricht protokolliert wird.

Synchronisieren von Aufrufen mit der C # -Protokollmethode

Hoppla! Wir haben vergessen, die Aufrufe mit den jeweiligen Log()Methoden zu synchronisieren . Dazu müssen wir das Schlüsselwort lock in der Log()Methode jeder der Logger-Klassen verwenden und den entsprechenden Code zum Synchronisieren dieser  Log()Methoden einbinden. Beziehen Sie sich auf die LogBaseunten angegebene Klasse. Wir haben ein geschütztes Mitglied integriert, mit dem die Sperre in die Log()Methode jeder der abgeleiteten Klassen angewendet wird . Hier sind die geänderten Versionen dieser Klassen.

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

            }

        }

    }

Sie können jetzt die Log()Methode der LogHelperKlasse aufrufen und das Protokollziel und die Textnachricht übergeben, um sie als Parameter zu protokollieren.

class Program

    {

        static void Main(string[] args)

        {

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

        }

    }

Wenn Sie die Textnachricht jemals auf einem anderen Protokollziel protokollieren müssen, übergeben Sie einfach das entsprechende Protokollziel als Parameter an die Log()Methode der LogHelperKlasse.

Es gibt viele Möglichkeiten, wie Sie dieses Protokollierungsframework verbessern können. Sie können Asynchronität und eine Warteschlange implementieren, sodass der Logger diese Nachrichten bei Ankunft einer großen Anzahl von Nachrichten asynchron verarbeiten kann, ohne den aktuellen Thread blockieren zu müssen. Möglicherweise möchten Sie auch Nachrichtenkritikalitätsstufen implementieren, z. B. Informationsnachrichten, Warnmeldungen, Fehlermeldungen usw.