Programmering

Sådan implementeres en simpel logger i C #

Du vil ofte gerne logge begivenheder eller fejl, som de forekommer i din. For at gøre dette kan du drage fordel af en af ​​de mange populære logningsrammer til rådighed, eller du kan designe og udvikle din egen logningsramme. I denne artikel vil vi se, hvordan vi nemt kan designe og udvikle vores egen logningsramme og gå gennem trinnene for at opbygge en simpel logger i C #.

For det første skal du forstå logmålene - de forskellige steder, hvor dataene kunne logges. Lad os antage, at vi logger dataene til flade filer, en database og hændelsesloggen. Følgende opregning definerer de logmål, vi vil bruge i denne enkle ramme.

offentlig enum LogTarget

    {

Fil, database, EventLog

    }

C # logger klasser

Det næste trin er at designe og implementere klasserne. Vi vil bruge tre forskellige klasser - nemlig FileLogger, DBLoggerog EventLogger—Til at logge data i henholdsvis en fil, en database og hændelsesloggen. Alle disse klasser skal arve den navngivne abstrakte baseklasse LogBase. Her er hvordan disse klasser er organiseret.

  offentlig abstrakt klasse LogBase

    {

offentlig abstrakt ugyldig Log (strengbesked);

    }

offentlig klasse FileLogger: LogBase

     {

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

offentlig tilsidesættelse ugyldig log (strengbesked)

        {

ved hjælp af (StreamWriter streamWriter = ny StreamWriter (filePath))

            {

streamWriter.WriteLine (besked);

streamWriter.Close ();

            }           

        }

    }

offentlig klasse DBLogger: LogBase

    {

streng connectionString = string.Empty;

offentlig tilsidesættelse ugyldig log (strengbesked)

        {

// Kode for at logge data i databasen

        }

    }

offentlig klasse EventLogger: LogBase

    {

offentlig tilsidesættelse ugyldig log (strengbesked)

        {

EventLog eventLog = ny EventLog (“”);

eventLog.Source;

eventLog.WriteEntry (besked);

        }

    }                                

Jeg har forladt DBLogger klasse ufuldstændig. Jeg overlader det til dig at udfylde den relevante kode for at logge dine meddelelser til databasen.

Som du kan se, er alle tre klasser - FileLogger, EventLoggerog DBLogger - udvide den abstrakte basisklasse LogBase. Den abstrakte basisklasse LogBase erklærer den abstrakte metode kaldet Log (). Det Log () metode accepterer en streng som parameter; denne streng er hvad der vil blive logget på en fil eller en database eller hændelsesloggen.

C # LogHelper-klassen

Lad os nu oprette en hjælperklasse, der kan bruges til at påkalde den respektive logger baseret på den valgte parameter. Denne hjælperklasse vil blive brugt til at forenkle opkaldene til Log () metode i hver af loggerklasser. Følgende kodestykke illustrerer denne hjælperklasse.

offentlig statisk klasse LogHelper

    {

privat statisk LogBase logger = null;

offentlig statisk tomrumslog (LogTarget-mål, strengbesked)

        {

switch (mål)

            {

sag LogTarget.File:

logger = ny FileLogger ();

logger.Log (besked);

pause;

sag LogTarget.Database:

logger = ny DBLogger ();

logger.Log (besked);

pause;

sag LogTarget.EventLog:

logger = ny EventLogger ();

logger.Log (besked);

pause;

Standard:

Vend tilbage;

            }

        }

    }

Det Log () metode til LogHelper klasse accepterer en streng og en forekomst af LogTarget optælling som parametre. Det bruger derefter en switch: sag konstruere for at bestemme målet, hvor tekstbeskeden skal logges.

Synkronisering af opkald til C # log-metoden

Ups! Vi glemte at synkronisere opkaldene til de respektive Log () metoder. For at gøre dette skal vi bruge lås nøgleordet i Log () metode for hver af loggerklasserne og inkorporere den relevante kode til at synkronisere demLog () metoder. Henvis til LogBase klasse angivet nedenfor. Vi har indarbejdet et beskyttet medlem, der vil blive brugt til at anvende låsen i Log () metode for hver af de afledte klasser. Her er de modificerede versioner af disse klasser.

offentlig abstrakt klasse LogBase

    {

beskyttet readonly objekt lockObj = nyt objekt ();

offentlig abstrakt ugyldig Log (strengbesked);

    }

offentlig klasse FileLogger: LogBase

    {

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

offentlig tilsidesættelse ugyldig log (strengbesked)

        {

lås (lockObj)

            {

ved hjælp af (StreamWriter streamWriter = ny StreamWriter (filePath))

                {

streamWriter.WriteLine (besked);

streamWriter.Close ();

                }

            }

        }

    }

offentlig klasse EventLogger: LogBase

    {

offentlig tilsidesættelse ugyldig log (strengbesked)

        {

lås (lockObj)

            {

EventLog m_EventLog = ny EventLog (“”);

m_EventLog.Source;

m_EventLog.WriteEntry (besked);

            }

        }

    }

offentlig klasse DBLogger: LogBase

    {

streng connectionString = string.Empty;

offentlig tilsidesættelse ugyldig log (strengbesked)

        {

lås (lockObj)

            {

// Kode for at logge data i databasen

            }

        }

    }

Du kan nu ringe til Log () metode til LogHelper klasse og videregive logmålet og tekstbeskeden til at logge som parametre.

klasse Program

    {

statisk ugyldigt Main (streng [] args)

        {

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

        }

    }

Hvis du nogensinde har brug for at logge tekstbeskeden til et andet logmål, skal du blot videregive det relevante logmål som en parameter til Log () metode til LogHelper klasse.

Der er mange måder, du kan forbedre denne logningsramme på. Du kunne implementere asynkroni og en kø, så når et stort antal meddelelser ankommer, kan loggeren behandle disse meddelelser asynkront uden at skulle blokere den aktuelle tråd. Det kan også være en god idé at implementere kritiske niveauer for beskeder, såsom informationsmeddelelser, advarselsmeddelelser, fejlmeddelelser osv.