• AspNetCore 使用log4net+IExceptionFilter 记录错误日志


    错误日志的好处我就不说了,大家都心里有数,那今天浩子就给大家说一说基本的错误日志吧这次通过log4net记录日志。

    原来写过一个关于Nlog的日志框架,传送门为:https://www.cnblogs.com/ZaraNet/p/9957655.html 

    使用呢,直接nuget log4net吧,这个就不多说了,那我们看一下如何使用。

    1.创建log4net.config

    2.配置Startup.

    3.定义HttpGlobalExceptionFilter

    在根目录创建log4net.config,其定义如下:

    <?xml version="1.0"?>
    <configuration>
      <configSections>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net, Version=1.2.11.0, Culture=neutral, PublicKeyToken=1B44E1D426115821" />
      </configSections>
      <log4net>
        <root>
          <!--<level value="DEBUG"/>-->
          <level value="ERROR"/>
          <!--根据log级别记录到不同的日志文件-->
          <!--<appender-ref ref="DebugLog" />-->
          <appender-ref ref="ErrorLog" />
        </root>
        <appender name="ErrorLog" type="log4net.Appender.RollingFileAppender">
          <!-- 最后放开注释-->
          <span style="font-family: Arial, Helvetica, sans-serif;">
            <!--<lockingModel type="命名空间.MinimalLockDeleteEmpty" />-->
          </span>
          <param name="File" value="Log" />
          <param name="AppendToFile" value="true" />
          <param name="RollingStyle" value="Date" />
          <param name="DatePattern" value="yyyy-MM\yyyy-MM-dd.'log'" />
          <param name="StaticLogFileName" value="false" />
          <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
          </layout>
          <securityContext type="log4net.Util.WindowsSecurityContext">
            <credentials value="Process" />
          </securityContext>
          <filter type="log4net.Filter.LevelRangeFilter">
            <levelMin value="ERROR" />
            <levelMax value="ERROR" />
          </filter>
        </appender>
      </log4net>
    </configuration>
    

      在Startup.cs定义如下,记得引用相应的命名空间。

    public static ILoggerRepository repository { get; set; }
    
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    
        //加载log4net日志配置文件
        repository = LogManager.CreateRepository("NETCoreRepository");
        XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));
    }
    
    public IConfiguration Configuration { get; }
    
    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
    
        services.AddMvc(options =>
        {
            options.Filters.Add<Models.HttpGlobalExceptionFilter>(); //加入全局异常类
        });
    }  

    控制器方面:

     public class IndexController : Controller
        {
            private ILog log = LogManager.GetLogger(Startup.repository.Name, typeof(HttpGlobalExceptionFilter));
            public IActionResult Index()
            {
                log.Error("哎哟我去");
                return View();
            }
        }

    那我们可以看到呢,我们的日志已经生成好了,但是有经验的人都应该知道,这个如果你不记录错误的话,你也是每天创建一个这样的文件,那么我们应该怎么办呢?看了一下国内的网站,还没有对这个有针对性的解决方案,但我们可以最low的定义一个计时器,来找到为空的日志文件,如果它是为空的我们就删除它。

    你可以自己搞个任务调度的框架去完成这个需求,当然在这里我还是非常推荐使用Quertz的。你自己去看一下它是不是0kb就完事了,Quertz文章传送门:https://www.cnblogs.com/ZaraNet/p/9962786.html.

    public IActionResult Index()
            {
           try{} 
            catch{
            ..
            }           
         return View();
            }    
    

      回归正题,我们想一想,在一般的控制器中,每次进行逻辑业务的时候,都需要try,catch吗? 我们可以这样耦合度就太大了,所以我们最好通过全局filter。

    public class HttpGlobalExceptionFilter : IExceptionFilter
        {
            private ILog log = LogManager.GetLogger(Startup.repository.Name,typeof(HttpGlobalExceptionFilter));
            /// <summary>
            /// 当系统发生未捕捉的异常时就会触发这个方法
            /// </summary>
            /// <param name="context">context是上下文,包含了错误异常信息</param>
            public void OnException(ExceptionContext context)
            {
                log.Error("哎呀呀我是菜鸡");
            }
        }
    

     你还可以自己定义记录格式:

      public static void ErrorLog(string throwMsg, Exception ex)
            {
                string errorMsg = string.Format("【抛出信息】:{0} <br>【异常类型】:{1} <br>【异常信息】:{2} <br>【堆栈调用】:{3}", new object[] { throwMsg,
                    ex.GetType().Name, ex.Message, ex.StackTrace });
                errorMsg = errorMsg.Replace("
    ", "<br>");
                errorMsg = errorMsg.Replace("位置", "<strong style="color:red">位置</strong>");
                logerror.Error(errorMsg);
            }

      继承IExceptionFilter接口,在你程序报错的时候就会走到这里,所以你可以在这里完成一些操作去配合日志框架,我们还需要去注册服务

     public void ConfigureServices(IServiceCollection services)
            {
                 ....///
                   services.AddMvc(options =>
                {
                    options.Filters.Add<Filter.HttpGlobalExceptionFilter>();//全局异常类
                });
            }       
    

      之后你就直接在OnException中直接进行写入就好了。今天就说到这里吧。嘿嘿!!

  • 相关阅读:
    【c# 学习笔记】使用virtual和override关键字实现方法重写
    【c# 学习笔记】多态
    【c# 学习笔记】子类的初始化顺序
    mybatis入门截图二
    解析xml文件,遍历输出xml文件中的所有节点, 最终模仿实现struts2框架自动封装参数的功能
    mybatis入门截图总结
    springMVC入门截图
    OA项目总结3
    修改struts2自定义标签的源代码,在原有基础上增加功能(用于OA项目权限判断,是否显示某个权限)
    ongl表达式中得到对象,调用对象方法(OA项目权限显示模块)
  • 原文地址:https://www.cnblogs.com/ZaraNet/p/10033153.html
Copyright © 2020-2023  润新知