log4net 高级运用之:在页面级捕获可预见的异常,在全局应用程序类Global.asax中捕获未知的异常(更新log4net的样式和配置)...
例如,我们在页面,知道一个地方可能会有异常,于是我们做如下处理。
1: int a = 0;
2:
3: try
4: {
5: int b = 3 / a;
6: }
7: catch (Exception ex)
8: {
9:
10: LogManager.GetLogger(typeof(_Default)).Error("发生在" + HttpContext.Current.Request.Url +" 的错误:"+ex.Message+"\r\n错误定位:"+ex.StackTrace, HttpContext.Current.Error);
11: //或者是
12: //ILog logger = LogManager.GetLogger(typeof (_Default));
13: //logger.Error(ex.Message);
14: }
15:
然后,这样可以保证,页面不会报错停止下来,而且错误信息也捕捉到了日志/邮箱/数据库里面
但是有些时候,网站的错误是我们不可预见的,没有发现到的,例如,我新建一个集合,再没有赋值的情况下就开始输出里面的值
1: ListP = new List<Person> { };
2: Response.Write(ListP[0].Name);
3:
这个时候的错误信息如何捕捉呢?需要到全局应用程序类Global.asax去设置
1: private static readonly ILog Logger = LogManager.GetLogger(typeof (Global));
2: protected void Application_Start(object sender, EventArgs e)
3: {
4: log4net.Config.XmlConfigurator.Configure();
5: }
6: protected void Application_Error(object sender, EventArgs e)
7: {
8: Logger.Error("程序发生未捕获的异常\t\t\t" + HttpContext.Current.Error.Message, HttpContext.Current.Error);
9: }
10:
这样,就既能保证,我们可以预见到的错误被捕获,那些我们不可预料到的错误,也记录下来了。(但是如果是不可预料到的错误,由于我们没有 try catch来捕捉,所以会导致页面报错,并停止运行,但是错误会被记录下来)
最后放一个修改版的 log4net的web.config里面的设置(主要是对生成的 文本日志/邮箱日志/数据库日志)进行了优化,尤其是数据库日志里面,不仅仅可以一眼看出哪些是我们预知捕获的,而且还能看到哪些是不可预知记录的错误(也就是通过Application_Error记录下的错误)
生成的数据库信息如下,Message里面包括了 是哪个aspx页面/cs页面报错,包括错误信息以及行号
Exception字段,如果不为空,则表示是未知的错误记录,由Application_Error进行记录到的错误,通过这个错误我们能更好的修改程序的未知错误.
生成的邮件信息如下
1:普通人为try catch的错误
2:未知的错误,通过Application_Error记录的错误(当然了,如果这个地方能直接把邮箱的标题分为普通和未知就更好了,需要额外再详细了解一下log4net,我暂时还没有弄出来)
生成的文本信息如下
最后,上log4net在web.config里面的配置代码 (一般是在 </configSections> 结束的下面一行)
<log4net> <!--这里是第一个附加器 RollingFileAppender 滚动日志文件附加器--> <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"> <file value="Log\\"/> <!--日志文件夹及文件名开头,文件名后面加上.log后缀,必须使用转义字符--> <DatePattern value="yyyyMM\\yyyy-MM-dd".log""/> <appendToFile value="true"/> <!--最多产生的日志文件数,超过则只保留最新的n个。设定值value="-1"为不限文件数--> <maxSizeRollBackups value="10"/> <!--日志文件的最大大小--> <maximumFileSize value="1024KB"/> <staticLogFileName value="false"/> <!--允许多个进程可以写入同一个文件--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%n%n=============================================记录时间:%date===========================================%n%n 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - %n错误描述:%message%newline%n%n%exception% %n =============================================End===========================================%n" /> </layout> </appender> <!--这里是第二个附加器 用来发送邮件--> <appender name="SmtpAppender" type="log4net.Appender.SmtpAppender"> <authentication value="Basic" />
<to value="发送的目标邮箱 例如 [email protected]" /> <from value="从哪里发出的邮箱 例如 from123456@qq.com" /> <username value="邮箱账号 例如 from123456" /> <password value="邮箱密码" />
<subject value="网站报错" /> <smtpHost value="smtp.qq.com" /> <bufferSize value="512" /> <lossy value="true" /> <evaluator type="log4net.Core.LevelEvaluator"> <threshold value="Error"/> </evaluator> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%n记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - %n错误描述:%message%newline%n%exception% %n" /> </layout> </appender> <!--这里是第三个附加器,用来发送到 Mssql数据库--> <appender name="AdoNetAppender_MsSql2005" type="log4net.Appender.AdoNetAppender"> <bufferSize value="1" /> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <connectionString value="server=.\SQL2005;database=eftest;integrated security=false;persist security info=True;UID=sa;PWD=tiantang" /> <!--这里可以是参数化的查询语句,也可以是存储过程--> <commandText value="INSERT INTO Log ([LogDate],[Thread],[LogLevel],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /> <parameter> <parameterName value="@log_date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@log_level" /> <dbType value="String" /> <size value="50" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <parameter> <parameterName value="@exception" /> <dbType value="String" /> <size value="2000" /> <layout type="log4net.Layout.ExceptionLayout" /> </parameter> </appender> <!--这里是第四个附加器,用来发送日志到 Mysql数据库,记得要在项目中引用 MySql.Data.dll--> <appender name="AdoNetAppender_MySql" type="log4net.Appender.AdoNetAppender"> <!--千万注意这里的name不能为AdoNetAppender,或者说是与后面Type的类型相同,就因为这个问题,我花了少功夫找问题.最后终于在某人blog中看到这样的提示.改名后就OK了.--> <bufferSize value="1"/> <param name="ConnectionType" value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" /> <param name="ConnectionString" value="database=edt_date;Password=123456;uid=root;server=localhost;Port=3306"/> <param name="CommandText" value="insert into `log`(LogDate,Thread,LogLevel,Logger,Message,Exception) values(@log_date, @thread , @log_level, @logger, @message,@exception)" /> <parameter> <parameterName value="@log_date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@log_level" /> <dbType value="String" /> <size value="50" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <parameter> <parameterName value="@exception" /> <dbType value="String" /> <size value="2000" /> <layout type="log4net.Layout.ExceptionLayout" /> </parameter> </appender> <root> <level value="Error"/> <!--如果这里还写了 DEBUG,那么凡是你DEBUG的时候的信息,都会记录下来--> <!--<level value="DEBUG"/>--> <!--定义日志的输出媒介,这里的ref就是根据上面你有多少个appender附加器。--> <appender-ref ref="RollingLogFileAppender"/> <appender-ref ref="SmtpAppender"/> <appender-ref ref="AdoNetAppender_MsSql2005"/> <appender-ref ref="AdoNetAppender_MySql"/> </root> </log4net>
转载于:https://www.cnblogs.com/joeylee/archive/2012/12/18/2823059.html