Jak zaimplementować prosty rejestrator w C #

Często będziesz chciał rejestrować zdarzenia lub błędy występujące w aplikacji .Net. Aby to zrobić, możesz skorzystać z jednej z wielu popularnych dostępnych platform rejestrowania lub zaprojektować i opracować własną strukturę rejestrowania. W tym artykule zobaczymy, jak z łatwością możemy zaprojektować i opracować własną strukturę rejestrowania, a także przejść przez kroki tworzenia prostego rejestratora w języku C #.

Po pierwsze, musisz zrozumieć cele dziennika - różne miejsca, w których dane mogą być rejestrowane. Załóżmy, że będziemy logować dane do plików płaskich, bazy danych i dziennika zdarzeń. Poniższe wyliczenie definiuje cele dziennika, których użylibyśmy w tej prostej strukturze.

public enum LogTarget

    {

        File, Database, EventLog

    }

Klasy rejestratora C #

Następnym krokiem jest zaprojektowanie i wdrożenie zajęć. Będziemy korzystać z trzech różnych klas, a mianowicie, FileLogger, DBLogger, i EventLogger-to danych dziennika do pliku, bazy danych i dziennika zdarzeń odpowiednio. Wszystkie te klasy powinny dziedziczyć abstrakcyjną klasę bazową o nazwie LogBase. Oto jak organizowane są te zajęcia.

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

        }

    }                                

Opuściłem DBLoggerzajęcia niekompletne. Tobie pozostawiam wpisanie odpowiedniego kodu w celu zalogowania wiadomości do bazy danych.

Jak widać, wszystkie trzy klasy - FileLogger, EventLoggeri DBLogger- rozszerzenie abstrakcyjną klasę bazową LogBase. Abstrakcyjna klasa bazowa LogBasedeklaruje abstrakcyjną metodę o nazwie Log(). Log() Sposób przyjmuje ciągu jako parametru; ten ciąg jest tym, co zostanie zarejestrowane w pliku, bazie danych lub dzienniku zdarzeń. 

Klasa C # LogHelper

Teraz utwórzmy klasę pomocniczą, której można użyć do wywołania odpowiedniego programu rejestrującego na podstawie przekazanego parametru. Ta klasa pomocnicza będzie używana do uproszczenia wywołań Log()metody w każdej z klas programu rejestrującego. Poniższy fragment kodu ilustruje tę klasę pomocniczą.

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;

            }

        }

    }

Log() Sposób LogHelperklasy przyjmuje sznurek i wystąpienie LogTargetwyliczenie jako parametry. Następnie używa switch: casekonstrukcji do określenia miejsca docelowego, w którym wiadomość tekstowa zostanie zarejestrowana.

Synchronizowanie wywołań z metodą C # Log

Ups! Zapomnieliśmy zsynchronizować wywołania do odpowiednich Log()metod. Aby to zrobić, musimy użyć słowa kluczowego lock w Log()metodzie każdej z klas rejestratora i włączyć odpowiedni kod do synchronizacji tych  Log()metod. Zapoznaj się z LogBaseklasą podaną poniżej. Dodaliśmy chroniony element członkowski, który będzie używany do stosowania blokady w Log()metodzie każdej z klas pochodnych. Oto zmodyfikowane wersje tych klas.

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

            }

        }

    }

Możesz teraz wywołać Log()metodę LogHelperklasy i przekazać cel dziennika i wiadomość tekstową do logowania jako parametry.

class Program

    {

        static void Main(string[] args)

        {

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

        }

    }

Jeśli kiedykolwiek zajdzie potrzeba zarejestrowania wiadomości tekstowej w innym miejscu docelowym dziennika, po prostu przekażesz odpowiedni cel dziennika jako parametr do Log()metody LogHelperklasy.

Istnieje wiele sposobów ulepszenia tej struktury rejestrowania. Można zaimplementować asynchronię i kolejkę, aby w przypadku nadejścia dużej liczby komunikatów rejestrator mógł przetwarzać te komunikaty asynchronicznie, bez konieczności blokowania bieżącego wątku. Możesz również zaimplementować poziomy krytyczności wiadomości, takie jak komunikaty informacyjne, komunikaty ostrzegawcze, komunikaty o błędach i tak dalej.