.NET Core整合log4net以及全局异常捕获实现2
Startup代码
1 public static ILoggerRepository repository { get; set; } 2 public Startup(IConfiguration configuration) 3 { 4 Configuration = configuration; 5 repository = LogManager.CreateRepository("NetCoreRepository"); 6 XmlConfigurator.Configure(repository, new FileInfo("log4net.config")); 7 InitRepository.loggerRepository = repository; 8 } 9 10 public IConfiguration Configuration { get; } 11 12 // This method gets called by the runtime. Use this method to add services to the container. 13 public void ConfigureServices(IServiceCollection services) 14 { 15 services.Configure<CookiePolicyOptions>(options => 16 { 17 // This lambda determines whether user consent for non-essential cookies is needed for a given request. 18 options.CheckConsentNeeded = context => true; 19 options.MinimumSameSitePolicy = SameSiteMode.None; 20 }); 21 22 23 services.AddMvc(o => o.Filters.Add(typeof(GlobalExceptions))).SetCompatibilityVersion(CompatibilityVersion.Version_2_1); 24 } 25 26 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 27 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 28 { 29 if (env.IsDevelopment()) 30 { 31 app.UseDeveloperExceptionPage(); 32 } 33 else 34 { 35 app.UseExceptionHandler("/Home/Error"); 36 } 37 38 app.UseStaticFiles(); 39 app.UseCookiePolicy(); 40 41 app.UseMvc(routes => 42 { 43 routes.MapRoute( 44 name: "default", 45 template: "{controller=Home}/{action=Index}/{id?}"); 46 }); 47 }
log4net.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <log4net> 4 <!-- 错误日志类--> 5 <logger name="logerror"> 6 <level value="ALL" /> 7 <appender-ref ref="ErrorAppender" /> 8 </logger> 9 <!-- 错误日志附加介质--> 10 <appender name="ErrorAppender" type="log4net.Appender.RollingFileAppender"> 11 <!--日志文件路径--> 12 <param name="File" value="Log\\LogError\\" /> 13 <!--是否是向文件中追加日志--> 14 <param name="AppendToFile" value="true" /> 15 <!--log保留天数--> 16 <param name="MaxSizeRollBackups" value="1000" /> 17 <!--最大文件大小--> 18 <param name="MaxFileSize" value="10240" /> 19 <!--日志文件名是否是固定不变的--> 20 <param name="StaticLogFileName" value="false" /> 21 <!--日志文件名格式为:2008-08-31.log--> 22 <param name="DatePattern" value="yyyy-MM-dd".log"" /> 23 <!--日志根据日期滚动--> 24 <param name="RollingStyle" value="Date" /> 25 <param name="Encoding" value="utf-8" /> 26 <!--信息日志布局--> 27 <layout type="log4net.Layout.PatternLayout"> 28 <param name="ConversionPattern" value="<!--异常信息头-->%n【异常时间】:%d [%t] ;%n【异常级别】:%-5p %n%m %n <!--异常信息尾部-->%n" /> 29 </layout> 30 </appender> 31 32 <!-- 信息日志类 --> 33 <logger name="loginfo"> 34 <level value="ALL" /> 35 <appender-ref ref="InfoAppender" /> 36 </logger> 37 <!-- 信息日志附加介质--> 38 <appender name="InfoAppender" type="log4net.Appender.RollingFileAppender"> 39 <!--日志文件路径--> 40 <param name="File" value="Log\\LogInfo\\" /> 41 <!--是否是向文件中追加日志--> 42 <param name="AppendToFile" value="true" /> 43 <!--log保留天数--> 44 <param name="MaxSizeRollBackups" value="100" /> 45 <param name="MaxFileSize" value="1" /> 46 <!--日志文件名是否是固定不变的--> 47 <param name="StaticLogFileName" value="false" /> 48 <!--日志文件名格式为:2008-08-31.log--> 49 <param name="DatePattern" value="yyyy-MM-dd".log"" /> 50 <!--日志根据日期滚动--> 51 <param name="RollingStyle" value="Date" /> 52 <param name="Encoding" value="utf-8" /> 53 <!--信息日志布局--> 54 <layout type="log4net.Layout.PatternLayout"> 55 <param name="ConversionPattern" value="<!--信息头>%n日志时间:%d [%t] <BR>%n日志级别:%-5p %n%m %n <信息尾>" /> 56 </layout> 57 </appender> 58 </log4net> 59 60 61 <!-- To customize the asp.net core module uncomment and edit the following section. 62 For more info see https://go.microsoft.com/fwlink/?linkid=838655 --> 63 <!-- 64 <system.webServer> 65 <handlers> 66 <remove name="aspNetCore"/> 67 <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/> 68 </handlers> 69 <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" /> 70 </system.webServer> 71 --> 72 73 </configuration>
1 public class GlobalExceptions : IExceptionFilter 2 { 3 private readonly IHostingEnvironment _env; 4 public GlobalExceptions(IHostingEnvironment env) 5 { 6 _env = env; 7 } 8 public void OnException(ExceptionContext context) 9 { 10 var json = new JsonErrorResponse(); 11 //这里面是自定义的操作记录日志 12 if (context.Exception.GetType() == typeof(UserOperationException)) 13 { 14 json.Message = context.Exception.Message; 15 if (_env.IsDevelopment()) 16 { 17 json.DevelopmentMessage = context.Exception.StackTrace;//堆栈信息 18 } 19 context.Result = new BadRequestObjectResult(json);//返回异常数据 20 } 21 else 22 { 23 json.Message = "发生了未知内部错误"; 24 if (_env.IsDevelopment()) 25 { 26 json.DevelopmentMessage = context.Exception.StackTrace;//堆栈信息 27 } 28 context.Result = new InternalServerErrorObjectResult(json); 29 } 30 31 //采用log4net 进行错误日志记录 32 LogHelper.ErrorLog(json.Message, context.Exception); 33 34 } 35 } 36 public class InternalServerErrorObjectResult : ObjectResult 37 { 38 public InternalServerErrorObjectResult(object value) : base(value) 39 { 40 StatusCode = StatusCodes.Status500InternalServerError; 41 } 42 }
public class JsonErrorResponse { /// <summary> /// 生产环境的消息 /// </summary> public string Message { get; set; } /// <summary> /// 开发环境的消息 /// </summary> public string DevelopmentMessage { get; set; } }
1 public static class InitRepository 2 { 3 public static ILoggerRepository loggerRepository { get; set; } 4 } 5 6 public static class LogHelper 7 { 8 public static readonly ILog logerror = LogManager.GetLogger(InitRepository.loggerRepository.Name, "logerror"); 9 10 public static readonly ILog loginfo = LogManager.GetLogger(InitRepository.loggerRepository.Name, "loginfo"); 11 12 #region 全局异常错误记录持久化 13 /// <summary> 14 /// 全局异常错误记录持久化 15 /// </summary> 16 /// <param name="throwMsg"></param> 17 /// <param name="ex"></param> 18 public static void ErrorLog(string throwMsg, Exception ex) 19 { 20 string errorMsg = string.Format("【抛出信息】:{0} \n【异常类型】:{1} \n【异常信息】:{2} \n【堆栈调用】:{3}", new object[] { throwMsg, 21 ex.GetType().Name, ex.Message, ex.StackTrace }); 22 23 logerror.Error(errorMsg); 24 } 25 #endregion 26 27 #region 自定义操作记录 28 /// <summary> 29 /// 自定义操作记录,与仓储中的增删改的日志是记录同一张表 30 /// </summary> 31 /// <param name="throwMsg"></param> 32 /// <param name="ex"></param> 33 public static void WriteLog(string throwMsg, Exception ex) 34 { 35 string errorMsg = string.Format("【抛出信息】:{0} \n【异常类型】:{1} \n【异常信息】:{2} \n【堆栈调用】:{3}", new object[] { throwMsg, 36 ex.GetType().Name, ex.Message, ex.StackTrace }); 37 38 logerror.Error(errorMsg); 39 } 40 #endregion 41 }
/// <summary> /// 操作日志 /// </summary> public class UserOperationException : Exception { public UserOperationException() { } public UserOperationException(string message) : base(message) { } public UserOperationException(string message, Exception innerException) : base(message, innerException) { } }
public class ErrorViewModel { public string RequestId { get; set; } public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); }