译文链接: https://www.infoworld.com/art...

在你的 .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 等等。

更多高质量干货:参见我的 GitHub: dotnetfly