MVC使用Log4Net进行错误日志记录学习笔记4
在web应用运行过程中,我们难免会遇到程序运行异常,这个时候我们就应该将异常信息记录下来,以便开发人员和维护人员对异常原因进行还原,对异常原因进行修复。在asp.net平台中进行日志记录的组件也有很多,如log4net、commonlogging等,我们这里选用log4net进行异常日志的记录。
1. 捕获异常
在asp.net mvc中提供了一个全局的异常处理过滤器:handleerrorattribute,可以通过该过滤器捕获异常信息。
我们在models文件夹下新建类型log4exceptionattribute,继承handleerrorattribute类,同时重写onexception方法来捕获异常数据:
using system.web.mvc; namespace pms.webapp.models { public class log4exceptionattribute:handleerrorattribute { /// <summary> /// 重写onexception方法来捕获异常数据 /// </summary> /// <param name="filtercontext"></param> public override void onexception(exceptioncontext filtercontext) { base.onexception(filtercontext); //捕获当前异常数据 var ex = filtercontext.exception; } } }
新建过滤器后我们还需要在global文件中调用的registerglobalfilters方法中完成自己定义异常处理过滤的注册。
using system.web.mvc; using pms.webapp.models; namespace pms.webapp { public class filterconfig { public static void registerglobalfilters(globalfiltercollection filters) { //filters.add(new handleerrorattribute()); filters.add(new log4exceptionattribute()); } } }
2. 考虑到多用户并发操作时可能产生的问题,我们需要新建一个队列来进行异常信息的暂存,同时开辟一个线程专门对队列中的异常信息进行处理。
在log4exceptionattribute类中新建一个静态的异常类型的队列,在发生异常后,程序自动触发onexception方法,方法中将当前的异常信息入队后,跳转到错误页面。
using system; using system.collections.generic; using system.web.mvc; namespace pms.webapp.models { public class log4exceptionattribute:handleerrorattribute { public static queue<exception> exceptions=new queue<exception>(); /// <summary> /// 重写onexception方法来捕获异常数据 /// </summary> /// <param name="filtercontext"></param> public override void onexception(exceptioncontext filtercontext) { base.onexception(filtercontext); //捕获当前异常数据 var ex = filtercontext.exception; //将异常数据入队 exceptions.enqueue(ex); //跳转到错误页面 filtercontext.httpcontext.response.redirect("/error.html"); } } }
log4net的配置是在应用程序配置文件中进行的,我们先在配置文件中进行log4net的配置。log4net需要配置的节点位置和springnet完全相同,首先需要在configsessions中新增子节点,然后在configuration节点中增加log4net节点完成具体配置。
<configuration> <configsections> <section name="entityframework" type="system.data.entity.internal.configfile.entityframeworksection, entityframework, version=6.0.0.0, culture=neutral, publickeytoken=b77a5c561934e089" requirepermission="false" /> <!-- for more information on entity framework configuration, visit http://go.microsoft.com/fwlink/?linkid=237468 --> <!--↓log4net配置↓--> <section name="log4net" type="log4net.config.log4netconfigurationsectionhandler, log4net"/> <!--↑log4net配置↑--> <!--↓spring.net配置↓--> <sectiongroup name="spring"> <section name="context" type="spring.context.support.mvccontexthandler, spring.web.mvc4"/> </sectiongroup> <!--↑spring.net配置↑--> </configsections> <!--↓spring.net配置↓--> <spring> <context> <resource uri="file://~/config/controllers.xml"/> <resource uri="file://~/config/services.xml"/> </context> </spring> <!--↑spring.net配置↑--> <!--↓log4net配置↓--> <log4net> <!-- off, fatal, error, warn, info, debug, all --> <!-- set root logger level to error and its appenders --> <root> <level value="all"/> <appender-ref ref="sysappender"/> </root> <!-- print only messages of level debug or above in the packages --> <logger name="weblogger"> <level value="debug"/> </logger> <appender name="sysappender" type="log4net.appender.rollingfileappender,log4net" > <param name="file" value="app_data/" /> <param name="appendtofile" value="true" /> <param name="rollingstyle" value="date" /> <param name="datepattern" value=""logs_"yyyymmdd".txt"" /> <param name="staticlogfilename" value="false" /> <layout type="log4net.layout.patternlayout,log4net"> <param name="conversionpattern" value="%d [%t] %-5p %c - %m%n" /> <param name="header" value=" ----------------------header-------------------------- " /> <param name="footer" value=" ----------------------footer-------------------------- " /> </layout> </appender> <appender name="consoleapp" type="log4net.appender.consoleappender,log4net"> <layout type="log4net.layout.patternlayout,log4net"> <param name="conversionpattern" value="%d [%t] %-5p %c - %m%n" /> </layout> </appender> </log4net> <!--↑log4net配置↑--> ... </configuration>
在配置文件中可以对日志记录的信息、格式、文件名等作出具体的配置,下面是配置信息的详解
<?xml version="1.0"?> <configuration> <configsections> <section name="log4net" type="log4net.config.log4netconfigurationsectionhandler,log4net"/> </configsections> <!--站点日志配置部分--> <log4net> <root> <!--控制级别,由低到高: all|debug|info|warn|error|fatal|off--> <!--比如定义级别为info,则info级别向下的级别,比如debug日志将不会被记录--> <!--如果没有定义level的值,则缺省为debug--> <level value="error"/> <appender-ref ref="rollingfileappender"/> </root> <appender name="rollingfileappender" type="log4net.appender.rollingfileappender"> <!--日志文件名开头--> <file value="c:\log\testlog4net.txt"/> <!--多线程时采用最小锁定--> <lockingmodel type="log4net.appender.fileappender+minimallock"/> <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置--> <datepattern value="(yyyymmdd)"/> <!--是否追加到文件,默认为true,通常无需设置--> <appendtofile value="true"/> <!--变换的形式为日期,这种情况下每天只有一个日志--> <!--此时maxsizerollbackups和maximumfilesize的节点设置没有意义--> <!--<rollingstyle value="date"/>--> <!--变换的形式为日志大小--> <!--这种情况下maxsizerollbackups和maximumfilesize的节点设置才有意义--> <rollingstyle value="size"/> <!--每天记录的日志文件个数,与maximumfilesize配合使用--> <maxsizerollbackups value="10"/> <!--每个日志文件的最大大小--> <!--可用的单位:kb|mb|gb--> <!--不要使用小数,否则会一直写入当前日志--> <maximumfilesize value="2mb"/> <!--日志格式--> <layout type="log4net.layout.patternlayout"> <conversionpattern value="%date [%t]%-5p %c - %m%n"/> </layout> </appender> </log4net> </configuration>
在global文件中的application_start方法中开启一个线程,用于将队列中的错误信息写入日志文件。
using system.linq; using system.threading; using system.web.http; using system.web.mvc; using system.web.optimization; using system.web.routing; using log4net; using pms.webapp.models; using spring.web.mvc; namespace pms.webapp { // 注意: 有关启用 iis6 或 iis7 经典模式的说明, // 请访问 http://go.microsoft.com/?linkid=9394801 public class mvcapplication : springmvcapplication//httpapplication { protected void application_start() { log4net.config.xmlconfigurator.configure();//读取log4net配置信息 arearegistration.registerallareas(); webapiconfig.register(globalconfiguration.configuration); filterconfig.registerglobalfilters(globalfilters.filters); routeconfig.registerroutes(routetable.routes); bundleconfig.registerbundles(bundletable.bundles); //开启一个线程,扫描异常信息队列. var filepath = server.mappath("/log/"); threadpool.queueuserworkitem((a) => { while (true) { //判断队列中是否有数据 if (log4exceptionattribute.exceptions.any()) { //出队一条异常信息 var ex = log4exceptionattribute.exceptions.dequeue(); //若异常信息不为空 if (ex == null) continue; //将异常信息写入到日志文件中 var logger = logmanager.getlogger("errormsg"); logger.error(ex.tostring()); } else { //若异常信息队列为空,则线程休息三秒 thread.sleep(3000); } } }, filepath); } } }
成功完成错误日志的配置。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: vue项目首屏打开速度慢的解决方法
下一篇: iOS开发教程之单例使用问题详析