首頁>技術>

在你的 .NET 程式中經常會記錄一些日誌或者錯誤,為了實現這個功能,你可能會使用市面上那些現成的日誌框架(log4net,nlog ...),當然你也可以設計並開發一個自己的日誌框架,在這篇文章中,我將會帶你一起如何輕鬆愉快的建立一個自定義日誌框架,並且一步一步的構建這個簡單的 logger。

首先,你要知道什麼叫 log targets,從字面意思看就是你的日誌要輸送到哪裡?可以假定我們的日誌可以輸出到: 檔案,資料庫 或者 windows 日誌 中,下面我在 日誌框架 中定義一個列舉表示這三個輸出地。

    public enum LogTarget    {        File, Database, EventLog    }
構建 logger 類

接下來實現一下 logger 類,我準備定義三個類來表示這三個output,FileLogger, DBLogger, EventLog ,所有的這些類都需要繼承基類 LogBase,下面上一下程式碼展示一下這些類的繼承關係。

    public abstract class LogBase    {        public abstract void Log(string message);    }    public class FileLogger : LogBase     {        public string filePath = @”D:\IDGLog.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 ="IDGEventLog";            eventLog.WriteEntry(message);        }    } 

上面 DBLogger 的 Log 方法我故意沒有實現,你可以在學習完本文後自己來實現這一塊的邏輯,將日誌記錄到資料庫中。

正如你看到的,上面三個類:FileLogger,EventLogDBLogger 繼承了抽象類 LogBase,這個抽象類定義了一個抽象方法 Log(), 這個 Log() 方法中定義了一個 string 型別的引數,這個引數的內容將會被記錄到 file 或者 database 或者 windows event 中。

構建 LogHelper 類

現在我們一起來構建一個 LogHelper 類,這個類可以用簡單工廠模式,根據引數的不同建立不同的 XXXLogger 子類,用簡單工廠簡化我們呼叫其中各個子類的 Log() 方法,下面展示了具體程式碼:

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

LogHelper 類的 Log() 方法接收一個 string 引數和一個 LogTarget 列舉例項,然後使用 switch: case 結構去決定記錄日誌的 target 是哪一個。

Log 方法的同步呼叫

我去,我忘了使用同步機制對這些子類的 log() 方法的呼叫,現在趕緊同步一下,我可以使用 C# 中的 lock 關鍵詞 在 各個子類的 log 方法的合適地方使用,可以參考下面程式碼的 LogBase 類,我在這個類中定義了一個 protected 型別的 lockObj 物件,這個物件會被所有子類中的 Log 方法所使用,下面就是這個類的修改版本:

    public abstract class LogBase    {        protected readonly object lockObj = new object();        public abstract void Log(string message);    }    public class FileLogger : LogBase    {        public string filePath = @”D:\IDGLog.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 ="IDGEventLog";                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            }        }    }

現在你可以呼叫 LogHelper.Log 方法了,指定一個 LogTarget 列舉引數和一個需要記錄到日誌的文字,如下程式碼所示:

    class Program    {        static void Main(string[] args)        {            LogHelper.Log(LogTarget.File, “Hello”);        }    }

如果你需要切換日誌的記錄方式,實現起來很簡單,在 LogHelper.Log 方法中傳遞一個不同的 LogTarget 引數即可。

這個框架做的非常簡單,還有太多需要實現的功能去完善這個 logger framework,比如說,你可以加入 非同步 和 佇列,以便應對有大量的 message 被灌入,因為有了非同步,logger 在寫入日誌的時候不會被當前執行緒阻塞,同樣,你也可以實現一些 message 的級別,比如說 info,warning,error 等等。

13
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 如何使用 C# 擴充套件方法