我心中的核心组件(可插拔的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)~第一回 日志记录组件之自主的Vlog,如需转载请自行联系原博主。

时间: 2024-08-01 10:13:11

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

我心中的核心组件(可插拔的AOP)~第三回 日志记录组件之log4net

在项目中有统一的日志是很必要的,之前自己写过vlog项目,这个项目与现在比较流行的log4net很像,用起来也很方便,今天主要说一下log4net这个日志工具,这使用vs2012测试的,使用nuget把log4net组件添加到项目中,如图: 然后在项目里为log4net建立一个配置文件,可以命名为log4net.config,一般代码如下: <log4net> <logger name="loginfo"> <level value="INFO&

我心中的核心组件(可插拔的AOP)~大话开篇及目录

核心组件 我心中的核心组件,核心组件就是我认为在项目中比较常用的功能,如日志,异常处理,消息,邮件,队列服务,调度,缓存,持久化,分布式文件存储,NoSQL存储,IoC容器,方法拦截等等. 对于以上内容可以说即是一个大餐,又是一个挑战,就让我带着大家去迎接这份挑战吧,呵呵! 可插拔的AOP AOP即面向切面的编程,是指将一个公用的与领域无关的组件抽象出来,方便在各个项目中使用.在微软很多项目中,基本都会有这种组件,它们叫它frameworks,或者叫core,从字面上看,就是核心的东西,而这些核

我心中的核心组件(可插拔的AOP)~第十五回 我的日志组件Logger.Core(策略,模版方法,工厂,单例等模式的使用)

之前的讲过两篇关于日志组件的文章,分别是<第一回  日志记录组件之自主的Vlog>和<第三回  日志记录组件之log4net>,而今天主要说一下我自己开发的另一种日志组件Logger.Core,它也属于面试AOP(横切关注点)的一部分,这个组件对于一些想学习设计模式的同学来说,无疑是一个大餐!Logger.Core项目里内含了策略模式,模版方法模式,工厂模式和单例模式,可以说,最常用的模式都用到了,而它们在这个项目里都起到了什么作用,什么时候用到它们呢,这些答案相信在看完我的文章之

我心中的核心组件(可插拔的AOP)~第二回 缓存拦截器

AOP面向切面的编程,也称面向方面的编程,我更青睐于前面的叫法,将一个大系统切成多个独立的部分,而这个独立的部分又可以方便的插拔在其它领域的系统之中,这种编程的方式我们叫它面向切面,而这些独立的部分,我们很早之前叫它部件,在SOA里,它叫做服务,而我认为叫它模块更加贴切,确实,这些与领域无关的东西,是像是一个个的功能模块. 之前讲过一个日志组件,有兴趣的同学可以查看:第一回 日志记录组件 今天主要说一下缓存组件,就是缓存模块,这些模块可以很方便的为每个方法添加缓存机制,事实上是在方法体执行之前,

我心中的核心组件(可插拔的AOP)~调度组件quartz.net

quartz.net是一个任务调度组件,它可以灵活的设置你的调试方式,按时间,按日期,按周期都可以很容易的实现,quartz不仅可以用在web中,而且还可以部署在winform,winservice上,下面我们就来作一个简单的调试服务,我们以WEB环境为例,WEB端采用比较流行的MVC3实现. 首先需要引入三个组件DLL C5.DLL,log4net.DLL,Quartz.DLL,Common.Logging 对于WEB项目来说,调度的注入后我们可以放在global.asax里,它可以使我们的调

我心中的核心组件(可插拔的AOP)~第四回 异常拦截器

之前说过有关拦截器的文章,第二回  缓存拦截器,事实上,在那讲里说的最多是AOP和缓存组件,对于拦截的概念并没有详细的说明,这一讲,不说AOP,主要说一下拦截器,拦截器Interception,主要是在方法执行前或者执行后,动态添加一些行为,而这个行为主要包含缓存,日志,异常处理及你可以想到的所有的一切,呵呵. 这一讲是异常拦截器,它的主要意义在于,当你的一个方法被执行时,你可以通过配置文件去管理这个方法执行前与执行后是否附加统一异常处理行为. 拦截器组件我们还是用Unity.Intercept

我心中的核心组件(可插拔的AOP)~第十三回 实现AOP的拦截组件Unity.Interception

说在前 本节主要说一下Unity家族里的拦截组件,对于方法拦截有很多组件提供,基本上每个Ioc组件都有对它的实现,如autofac,它主要用在orchard项目里,而castle也有以拦截的体现,相关可以看我的Castle~实现IoC容器这篇文章,而今天主要说一个Unity里的方法拦截的实现,事实上本篇文章是对第二回 缓存拦截器的一个扩展和补充,对于unity这东西在微软的Nlayer项目里有所体现,它是基于DDD构架的,无论在架构选型还是技术选型上都很超前,也都结合了很大微软高手的心血,可读性

如何让移动硬盘插拔自如

  故障分析:我们在插拔移动硬盘的时候,当你使用之后, 需要在任务栏托盘区中的删除硬件图标将移动硬盘的图标删除掉.而经常会出现提示[现在无法停止通用卷设备.请稍候再停止该设备.]有时候会发现无法通过任务栏托盘区中的删除硬件图标将之删除掉,大部分人都会选择直接拔出来移动硬盘,而强行插拔又担心会损坏移动硬盘中的数据.如图所示: 故障解决: 一.xp系统操作步骤如下:在打开的 "系统属性"窗口中单击顶部的"硬件"标签,再单击其中的"设备管理器"按钮打开

stm32-STM32的JTAG下载器插拔后程序复位

问题描述 STM32的JTAG下载器插拔后程序复位 在用JTAG调试程序时,拔掉或者插上JTAG后,程序复位,有没有人遇到过此类情况,该怎么解决? 解决方案 http://www.51hei.com/mcu/1954.html