.NET Core中使用NLog之封装、过滤器、注入全局使用
上篇咋们聊到NLog在Core中比较基础的使用,这篇接着上篇,对NLog做下封装和过滤器集成,然后全局使用
说道这里咋们想说说过滤器Filter,Filter其实
是延续ASP.NET MVC的产物,同样保留了五种的Filter,分别是Authorization Filter、Resource Filter、Action Filter、Exception Filter及Result Filter。
本篇咋们就用NLog日志记录结合Filter中的Exception Filter异常日志全局过滤器,记录全局异常日志方便咋们排错,进入主题:
1、首先咋们创建个单独的项目,命名为Nlog.Framework,然后在类库中添加一个Log文件夹,把所有Log相关的文件都放到该文件夹下,添加后的项目结构如下图所示:
2、在Log文件下创建个LogMessage类,里面是要记录的一些信息属性字段,代码如下:

using System; using System.Collections.Generic; using System.Text; namespace Nlog.Framework.Log { /// <summary> /// 日志消息 /// </summary> public class LogMessage { /// <summary> /// IP /// </summary> public string IpAddress { get; set; } /// <summary> /// 操作人 /// </summary> public string OperationName { get; set; } /// <summary> /// 操作时间 /// </summary> public DateTime OperationTime { get; set; } /// <summary> /// 日志信息 /// </summary> public string LogInfo { get; set; } /// <summary> /// 跟踪信息 /// </summary> public string StackTrace { get; set; } } }
3、在Log文件下创建个格式化LogFormat类,用来格式化日志输出内容(日志看起来没那么凌乱),代码如下:

using System; using System.Collections.Generic; using System.Text; namespace Nlog.Framework.Log { public class LogFormat { public static string ErrorFormat(LogMessage logMessage) { StringBuilder strInfo = new StringBuilder(); strInfo.Append("\r\n"); strInfo.Append("1. 操作时间: " + logMessage.OperationTime + " \r\n"); strInfo.Append("2. 操作人: " + logMessage.OperationName + " \r\n"); strInfo.Append("3. Ip : " + logMessage.IpAddress + "\r\n"); strInfo.Append("4. 错误内容: " + logMessage.LogInfo + "\r\n"); strInfo.Append("5. 跟踪: " + logMessage.StackTrace + "\r\n"); strInfo.Append("----------------------------------------------------------------END---------------------------------------------------------------\r\n"); return strInfo.ToString(); } } }
4、在Log文件下定义一个接口,代码如下:

using System; using System.Collections.Generic; using System.Text; namespace Nlog.Framework.Log { public interface INLogHelper { void LogError(Exception ex); } }
5、在Log文件下定义接口的实现类,代码如下:

using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System; namespace Nlog.Framework.Log { public class NLogHelper : INLogHelper { private readonly IHttpContextAccessor _httpContextAccessor; private readonly ILogger<NLogHelper> _logger; public NLogHelper(IHttpContextAccessor httpContextAccessor, ILogger<NLogHelper> logger) { _httpContextAccessor = httpContextAccessor; _logger = logger; } public void LogError(Exception ex) { LogMessage logMessage = new LogMessage(); logMessage.IpAddress = _httpContextAccessor.HttpContext.Request.Host.Host; if (ex.InnerException != null) logMessage.LogInfo = ex.InnerException.Message; else logMessage.LogInfo = ex.Message; logMessage.StackTrace = ex.StackTrace; logMessage.OperationTime = DateTime.Now; logMessage.OperationName = "administator"; _logger.LogError(LogFormat.ErrorFormat(logMessage)); } } }
6、添加个Filter文件夹,在当前文件夹下创建个全局异常过滤器,代码如下:

using Microsoft.AspNetCore.Mvc.Filters; using Nlog.Framework.Log; using System; using System.Threading.Tasks; namespace FristCoreProgram.Filter { public class CustomerGlobalExceptionFilterAsync : ActionFilterAttribute, IAsyncExceptionFilter { private readonly INLogHelper _logHelper; public CustomerGlobalExceptionFilterAsync(INLogHelper logHelper) { _logHelper = logHelper; } /// <summary> /// 重新OnExceptionAsync方法 /// </summary> /// <param name="context">异常信息</param> /// <returns></returns> public Task OnExceptionAsync(ExceptionContext context) { // 如果异常没有被处理,则进行处理 if (!context.ExceptionHandled) { // 记录错误信息 _logHelper.LogError(context.Exception); // 设置为true,表示异常已经被处理了,其它捕获异常的地方就不会再处理了 context.ExceptionHandled = true; } return Task.CompletedTask; } } }
7、修改Program类文件,代码如下:

public static void Main(string[] args) { //设置读取指定位置的nlog.config文件 //NLogBuilder.ConfigureNLog("XmlConfig/nlog.config"); //CreateWebHostBuilder(args).Build().Run(); //读取指定位置的NLog配置文件 var logger = NLogBuilder.ConfigureNLog("XmlConfig/nlog.config").GetCurrentClassLogger(); try { logger.Info("Init Main..."); CreateWebHostBuilder(args).Build().Run(); } catch (System.Exception ex) { logger.Error(ex, "Stopped program because of exception"); } finally { LogManager.Shutdown(); } } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() //配置使用Nlog .UseNLog();
8、在Startup类里面ConfigureServices注入全局异常过滤器,,代码如下:

public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddMvc(options => { #region NLog过滤器注册 options.Filters.Add(typeof(CustomerGlobalExceptionFilterAsync)); #endregion }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); services.AddSingleton<INLogHelper, NLogHelper>(); //services.AddControllers(); }
PS:需要注意的是,由于Core的版本不同,Startup注入过滤器时方式有所不同
本例是core2.2版本注入的方式是:
options.Filters.Add(typeof(CustomerGlobalExceptionFilterAsync));
而core3.1版本注入的方式是:
services.AddControllers(options => options.Filters.Add(typeof(CustomerGlobalExceptionFilterAsync)));
9、最后再controller模拟个异常测试过滤器,代码如下:
最最最后,访问模拟异常的Action,查看日志文件,如下:
以上完成,这里只是封装了Error,如果是其他级别的日志,可以自己封装,然后注入到Startup类中!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
2016-07-27 谷歌浏览器禁止表单自动填充