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:   

 image

这个时候的错误信息如何捕捉呢?需要到全局应用程序类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进行记录到的错误,通过这个错误我们能更好的修改程序的未知错误.

image

 

生成的邮件信息如下

1:普通人为try catch的错误

image

2:未知的错误,通过Application_Error记录的错误(当然了,如果这个地方能直接把邮箱的标题分为普通和未知就更好了,需要额外再详细了解一下log4net,我暂时还没有弄出来)

image

生成的文本信息如下

image

image

 

最后,上log4net在web.config里面的配置代码 (一般是在  </configSections> 结束的下面一行)

 

<log4net>
        <!--这里是第一个附加器   RollingFileAppender  滚动日志文件附加器-->
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">

            <file value="Log\\"/>
            <!--日志文件夹及文件名开头,文件名后面加上.log后缀,必须使用转义字符-->
            <DatePattern value="yyyyMM\\yyyy-MM-dd&quot;.log&quot;"/>
            <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="发送的目标邮箱 例如 to@qq.com" />
            <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>
posted @ 2012-12-18 12:29  梨花驿路  阅读(698)  评论(0编辑  收藏  举报