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
, DBLogger
und EventLogger
Daten -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 DBLogger
Klasse 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
, EventLogger
und DBLogger
- erweitern die abstrakte Basisklasse LogBase
. Die abstrakte Basisklasse LogBase
deklariert 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 LogHelper
Klasse akzeptiert eine Zeichenfolge und eine Instanz der LogTarget
Aufzählung als Parameter. Anschließend wird mithilfe eines switch: case
Konstrukts 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 LogBase
unten 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 LogHelper
Klasse 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 LogHelper
Klasse.
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.