我心中的核心组件(可插拔的AOP)~第一回 日志记录组件之自主的Vlog

回到目录

对于.net环境而言,日志的开源组件有很多,像Nlog,log4net等等,而我今天要介绍的是我的日志组件VLog,呵呵,事实上实现原理与作用都大同小异。

作用:记录程序运行中的相关信息

特点:提供了消息日志,错误日志,调试日志,警告日志,崩溃日志等等

优势:提供了多种日志实现的方式,如SQL数据库,XML文本,WIN日志等等

配置:它可以通过配置文件进行设置,提供了日志级别和记录方式等参数

说明:VLog项目层次分明,一个接口,一个基类,5个实现的功能类,一切都是那么自然,下面看一下结构图:

一个接口:

 1 namespace VLog

 2 {

 3     /// <summary>

 4     /// 日志操作规范

 5     /// </summary>

 6     public interface IVLog

 7     {

 8         /// <summary>

 9         /// 调试型日志

10         /// </summary>

11         /// <param name="msg"></param>

12         void DebugLog(string msg);

13         /// <summary>

14         /// 信息型日志

15         /// </summary>

16         /// <param name="msg"></param>

17         void InfoLog(string msg);

18         /// <summary>

19         /// 警告型日志

20         /// </summary>

21         /// <param name="msg"></param>

22         void WarnLog(string msg);

23         /// <summary>

24         /// 错误型日志

25         /// </summary>

26         /// <param name="msg"></param>

27         void ErrorLog(string msg);

28         /// <summary>

29         /// 系统崩溃型日志

30         /// </summary>

31         /// <param name="msg"></param>

32         void FatalLog(string msg);

33     }

34 }

一个基类:

  1 namespace VLog

  2 {

  3     /// <summary>

  4     /// VLog 基类

  5     /// </summary>

  6     public abstract class VLogBase : IVLog

  7     {

  8         #region Protected Properties

  9         /// <summary>

 10         /// 获取执行路径

 11         /// </summary>

 12         /// <returns>返回 执行路径</returns>

 13         protected string GetSenders()

 14         {

 15             StringBuilder sb = new StringBuilder();

 16             StackFrame[] frames = new StackTrace(true).GetFrames();

 17             for (int index = 2; index < frames.Length; index++)

 18             {

 19                 if (frames[index].GetMethod().ReflectedType == null)

 20                 {

 21                     sb.AppendFormat("[systemfuntion:{0}]->", frames[index].GetMethod().Name);

 22                 }

 23                 else

 24                 {

 25                     sb.AppendFormat("[{0}]->", frames[index].GetMethod().ReflectedType.Name);

 26                 }

 27             }

 28             //return sb.ToString(0, sb.Length - 2);

 29             return string.Empty;

 30         }

 31 

 32         /// <summary>

 33         /// 得到当现异常的URL

 34         /// 子类可以根据自己的逻辑去复写本属性

 35         /// </summary>

 36         protected virtual string RequestReffer { get { return HttpContext.Current.Request.Url.AbsoluteUri; } }

 37 

 38         /// <summary>

 39         /// 得到当前异常URL的请求方式(POST,GET或HEAD)

 40         /// 子类可以根据自己的逻辑去复写本属性

 41         /// </summary>

 42         protected virtual string HttpMethod { get { return HttpContext.Current.Request.HttpMethod; } }

 43 

 44         /// <summary>

 45         /// 写日志地址 或是 DBConnectionStr

 46         /// </summary>

 47         protected string Path { get; set; }

 48         #endregion

 49 

 50         #region Protected Methods

 51         /// <summary>

 52         /// 写日志,子类必须去实现这个方法

 53         /// </summary>

 54         /// <param name="text">内容</param>

 55         /// <returns>返回是否成功</returns>

 56         protected abstract bool Write(VLogEntity entity);

 57         #endregion

 58 

 59         #region Delegates & Events

 60         /// <summary>

 61         /// 日志相关委托

 62         /// </summary>

 63         public delegate void VLogEventHandler(object sender, VLogsEventArgs e);

 64 

 65         /// <summary>

 66         /// 添加日志事件

 67         /// </summary>

 68         public static event VLogEventHandler AddVLog;

 69 

 70         /// <summary>

 71         /// 触发写日志事件

 72         /// </summary>

 73         /// <param name="entity"></param>

 74         public void OnAddVLog(VLogEntity entity)

 75         {

 76             try

 77             {

 78                 if (AddVLog != null)

 79                 {

 80                     AddVLog(this, new VLogsEventArgs(entity));

 81                 }

 82             }

 83             catch (Exception)

 84             {

 85                 throw;

 86             }

 87         }

 88         #endregion

 89 

 90         #region Private Fields

 91         static int configLevel = Convert.ToInt32(ConfigurationManager.AppSettings["VLogLevel"]);

 92 

 93         #endregion

 94 

 95         #region IVLog 成员

 96 

 97         public virtual void DebugLog(string msg)

 98         {

 99             if (configLevel >= (int)VLog.VLogLevel.Debug)

100                 this.Write(new VLogEntity { ExceptionID = Guid.NewGuid().ToString(), FullInfo = msg, Level = VLogLevel.Debug });

101         }

102 

103         public virtual void InfoLog(string msg)

104         {

105             if (configLevel >= (int)VLog.VLogLevel.Info)

106                 this.Write(new VLogEntity { ExceptionID = Guid.NewGuid().ToString(), FullInfo = msg, Level = VLogLevel.Info });

107         }

108 

109         public virtual void WarnLog(string msg)

110         {

111             if (configLevel >= (int)VLog.VLogLevel.Warn)

112                 this.Write(new VLogEntity { ExceptionID = Guid.NewGuid().ToString(), FullInfo = msg, Level = VLogLevel.Warn });

113         }

114 

115         public virtual void ErrorLog(string msg)

116         {

117             if (configLevel >= (int)VLog.VLogLevel.Error)

118                 this.Write(new VLogEntity { ExceptionID = Guid.NewGuid().ToString(), FullInfo = msg, Level = VLogLevel.Error });

119         }

120 

121         public void FatalLog(string msg)

122         {

123             if (configLevel >= (int)VLog.VLogLevel.Fatal)

124                 this.Write(new VLogEntity { ExceptionID = Guid.NewGuid().ToString(), FullInfo = msg, Level = VLogLevel.Fatal });

125         }

126 

127         #endregion

128 

129     }

130 }

