MVC使用Log4Net进行错误日志记录学习笔记4
在Web应用运行过程中,我们难免会遇到程序运行异常,这个时候我们就应该将异常信息记录下来,以便开发人员和维护人员对异常原因进行还原,对异常原因进行修复。在ASP.NET平台中进行日志记录的组件也有很多,如Log4Net、CommonLogging等,我们这里选用Log4Net进行异常日志的记录。
1.捕获异常
在ASP.NETMVC中提供了一个全局的异常处理过滤器:HandleErrorAttribute,可以通过该过滤器捕获异常信息。
我们在Models文件夹下新建类型Log4ExceptionAttribute,继承HandleErrorAttribute类,同时重写OnException方法来捕获异常数据:
usingSystem.Web.Mvc;
namespacePMS.WebApp.Models
{
publicclassLog4ExceptionAttribute:HandleErrorAttribute
{
///<summary>
///重写OnException方法来捕获异常数据
///</summary>
///<paramname="filterContext"></param>
publicoverridevoidOnException(ExceptionContextfilterContext)
{
base.OnException(filterContext);
//捕获当前异常数据
varex=filterContext.Exception;
}
}
}
新建过滤器后我们还需要在Global文件中调用的RegisterGlobalFilters方法中完成自己定义异常处理过滤的注册。
usingSystem.Web.Mvc;
usingPMS.WebApp.Models;
namespacePMS.WebApp
{
publicclassFilterConfig
{
publicstaticvoidRegisterGlobalFilters(GlobalFilterCollectionfilters)
{
//filters.Add(newHandleErrorAttribute());
filters.Add(newLog4ExceptionAttribute());
}
}
}
2.考虑到多用户并发操作时可能产生的问题,我们需要新建一个队列来进行异常信息的暂存,同时开辟一个线程专门对队列中的异常信息进行处理。
在Log4ExceptionAttribute类中新建一个静态的异常类型的队列,在发生异常后,程序自动触发OnException方法,方法中将当前的异常信息入队后,跳转到错误页面。
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Web.Mvc;
namespacePMS.WebApp.Models
{
publicclassLog4ExceptionAttribute:HandleErrorAttribute
{
publicstaticQueue<Exception>Exceptions=newQueue<Exception>();
///<summary>
///重写OnException方法来捕获异常数据
///</summary>
///<paramname="filterContext"></param>
publicoverridevoidOnException(ExceptionContextfilterContext)
{
base.OnException(filterContext);
//捕获当前异常数据
varex=filterContext.Exception;
//将异常数据入队
Exceptions.Enqueue(ex);
//跳转到错误页面
filterContext.HttpContext.Response.Redirect("/Error.html");
}
}
}
Log4Net的配置是在应用程序配置文件中进行的,我们先在配置文件中进行Log4Net的配置。Log4Net需要配置的节点位置和SpringNet完全相同,首先需要在configSessions中新增子节点,然后在configuration节点中增加log4net节点完成具体配置。
<configuration> <configSections> <sectionname="entityFramework"type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,EntityFramework,Version=6.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089"requirePermission="false"/> <!--FormoreinformationonEntityFrameworkconfiguration,visithttp://go.microsoft.com/fwlink/?LinkID=237468--> <!--↓Log4Net配置↓--> <sectionname="log4net"type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> <!--↑Log4Net配置↑--> <!--↓Spring.Net配置↓--> <sectionGroupname="spring"> <sectionname="context"type="Spring.Context.Support.MvcContextHandler,Spring.Web.Mvc4"/> </sectionGroup> <!--↑Spring.Net配置↑--> </configSections> <!--↓Spring.Net配置↓--> <spring> <context> <resourceuri="file://~/Config/controllers.xml"/> <resourceuri="file://~/Config/services.xml"/> </context> </spring> <!--↑Spring.Net配置↑--> <!--↓Log4Net配置↓--> <log4net> <!--OFF,FATAL,ERROR,WARN,INFO,DEBUG,ALL--> <!--SetrootloggerleveltoERRORanditsappenders--> <root> <levelvalue="ALL"/> <appender-refref="SysAppender"/> </root> <!--PrintonlymessagesoflevelDEBUGoraboveinthepackages--> <loggername="WebLogger"> <levelvalue="DEBUG"/> </logger> <appendername="SysAppender"type="log4net.Appender.RollingFileAppender,log4net"> <paramname="File"value="App_Data/"/> <paramname="AppendToFile"value="true"/> <paramname="RollingStyle"value="Date"/> <paramname="DatePattern"value=""Logs_"yyyyMMdd".txt""/> <paramname="StaticLogFileName"value="false"/> <layouttype="log4net.Layout.PatternLayout,log4net"> <paramname="ConversionPattern"value="%d[%t]%-5p%c-%m%n"/> <paramname="Header"value=" ----------------------header-------------------------- "/> <paramname="Footer"value=" ----------------------footer-------------------------- "/> </layout> </appender> <appendername="consoleApp"type="log4net.Appender.ConsoleAppender,log4net"> <layouttype="log4net.Layout.PatternLayout,log4net"> <paramname="ConversionPattern"value="%d[%t]%-5p%c-%m%n"/> </layout> </appender> </log4net> <!--↑Log4Net配置↑--> ... </configuration>
在配置文件中可以对日志记录的信息、格式、文件名等作出具体的配置,下面是配置信息的详解
<?xmlversion="1.0"?> <configuration> <configSections> <sectionname="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <!--站点日志配置部分--> <log4net> <root> <!--控制级别,由低到高:ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--> <!--比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录--> <!--如果没有定义LEVEL的值,则缺省为DEBUG--> <levelvalue="ERROR"/> <appender-refref="RollingFileAppender"/> </root> <appendername="RollingFileAppender"type="log4net.Appender.RollingFileAppender"> <!--日志文件名开头--> <filevalue="c:\Log\TestLog4net.TXT"/> <!--多线程时采用最小锁定--> <lockingModeltype="log4net.Appender.FileAppender+MinimalLock"/> <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置--> <datePatternvalue="(yyyyMMdd)"/> <!--是否追加到文件,默认为true,通常无需设置--> <appendToFilevalue="true"/> <!--变换的形式为日期,这种情况下每天只有一个日志--> <!--此时MaxSizeRollBackups和maximumFileSize的节点设置没有意义--> <!--<rollingStylevalue="Date"/>--> <!--变换的形式为日志大小--> <!--这种情况下MaxSizeRollBackups和maximumFileSize的节点设置才有意义--> <RollingStylevalue="Size"/> <!--每天记录的日志文件个数,与maximumFileSize配合使用--> <MaxSizeRollBackupsvalue="10"/> <!--每个日志文件的最大大小--> <!--可用的单位:KB|MB|GB--> <!--不要使用小数,否则会一直写入当前日志--> <maximumFileSizevalue="2MB"/> <!--日志格式--> <layouttype="log4net.Layout.PatternLayout"> <conversionPatternvalue="%date[%t]%-5p%c-%m%n"/> </layout> </appender> </log4net> </configuration>
在Global文件中的Application_Start方法中开启一个线程,用于将队列中的错误信息写入日志文件。
usingSystem.Linq;
usingSystem.Threading;
usingSystem.Web.Http;
usingSystem.Web.Mvc;
usingSystem.Web.Optimization;
usingSystem.Web.Routing;
usinglog4net;
usingPMS.WebApp.Models;
usingSpring.Web.Mvc;
namespacePMS.WebApp
{
//注意:有关启用IIS6或IIS7经典模式的说明,
//请访问http://go.microsoft.com/?LinkId=9394801
publicclassMvcApplication:SpringMvcApplication//HttpApplication
{
protectedvoidApplication_Start()
{
log4net.Config.XmlConfigurator.Configure();//读取Log4Net配置信息
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//开启一个线程,扫描异常信息队列.
varfilePath=Server.MapPath("/Log/");
ThreadPool.QueueUserWorkItem((a)=>
{
while(true)
{
//判断队列中是否有数据
if(Log4ExceptionAttribute.Exceptions.Any())
{
//出队一条异常信息
varex=Log4ExceptionAttribute.Exceptions.Dequeue();
//若异常信息不为空
if(ex==null)continue;
//将异常信息写入到日志文件中
varlogger=LogManager.GetLogger("errorMsg");
logger.Error(ex.ToString());
}
else
{
//若异常信息队列为空,则线程休息三秒
Thread.Sleep(3000);
}
}
},filePath);
}
}
}
成功完成错误日志的配置。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。