log4net在.net MVC中的简单使用

前言

log4net是用来做什么的?
在项目部署到服务器上时,不可能在服务器上调试,但是一些bug会因为各种原因发生,这时候我们就需要对项目的错误日志进行专门记录,如记录到txt文件、数据库、控制台之类的,并且有时候是记录到多个介质中。 有多种方法可以实现,其中使用log4net来记录错误日志是比较好的方法。

  • 注意:log4net只是帮助记录错误日志,而不管捕获异常。

正文

添加log4net引用

在程序包管理控制台输入下面代码:

PM> Install-Package log4net

管理器会自动将log4net的程序集下载到项目的packages文件夹下:
这里写图片描述
里面有各个版本的log4net.dll程序集,添加自己需要的引用就行:
这里写图片描述

log4net配置

默认配置节点在Web.config(cs是app.config)里面,但是自己可以自定一个文件夹来放自己的配置文件。这里新建Config文件夹,并且新建log4net.config文件:
这里写图片描述
常用的log4net.config配置如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!--增加log4net节点-->
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>
  <!--log4net节点配置-->
  <!--五个错误等级:OFF,FATAL,ERROR,WARN,INFO,DEBUG,ALL;三个节点root,logger,appender-->
  <!--root节点0或1个,这里并没有使用root-->
  <!--记录器logger,继承root,可以有多个记录器-->
  <!--可以有多个appender,是记录的方法-->
  <log4net>
    <logger name="WebLogger">
      <level value="DEBUG"/>
      <appender-ref ref="LogFileAppender"/>
    </logger>
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
      <!--最多产生10个日志文件-->
      <maxSizeRollBackups value="10"/>
      <!--每个文件最大1M-->
      <maximumFileSize value="1024KB"/>
      <!--是一个文件,且放在App_Data文件夹里面,安全-->
      <param name="File" value="App_Data/"/>
      <!--是否追加到文件-->
      <param name="AppendToFile" value="true"/>
      <!--按照何种方式产生多个日志文件(日期[Date],文件大小[Size],混合[Composite])-->
      <param name="RollingStyle" value="Date"/>
      <!--文件名字-->
      <param name="DatePattern" value="&quot;Logs_&quot;yyyyMMdd&quot;.txt&quot;"/>
      <!--是否只写到一个文件中-->
      <param name="StaticLogFileName" value="false"/>
      <layout type="log4net.Layout.PatternLayout,log4net">
        <!--每个文件的头部信息和底部信息-->
        <param name="Header" value="&#13;&#10;-----------------header---------------&#13;&#10;"/>
        <param name="Footer" value="&#13;&#10;-----------------header---------------&#13;&#10;"/>
        <!--错误的记录格式,-->
        <!--时间:%date 
        线程ID:[%thread] 
        日志级别:%level 
        记录类:%logger     
        操作者ID:%property{Operator} 
        操作类型:%property{Action}             
        当前机器名:%property
        当前机器名及登录用户:%username                
        记录位置:%location
        消息描述:%property{Message}
        异常:%exception
        消息:%message%newline
        换行:%n-->
        <param name="ConversionPattern" value="%d [%t] %-5level %c - %m%n%n"/>
      </layout>
    </appender>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender" >
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
      </layout>
    </appender>
    <!--如果是控制台项目可以输出到控制台-->
    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender,log4net">
      <mapping>
        <level value="ERROR" />
        <foreColor value="White" />
        <backColor value="Red, HighIntensity" />
      </mapping>
      <mapping>
        <level value="Info" />
        <foreColor value="Green" />
      </mapping>
      <layout type="log4net.Layout.PatternLayout,log4net">
        <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/>
      </layout>
    </appender>
    <appender name="ADONetAppender" type="log4net.Appender.AdoNetAppender ,log4net">
      <layout type="log4net.Layout.PatternLayout,log4net">
        <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n"/>
      </layout>
    </appender>

  </log4net>
</configuration>

应用开始运行时初始化log4net