一个生产日志的工厂:

 1 namespace VLog

 2 {

 3     /// <summary>

 4     /// 日志生产工厂

 5     /// </summary>

 6     public class VLogFactory

 7     {

 8         /// <summary>

 9         /// 创建日志对象

10         /// </summary>

11         /// <returns></returns>

12         public static VLogBase CreateVLog()

13         {

14             if (ConfigurationManager.AppSettings["VLog"] == null)

15                 return new VLog.NullVLog();

16             return (VLogBase)System.Reflection.Assembly.Load("VLog").CreateInstance("VLog." 

17                 + ConfigurationManager.AppSettings["VLog"]);

18         }

19     }

20 }

五种实现日志的对象

 1  /// <summary>

 2     /// 空日志

 3     /// </summary>

 4     public class NullVLog : VLogBase

 5     {

 6         protected override bool Write(VLogEntity entity)

 7         {

 8             return true;

 9         }

10     }
 1     /// <summary>

 2     /// SQL数据库 日志 

 3     /// </summary>

 4     public class SqlVLog : VLogBase

 5     {

 6         public SqlVLog()

 7         {

 8             this.Path = LogCommons.GetPath(PathType.DataBase);

 9         }

10 

11         /// <summary>

12         /// 写日志

13         /// </summary>

14         /// <param name="text"></param>

15         /// <returns></returns>

16         protected override bool Write(VLogEntity entity)

17         {

18 

19             using (SqlConnection sqlconn = new SqlConnection(this.Path))

20             {

21                 using (SqlCommand sqlcomm = new SqlCommand(

22                     "INSERT INTO [Web_ExceptionLog]([ExceptionID],[FullInfo],[Senders],[OccurTime],[HttpMethod],[Level]) VALUES (@ExceptionID,@FullInfo,@Senders,@OccurTime,@HttpMethod,@Level);"

23                     , sqlconn))

24                 {

25                     SqlParameter parameter = new SqlParameter("@ExceptionID", SqlDbType.VarChar, 36);

26                     parameter.Value = entity.ExceptionID;

27                     sqlcomm.Parameters.Add(parameter);

28 

29                     parameter = new SqlParameter("@FullInfo", SqlDbType.NText);

30                     parameter.Value = string.Format(@"<p>{0}</p>"

31                                          , entity.FullInfo

32                                        );

33                     sqlcomm.Parameters.Add(parameter);

34 

35                     parameter = new SqlParameter("@OccurTime", SqlDbType.DateTime, 4);

36                     parameter.Value = DateTime.Now;

37                     sqlcomm.Parameters.Add(parameter);

38 

39                     parameter = new SqlParameter("@Senders", SqlDbType.VarChar, 2000);

40                     parameter.Value = base.RequestReffer;

41                     sqlcomm.Parameters.Add(parameter);

42 

43                     parameter = new SqlParameter("@HttpMethod", SqlDbType.VarChar, 50);

44                     parameter.Value = base.HttpMethod;

45                     sqlcomm.Parameters.Add(parameter);

46 

47                     parameter = new SqlParameter("@Level", SqlDbType.Int);

48                     parameter.Value = entity.Level;

49                     sqlcomm.Parameters.Add(parameter);

50 

51                     sqlconn.Open();

52                     sqlcomm.ExecuteNonQuery();

53                     sqlconn.Close();

54                 }

55             }

56             OnAddVLog(entity); //触发写日志事件,外部订阅这个事件的对象将被执行

57             return true;

58         }

59 

60 

61     }
 1 namespace VLog

 2 {

 3     /// <summary>

 4     /// txt 日志

 5     /// </summary>

 6     public class TxtVLog : VLogBase

 7     {

 8         public TxtVLog()

 9         {

10             this.Path = LogCommons.GetPath(PathType.Txt);

11         }

12 

13         protected override bool Write(VLogEntity entity)

14         {

15             string text = string.Format(@"

16 Senders:    {0}

17 Content:    {1}

18 Date:       {2}

19 Level:      {3}

20 ", base.GetSenders()

21                   , entity.FullInfo

22                   , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")

23                   , entity.Level

24                   );

25 

26             File.AppendAllText(this.Path, text, Encoding.UTF8);

27 

28             return true;

29         }

30     }

31 }
 1 namespace VLog

 2 {

 3     /// <summary>

 4     /// windows 日志

 5     /// </summary>

 6     public class WindowsEventVLog : VLogBase

 7     {

 8         public WindowsEventVLog()

 9         {

10             this.Path = LogCommons.GetPath(PathType.WindowsEvent);

11         }

12 

13         protected override bool Write(VLogEntity entity)

14         {

15             string text = string.Format(@"

16 Senders:    {0}

17 Content:    {1}

18 Date:       {2}

19 Level:      {3}

20 ", base.GetSenders()

21                  , entity.FullInfo

22                  , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")

23                  , entity.Level

24                  );

25             System.Diagnostics.EventLog.WriteEntry(this.Path, text, System.Diagnostics.EventLogEntryType.Error);

26             return true;

27         }

28     }

29 }
 1 namespace VLog

 2 {

 3     /// <summary>

 4     /// XML 日志

 5     /// </summary>

 6     public class XmlVLog : VLogBase

 7     {

 8 

 9         public XmlDocument xmlDocument = null;

10 

11         public XmlVLog()

12         {

13             this.Path = LogCommons.GetPath(PathType.Xml);

14             if (!File.Exists(this.Path))

15             {

16                 ReCreate(this.Path);

17             }

18             this.xmlDocument = new XmlDocument();

19             this.xmlDocument.Load(this.Path);

20         }

21 

22         static void ReCreate(string path)

23         {

24             XmlDocument xmlDocument = new XmlDocument();

25             XmlDeclaration xmldecl = xmlDocument.CreateXmlDeclaration("1.0", "utf-8", null);

26             xmlDocument.AppendChild(xmldecl);

27             XmlElement ele = xmlDocument.CreateElement("root");

28             xmlDocument.AppendChild(ele);

29             xmlDocument.Save(path);

30         }

31 

32         protected override bool Write(VLogEntity entity)

33         {

34             XmlElement ele = this.xmlDocument.CreateElement("item");

35             ele.InnerXml = string.Format(

36                                         @"<Senders>{0}</Senders>

37                                         <Content>{1}</Content>

38                                         <Date>{2}</Date>

39                                         <Level>{3}</Level>

40                                         "               , base.GetSenders()

41                                                         , entity.FullInfo

42                                                         , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.ffff")

43                                                         , entity.Level

44               );

45             this.xmlDocument.DocumentElement.AppendChild(ele);

46             xmlDocument.Save(this.Path);

47             return true;

48         }

49     }

50 }

最后在配置文件里再进行设置就OK了,呵呵!

 回到目录

 

你可能感兴趣的:(AOP)