欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MVC使用Log4Net进行错误日志记录学习笔记4

程序员文章站 2023-08-17 15:17:31
在web应用运行过程中,我们难免会遇到程序运行异常,这个时候我们就应该将异常信息记录下来,以便开发人员和维护人员对异常原因进行还原,对异常原因进行修复。在asp.net平台...

在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);
    }
  }
}

 成功完成错误日志的配置。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。