Global.asax会在应用运行时最开始读取,在这里初始化log4net。
Global.asax里面添加下面代码:

  public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //读取log4net配置,进行初始化。
            //如果是web.config,则是 log4net.Config.XmlConfigurator.Configure();
            //如果是自定义config,就指定路径。
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(Server.MapPath("~") + @"/Config/log4net.config"));
        }
    }

替换异常过滤器

在MVC中,常见的过滤器是Authorization身份过滤器、action过滤器、result过滤器和Exception过滤器。在App_Start文件夹下的FilterConfig.cs中,默认会注册一个异常过滤器,在异常发生时自动执行某些操作:
这里写图片描述
打开HandleErrorAttribute元数据:
这里写图片描述
HandleErrorAttribute继承异常过滤器接口。可以继承HandleErrorAttribute类来写自己的异常过滤方法。这里把FilterConfig.cs里面的HandleErrorAttribute注释,改换成自己的异常处理类:

    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            // filters.Add(new HandleErrorAttribute());
            //添加自己的全局异常过滤器
            filters.Add(new MyHandleErrorAttribute());

        }
    }

使用接口来写异常方法

新建LogHelper文件夹,为了方便扩展这里使用接口,以后写自己的方法也方便:
这里写图片描述
ILogWriter.cs代码如下:

using System;
namespace Log4netDemo.UI.Portail.LogHelper
{
    public interface ILogWriter
    {
        void WriteLogInfo(string BugTxt);
    }
}

Log4NetWriter.cs代码如下:

using System;
using System.Web;
namespace Log4netDemo.UI.Portail.LogHelper
{
    public class Log4NetWriter : ILogWriter
    {
        public void WriteLogInfo(string BugTxt)
        {
            //WebLogger是配置文件里面logger的name
            log4net.ILog LogWriter = log4net.LogManager.GetLogger("WebLogger");
            LogWriter.Debug(BugTxt);
        }
    }
}

MyHandleErrorAttribute类继承HandleErrorAttribute,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Log4netDemo.UI.Portail.LogHelper
{
    public class MyHandleErrorAttribute: HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            //发生异常时调用
            base.OnException(filterContext);         LogHelper.WriteLog(filterContext.Exception.ToString());
        }
    }
}

LogHelper.cs代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;

namespace Log4netDemo.UI.Portail.LogHelper
{
    public class LogHelper
    {
        public static Queue<string> ExceptionStringQueue = new Queue<string>();
        public static List<ILogWriter> LogWriteList = new List<ILogWriter>();
        public static void WriteLogToFile(string txt) { }
        public static void WriteLogToDB(string txt) { }
        static LogHelper()
        {
            LogWriteList.Add(new Log4NetWriter());
            ThreadPool.QueueUserWorkItem(o =>
            {
                while (true)
                {
                    lock (ExceptionStringQueue)
                    {
                        if (ExceptionStringQueue.Count > 0)
                        {
                            string str = ExceptionStringQueue.Dequeue();//出队                                            
                            foreach (var logWriter in LogWriteList)
                            {
                                logWriter.WriteLogInfo(str);
                            }
                        }
                        else
                        {
                            Thread.Sleep(30);
                        }
                    }
                }
            });
        }
        public static void WriteLog(string exceptionText)
        {
            //解决多个错误写消息时,造成多线程访问问题。
            //解决方法:写到消息队列里面Queue
            lock (ExceptionStringQueue)
            {
                //入队
                ExceptionStringQueue.Enqueue(exceptionText);
            }
        }
    }
}

运行效果

在TestController.cs里面写一个action抛出自定义异常:

using System;
using System.Web.Mvc;

namespace Log4netDemo.UI.Portail.Controllers
{
    public class TestController : Controller
    {
        // GET: Test
        public ActionResult Index()
        {
            throw new Exception("主动抛出了异常");
            return View();
        }
    }
}

运行,访问/Test/Index,会抛出异常,记录到App_Start文件夹下面,并且这个txt文件是log4net根据配置自动生成的:
这里写图片描述
这里写图片描述

总结

  1. 不建议把log4net配置写在应用web.config里面。
  2. 使用订阅模式来记录错误日志方便扩展。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值