最近根据业务需要,俺们老大要求我们了解一个c#的组件——Log4Net 这玩意儿从来没弄过,感觉挺深奥的,结果经过2天的研究,还算小有所成吧,基本思路已经清晰明了了,不过过程中遇到一些很奇葩的问题,和第一次使用该组件 有些想不通的问题,现在弄明白了,所以给大家一起分享一下。
首先说明一下,该博客内容 是在 http://blog.csdn.net/niuyongjie/article/details/5777625 这篇博客上延生过来的,主要的功劳还是 niuyongjie 这位博主,我只是在他的文章上进行改进和详细说明。自认为这位博主写的很不错,但是在关键的地方没有说的太明白,为了接下来的解释,在此就先称这位博主为“原博主”吧,温馨提示:在看本篇博客之前 请先看原博主的文章,这样你会更容易理解
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <configSections> 4 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> 5 </configSections> 6 <log4net> 7 <root> 8 <level value="All" /> 9 <appender-ref ref="AdoNetAppender"/> 10 </root> 11 <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"> 12 <bufferSize value="1" /> 13 <connectionType value="System.Data.SqlClient.SqlConnection,System.Data, Version=1.0.3300.0, Culture=neutral,PublicKeyToken=b77a5c561934e089" /> //在不出效果的时候千万不用担心这句话的含义是否有其他写法,至少在这里这样写不会出问题 14 <connectionString value="database=xp_bw2012;server=192.168.33.131;User ID=xxzx;Password=xxzx" /> //这句话 如果你操作过数据库,就很容易理解 不懂得话可以查询一下关于sql2008连接字符串的问题 16 <commandText value="insert into OperatorLog([login],[username],[operator],[System],[Type],[LogType],[Point],[Value],[Status],[dt]) values(@login,@username,@operator,@System,@Type,@LogType,@Point,@Value,@Status,@dt)"/> 19 <parameter> 20 <parameterName value="@login" /> 21 <dbType value="String" /> 22 <size value="20" /> 23 <layout type="WebApplication1.MyLayout, WebApplication1" > 24 <param name="ConversionPattern" value="%property{Login}"/> 25 </layout> 26 </parameter> 27 28 <parameter> 29 <parameterName value="@username" /> 30 <dbType value="String" /> 31 <size value="20" /> 32 <layout type="WebApplication1.MyLayout, WebApplication1" > 33 <param name="ConversionPattern" value="%property{UserName}"/> 34 </layout> 35 </parameter> 36 <parameter> 37 <parameterName value="@operator" /> 38 <dbType value="String" /> 39 <size value="200" /> 40 <layout type="WebApplication1.MyLayout, WebApplication1" > 41 <param name="ConversionPattern" value="%property{Operator}"/> 42 </layout> 43 </parameter> 44 <parameter> 45 <parameterName value="@System" /> 46 <dbType value="String" /> 47 <size value="50" /> 48 <layout type="WebApplication1.MyLayout, WebApplication1" > 49 <param name="ConversionPattern" value="%property{System}"/> 50 </layout> 51 </parameter> 52 <parameter> 53 <parameterName value="@Type" /> 54 <dbType value="String" /> 55 <size value="50" /> 56 <layout type="WebApplication1.MyLayout, WebApplication1" > 57 <param name="ConversionPattern" value="%property{Type}"/> 58 </layout> 59 </parameter> 60 <parameter> 61 <parameterName value="@LogType" /> 62 <dbType value="String" /> 63 <size value="50" /> 64 <layout type="WebApplication1.MyLayout, WebApplication1" > 65 <param name="ConversionPattern" value="%property{LogType}"/> 66 </layout> 67 </parameter> 68 <parameter> 69 <parameterName value="@Point" /> 70 <dbType value="String" /> 71 <size value="50" /> 72 <layout type="WebApplication1.MyLayout, WebApplication1" > 73 <param name="ConversionPattern" value="%property{Point}"/> 74 </layout> 75 </parameter> 76 <parameter> 77 <parameterName value="@Value" /> 78 <dbType value="String" /> 79 <size value="50" /> 80 <layout type="WebApplication1.MyLayout, WebApplication1" > 81 <param name="ConversionPattern" value="%property{Value}"/> 82 </layout> 83 </parameter> 84 85 <parameter> 86 <parameterName value="@Status" /> 87 <dbType value="String" /> 88 <size value="50" /> 89 <layout type="WebApplication1.MyLayout, WebApplication1" > 90 <param name="ConversionPattern" value="%property{Status}"/> 91 </layout> 92 </parameter> 93 <parameter> 94 <parameterName value="@dt" /> 95 <dbType value="DateTime" /> 96 <layout type="log4net.Layout.RawTimeStampLayout" /> 97 </parameter> 98 99 </appender> 100 </log4net> 101 <system.web> 102 <compilation debug="true"/> 103 </system.web> 104 </configuration>
如果您在看这篇博客的同时和原博主的博客对比 ,那么很容易发现 区别其实并不大,唯一的区别就是我们自定义的业务对象,我定义的业务对象 比他的业务对象字段更多,由此web.config配置文集的内容也就更长,其实配置文件的内容长短不是问题,问题是要搞清楚每个字段为何要这样配置,那我们先来看看我自定义的这个业务对象在数据库中的图片:每个字段的意思就不用弄清楚了,需要注意的是每个字段的数据类型,虽然我不知道原博主的业务对象是什么,但是根据配置文件配置的配置 大致能猜中,他的字段中没有除varchar类型以外的数据类型(纯属猜测),但是在我们得项目需求中,难免会遇到多数据类型,这怎么办呢?也许你第一时间会想到在配置文件中指定数据类型就是了涩,比如说我们数据库中Type这个字段是Int类型,那么在配置文件中 就应该将dbType的value设置为Int,而int类型没有长度所以就会删除size这个节点,如果你这样做那就错了,根据测试,我想问题就出在这个地方,配置文件中不能出现类型为DateTime和String类型以外的,即使是int类型你的解决办法也只有将这个字段看成是String类型并设置他的size为最接近数据的长度,你是不是会问,那么数据库中是int 我又怎么来区分他是什么类型呢?这就是我们实体类发挥作用的时候了,实体类和数据库是对应关系,就解决了我们在给 实体类的对象的属性赋值时不知道什么类型的问题了,至此指定数据类型的问题就解决了,我们继续来看一段两段代码:
1 我的代码: 2 <parameter> 3 <parameterName value="@login" /> 4 <dbType value="String" /> 5 <size value="20" /> 6 <layout type="WebApplication1.MyLayout, WebApplication1" > 7 <param name="ConversionPattern" value="%property{Login}"/> 8 </layout> 9 </parameter> 10 原博主的代码: 11 <parameter> 12 <parameterName value="@Reason" /> 13 <dbType value="String" /> 14 <size value="100" /> 15 <layout type="TestLogNiu.MyLayout, TestLogNiu" > 16 <param name="ConversionPattern" value="%property{Reason}"/> 17 </layout> 18 </parameter>
注意看layout节点这部分,tape中的含义,我在刚用的时候一直没搞清楚双引号里面的含义,后来经过测试才知道,这里的TestLogNiu指的事 项目名,看这个图片:,对照这个图片和我的代码,你会发现我的代码中WebApplication1指的是我的项目的名字,而WebApplication1.MyLayout 和后面的参数也就不用多说,你应该懂得他们之间的关系了(注意:这个地方很重要,如果没设置对,是出不到效果的。)而MyLayout类中的内容,可以参照原博主的代码,哪个是完整代码,唯一要修改的地方就是命名空间。这部分就算完了。
再来看看原博主的代码,有三种给属性绑定值得方式:
//提示:这三种方式的区别在于layout这个节点
//方式一:
1 <parameter> 2 <parameterName value="@LogTime" /> 3 <dbType value="DateTime" /> 4 <layout type="log4net.Layout.RawTimeStampLayout" /> 5 </parameter> 6 //方式二: 7 <parameter> 8 <parameterName value="@level" /> 9 <dbType value="String" /> 10 <size value="50" /> 11 <layout type="log4net.Layout.PatternLayout" value="%level" /> 12 </parameter> 13 //方式三 14 <parameter> 15 <parameterName value="@Reason" /> 16 <dbType value="String" /> 17 <size value="100" /> 18 <layout type="TestLogNiu.MyLayout, TestLogNiu" > 19 <param name="ConversionPattern" value="%property{Reason}"/> 20 </layout> 21 </parameter>
接下来依次解释这三种方式的区别:
方式一:是给日期类型的属性赋值。
方式二:使用Log4Net 为layout 设置布局样式的方式:这里的value="%level" 的含义是 日志等级
value中可以有:(“%d %t %p %l %m %n”)以下分开解释:
%d输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy-MM-dd HH:mm:ss},输出类似:2005-7-19 17:49:27,刚好适合插入SQLServer;
%t 产生该日志事件的线程名;
%p 日志的log_level,如DEBUG、WARN或者INFO;
%c 输出所属的类目,通常就是所在类的全名,如“iNotes.Default”;
%m 日志的内容;
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。如write2database.main(write2database.java:33);
%n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n”
方式三:很明显是为我们自定义业务对象的属性进行赋值,如果你观察力够细致你会发现我基本上全部都用的第三种方式((*^__^*) 嘻嘻……)
好了,这部分告一段落。再来看看调用和将错误信息写入数据库
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 8 namespace WebApplication1 9 { 10 public partial class Global : System.Web.UI.Page 11 { 12 protected void Page_Load(object sender, EventArgs e) 13 { 24 //数据库记录方式 25 log4net.Config.XmlConfigurator.Configure(); 26 log4net.ILog log = log4net.LogManager.GetLogger(typeof(Global)); 28 OperatorLog_model model = new OperatorLog_model(); 29 model.Login = "Login"; 30 model.UserName = "UserName"; 31 model.Operator = "operator"; 32 model.System = "System"; 33 model.Type = 1; 34 model.LogType = 1; 35 model.Point = "Point"; 36 model.Value = 1; 37 model.Status = 1; 38 model.dt = DateTime.Now; 39 log.Info(model);41 } 42 } 43 }
这里只是调用Log4Net写入日志的方式之一,你可以使用自己的方式进行操作,原博主使用的是Program入口类,我一直没弄明白,他是怎么使用入口类调用的web.config,这是我没弄明白的地方,如果读者知道知道,麻烦给我留个言哈,在此先谢过!
我这里是使用的aspx页面的 页面加载事件,需要注意的是:log4net.ILog log = log4net.LogManager.GetLogger(typeof(Global)); 这句话中typeof()这部分,我也是没弄明白是什么含义,原博主使用的是Program,参照他的思路,我就填的 我这个页面的类名,呵呵 效果不影响所以我就没深究。好了大功告成,如果还有什么疑问,麻烦给我留言,我会尽我所能帮助大家!