Log4在.NetCore中的应用

1.管理Nuget程序包,安装Log4

2.log4net.config 的编写(有异常日志类和信息日志类,按需要配置)

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <log4net>
    <!-- 错误日志类-->
    <logger name="logerror">
      <level value="ALL" />
      <appender-ref ref="ErrorAppender" />
    </logger>
    <!-- 错误日志附加介质-->
    <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender">
      <!--日志文件路径-->
      <param name="File" value="Log\LogError\" />
      <!--是否是向文件中追加日志-->
      <param name="AppendToFile" value="true" />
      <!--log保留天数-->
      <param name="MaxSizeRollBackups" value="1000" />
      <!--最大文件大小-->
      <param name="MaxFileSize" value="10240" />
      <!--日志文件名是否是固定不变的-->
      <param name="StaticLogFileName" value="false" />
      <!--日志文件名格式为:2008-08-31.log-->
      <param name="DatePattern" value="yyyy-MM-dd&quot;.htm&quot;" />
      <!--日志根据日期滚动-->
      <param name="RollingStyle" value="Date" />
      <!--信息日志布局-->
      <layout type="log4net.Layout.PatternLayout">
        <param name="ConversionPattern" value="&lt;HR COLOR=red&gt;%n【异常时间】:%d [%t] &lt;BR&gt;%n【异常级别】:%-5p &lt;BR&gt;%n%m &lt;BR&gt;%n &lt;HR Size=1&gt;"  />
      </layout>
    </appender>
  </log4net>

</configuration>

cofig配置好之后,在startup里面,创建log仓储

 public static ILoggerRepository repository { get; set; }
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            repository = LogManager.CreateRepository("LogRepository");//创建一个Log仓储
            XmlConfigurator.Configure(repository, new FileInfo("log4net.config"));//文件流读取log配置文件
            InitRepository.LogRepository = repository;
        }

运行后,会在程序目录创建文件夹和html文件

现在我们写一个异常,将异常写入到日志里。

首先我们需要写一个全局异常的过滤器GlobalExceptions,捕获程序异常

//全局异常捕获过滤器
    public class GlobalExceptions : IExceptionFilter
    {
        private readonly IHostingEnvironment _env;
        public GlobalExceptions(IHostingEnvironment env)
        {
            _env = env;
        }
        /// <summary>
        /// 当出现异常的时候,会调用该方法捕获异常,该方法是对IExceptionFilter里面的OnException的实现
        /// </summary>
        /// <param name="context"></param>
        public void OnException(ExceptionContext context)
        {
            //将异常上下文给到LogHelper写入
             LogHelper.ErrorLog(context.Exception);
                
        }
    }
这里我们需要将过滤器注册下


OnException方法是对IExceptionFilter里同名方法的实现,当抛出异常的时候就会进入这里了,我们将异常上下文给到LogHelper,帮忙写入到日志文件中
LogHelper部分代码
 public class InitRepository
    {
        public static ILoggerRepository LogRepository { get; set; }
    }

    public class LogHelper
    {
        //全局异常错误记录持久化
        private static readonly ILog logerror = LogManager.GetLogger(InitRepository.LogRepository.Name, "logerror");
        //自定义操作记录
        //private static readonly ILog loginfo = LogManager.GetLogger(InitRepository.LogRepository.Name, "loginfo");

        #region 全局异常错误记录持久化    
        /// <summary>
        /// 全局异常错误记录持久化     
        /// </summary>
        /// <param name="ex">异常上下文</param>
        public static void ErrorLog(Exception ex)
        {
            string errorMsg = string.Format("【异常信息】:{0} <br>【异常类型】:{1} <br>【堆栈调用】:{2} <br>", new object[] {ex.Message,
                ex.GetType().Name, ex.StackTrace });
            errorMsg = errorMsg.Replace("
", "<br>");
            errorMsg = errorMsg.Replace("位置", "<strong style="color:red">位置</strong>");
            logerror.Error(errorMsg);
        }
        #endregion


        #region 自定义操作记录       
        /// <summary>
        /// 自定义操作记录,与仓储中的增删改的日志是记录同一张表,操作记录暂不需要        
        /// </summary>
        /// <param name="throwMsg"></param>
        /// <param name="ex"></param>
        //public static void WriteLog(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);
        //}
        #endregion

    }

现在我们去写一个异常

这里重点说下,写异常的时候不能加async,这个标识会在主线程下创建一个子线程,当没有await 返回程序执行结果或异常的时候,异常会直接死在子线程里,不回被全局异常捕获到,大概就是下面这个意思

我们去掉标识再执行这个异常,监测主线程的过滤器就能检测到异常,Loghelper将异常信息写入文件



原文地址:https://www.cnblogs.com/wangcongsuibi/p/10375138.html