.Net Core中间件和过滤器实现错误日志记录
1.中间件的概念
ASP.NET Core的处理流程是一个管道,中间件是组装到应用程序管道中用来处理请求和响应的组件。 每个中间件可以:
- 选择是否将请求传递给管道中的下一个组件。
- 可以在调用管道中的下一个组件之前和之后执行业务逻辑。
中间件是一个请求委托( public delegate Task RequestDelegate(HttpContext context) )的实例,所以中间件的本质就是一个方法,方法的参数是HttpContext,返回Task。传入的HttpContext参数包含了请求和响应信息,我们可以在中间件中对这些信息就行修改。中间件的管道处理流程如下:
<?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" ae4 internalLogLevel="Info" internalLogFile="D:\LogDemoOfWebapi\internal-nlog.txt"> <!-- enable asp.net core layout renderers --> <extensions> <add assembly="NLog.Web.AspNetCore"/> </extensions> <targets> <target xsi:type="File" name="errorLog" fileName="D:/logs/AT___${shortdate}.log" layout="----------------日志记录开始----------------${newline}【日志时间】:${longdate} ${newline}【日志级别】:${level:uppercase=true}${newline}【异常相关信息】${newline}${message}${newline}${newline}${newline}" /> </targets> <rules> <logger name="*" minlevel="Error" writeTo="errorLog" /> </rules> </nlog>View Code 576 到这里异常处理中间件就注册完成了,修改ValueController自己制造一个异常来测试一下,代码如下:
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { private ILogger<ValuesController> _logger; public ValuesController(ILogger<ValuesController> logger) { _logger = logger; } // GET api/values [HttpGet] public ActionResult<IEnumerable<string>> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { throw new Exception("有一个错误发生了.."); return "value"; } }
运行程序,在开发环境下访问/Values/1,显示结果如下,同时这些错误信息也会通过nlog写入到错误日志中:
非开发环境下,访问/values/1,显示如下:
如果我们想使用类似app.UseMvc()这样的形式来使用我们自定义的中间件的话,就需要给ApplicationBuilder添加一个扩展方法,首先添加一个静态类CostomMiddleware,代码如下:
/// <summary> /// 扩展方法 /// </summary> public static class CostomMiddleware { public static IApplicationBuilder UseCostomError(this IApplicationBuilder app) { return app.UseMiddleware<CostomErrorMiddleware>(); } }
然后修改Configure方法即可:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory factory) { //添加nlog factory.AddNLog(); env.ConfigureNLog("nlog.config"); //使用扩展方法 app.UseCostomError(); app.UseMvc(); }
运行程序后和前边的执行效果是一样的。
3 使用过滤器记录错误日志
过滤器大家应该都很熟悉,在ASP.NET Core中过滤器的使用没有太大的变化,这里也实现一个使用过滤器记录错误日志的栗子,直接看代码吧,首先创建一个过滤器,代码如下:
/// <summary> /// 自定义的错误处理过滤器 /// </summary> public class CustomErrorFilter :Attribute, IExceptionFilter { private readonly ILogger _logger; private IHostingEnvironment _environment; public CustomErrorFilter(ILogger<CustomErrorFilter> logger,IHostingEnvironment environment) { _logger = logger; _environment = environment; } public void OnException(ExceptionContext context) { Exception ex = context.Exception; string errorMsg = $"错误消息:{ex.Message}{Environment.NewLine}错误追踪:{ex.StackTrace}"; ContentResult result = new ContentResult { ContentType = "text/json;charset=utf-8;", StatusCode = 500 }; //无论是否为开发环境都记录错误日志 _logger.LogError(errorMsg); //浏览器在开发环境显示详细错误信息,其他环境隐藏错误信息 if (_environment.IsDevelopment()) { result.Content = $"错误消息:{ex.Message}{Environment.NewLine}错误追踪:{ex.StackTrace}"; } else { result.Content = "抱歉,服务端出错了"; } context.Result = result; context.ExceptionHandled = true; } }
修改StartUp类,注入nlog,配置全局过滤器,代码如下,其中nlog.config和中间件栗子中一样:
public class Start 576 up { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // 依赖注入 public void ConfigureServices(IServiceCollection services) { services.AddMvc( configure => { configure.Filters.Add<CustomErrorFilter>();//全局过滤器,不用添加特性头 }//全局过滤器,不用添加特性头 ).SetCompatibilityVersion(CompatibilityVersion.Version_2_2); //services.AddScoped<CustomErrorFilter>();//局部过滤器,需要在Controller/Action添加特性头 [ServiceFilter(typeof(CustomErrorFilter))] } // 配置管道 public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory factory) { factory.AddNLog(); env.ConfigureNLog("nlog.config"); app.UseMvc(); } }
然后修改ValuesController,设置错误和上边中间件的栗子一样,运行代码访问/values/1时,在开发环境中显示如下,同时错误信息也会写入错误日志中:
在生产环境中访问/values/1的话,错误详细也会写入错误日志中,浏览器显示如下:
本文介绍了中间件的基本使用,同时使用中间件和过滤器两种方式实现了异常日志的记录,如果文中有错误的地方希望大家可以指出,我会及时改正。
参考文章
【1】https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/logging/?view=aspnetcore-3.0
【2】https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.0
- Global.asax的Application_Error实现错误记录/错误日志的代码
- ASP.NET记录错误日志的实现方法
- [置顶] 利用Global.asax的Application_Error实现错误记录,错误日志
- 实现Nginx中使用PHP-FPM时记录PHP错误日志的配置方法
- 如何覆盖PB的系统函数 比如Messagebox 以记录Messagebox错误日志 或者实现MESSAGEBOX信息的翻译
- Laravel框架实现利用中间件进行操作日志记录功能
- node错误处理与日志记录的实现
- WebAPI 用ExceptionFilterAttribute实现错误(异常)日志的记录(log4net做写库操作)
- 实现Nginx中使用PHP-FPM时记录PHP错误日志的配置方法
- 实现Nginx中使用PHP-FPM时记录PHP错误日志的配置方法
- Jersey使用注解和过滤器实现日志记录
- Global.asax的Application_Error实现错误记录/错误日志的代码
- ASP.NET记录错误日志的实现方法
- 实现Nginx中使用PHP-FPM时记录PHP错误日志的配置方法
- oracle实现对表dml错误记录日志
- ASP.NET记录错误日志的实现方法
- 利用Global.asax的Application_Error实现错误记录,错误日志
- .NET Core微服务之基于Exceptionless实现分布式日志记录
- tp5框架使用composer实现日志记录功能示例
- shell将脚本输出结果记录到日志文件的实现