AspNetCore 使用log4net+IExceptionFilter 记录错误日志
错误日志的好处我就不说了,大家都心里有数,那今天浩子就给大家说一说基本的错误日志吧这次通过log4net记录日志。
原来写过一个关于Nlog的日志框架,传送门为:https://www.cnblogs.com/ZaraNet/p/9957655.html
使用呢,直接nuget log4net吧,这个就不多说了,那我们看一下如何使用。
1.创建log4net.config
2.配置Startup.
3.定义HttpGlobalExceptionFilter
在根目录创建log4net.config,其定义如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <?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定义如下,记得引用相应的命名空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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>(); //加入全局异常类 }); } |
控制器方面:
1 2 3 4 5 6 7 8 9 | 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.
1 2 3 4 5 6 7 8 | public IActionResult Index() { try {} catch { .. } return View(); } |
回归正题,我们想一想,在一般的控制器中,每次进行逻辑业务的时候,都需要try,catch吗? 我们可以这样耦合度就太大了,所以我们最好通过全局filter。
1 2 3 4 5 6 7 8 9 10 11 12 | 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( "哎呀呀我是菜鸡" ); } } |
你还可以自己定义记录格式:
1 2 3 4 5 6 7 8 | 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( "\r\n" , "<br>" ); errorMsg = errorMsg.Replace( "位置" , "<strong style=\"color:red\">位置</strong>" ); logerror.Error(errorMsg); } |
继承IExceptionFilter接口,在你程序报错的时候就会走到这里,所以你可以在这里完成一些操作去配合日志框架,我们还需要去注册服务
1 2 3 4 5 6 7 8 | public void ConfigureServices(IServiceCollection services) { .... /// services.AddMvc(options => { options.Filters.Add<Filter.HttpGlobalExceptionFilter>(); //全局异常类 }); } |
之后你就直接在OnException中直接进行写入就好了。今天就说到这里吧。嘿嘿!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异