ASP.NET Core:ASP.NET Core中使用NLog记录日志

2024-01-21 12:08

本文主要是介绍ASP.NET Core:ASP.NET Core中使用NLog记录日志,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、前言

在所有的应用程序中,日志功能是不可或缺的模块,我们可以根据日志信息进行调试、查看产生的错误信息,在ASP.NET Core中我们可以使用log4net或者NLog日志组件来实现记录日志的功能,这里讲解如何在ASP.NET Core中使用NLog。

这里采用的是.NET Core 3.1创建应用程序。

那么什么是NLog呢?

NLog是一个基于.NET平台编写的类库,我们可以使用NLog在应用程序中添加即为完善的跟踪调试代码。

NLog是一个简单灵活的.NET日志记录类库。通过使用NLog,我们可以在任何一种.NET语言中输出带有上下文的调试诊断信息,根据个人的爱好配置其输出的样式,然后发送到一个或多个输出目标(target)中。

NLog的API非常类似于log4net,且配置方式非常简单。NLog使用路由表进行配置,这样就让NLog的配置文件非常容易阅读,并便于今后维护。

NLog遵循BSD license,即允许商业应用且完全开放源代码。任何人都可以免费使用并对其进行测试,然后通过邮件列表反馈问题以及建议。

NLog支持.NET、C/C++以及COM组件,因此我们的程序、组件、包括用C++/COM编写的遗留模块都可以通过同一个路由引擎将信息发送至NLog中。

简单来说,NLog就是用来记录项目日志的组件。

二、使用NLog

首先我们创建一个WebAPI的项目:

1、引入NLog

直接在NuGet里面搜索NLog.Web.AspNetCore,然后进行安装即可,如下图所示:

安装完成以后在依赖项里面就可以看到了:

修改Program类,在里面配置使用NLog,代码如下所示:

复制代码

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using NLog.Web;namespace NLogDemo
{public class Program{public static void Main(string[] args){CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();})// 配置使用NLog.UseNLog();}
}

复制代码

2、添加配置文件

右键添加新建项,然后选择Web配置文件,命名为nlog.config如下图所示:

nlog.config文件结构如下:

复制代码

<?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"throwConfigExceptions="true"internalLogLevel="info"internalLogFile="E:\log\internal-nlog.txt"><!--autoReload:修改后自动加载,可能会有延迟--><!--throwConfigExceptions:NLog日志系统抛出异常--><!--internalLogLevel:内部日志的级别--><!--internalLogFile:内部日志保存路径,日志的内容大概就是NLog的版本信息,配置文件的地址等等--><!--输出日志的配置,用于rules读取--><targets><!--write logs to file--><!--将日志写入文件中,fileName可以指定日志生成的路径--><target xsi:type="File" name="allfile" fileName="D:\Log\nlog-all-${shortdate}.log"layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" /><!--同样是将文件写入日志中,写入的内容有所差别,差别在layout属性中体现。写入日志的数量有差别,差别在路由逻辑中体现--><target xsi:type="File" name="ownFile-web" fileName="D:\Log\nlog-my-${shortdate}.log"layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" /><target xsi:type="Null" name="blackhole" /></targets><rules><!--路由顺序会对日志打印产生影响。路由匹配逻辑为顺序匹配。--><!--All logs, including from Microsoft--><logger name="*" minlevel="Trace" writeTo="allfile" /><!--Skip Microsoft logs and so log only own logs--><!--以Microsoft打头的日志将进入此路由,由于此路由没有writeTo属性,所有会被忽略--><!--且此路由设置了final,所以当此路由被匹配到时。不会再匹配此路由下面的路由。未匹配到此路由时才会继续匹配下一个路由--><logger name="Microsoft.*" minlevel="Trace"  final="true" /><!--上方已经过滤了所有Microsoft.*的日志,所以此处的日志只会打印除Microsoft.*外的日志--><logger name="*" minlevel="Trace" writeTo="ownFile-web" /></rules>
</nlog> 

复制代码

添加完配置文件以后,我们还需要修改配置文件的属性,设置为始终复制,如下图所示:

3、在控制器中使用

通过上面的步骤,我们已经完成NLog的配置,接下来我们就可以在控制器中使用了,通过构造函数注入的方式实现注入。控制器代码如下:

复制代码

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;namespace NLogDemo.Controllers
{[Route("api/[controller]")][ApiController]public class NLogTestController : ControllerBase{private readonly ILogger<NLogTestController> _logger;public NLogTestController(ILogger<NLogTestController> logger){_logger = logger;}[HttpGet]public IActionResult Get(){_logger.LogError("这是错误信息");_logger.LogDebug("这是调试信息");_logger.LogInformation("这是提示信息");return Ok();}}
}

复制代码

运行程序,访问nlogtest控制器,然后查看是否有日志生成:

我们在nlog.config里面配置的文件路径是D:\Log,从上面的截图中看到,有日志生成了 。这里生成了两个日志文件,这是因为我们在nlog.config里面配置的日志级别不同。日志内容如下:

可以看到,启动过程中的Microsoft日志也输出了,如果不想输出Microsoft日志,修改nlog.config里rules节点下面的路径规则顺序即可。

4、读取指定位置的配置文件

上面的例子中,我们是直接在项目的根目录下面添加的nlog.config文件,有时候我们想把程序里面的配置文件都放到单独的文件夹里面,这样方便管理,那么该如何设置让程序读取指定位置的nlog.config文件呢?看下面的例子。

新建一个文件夹,命名为XmlConfig,然后把nlog.config文件移到到XmlConfig文件夹下面,移到后的结构如下图所示:

然后修改Program文件,在程序里面设置读取XmlConfig文件夹下面的nlog.config文件,代码如下:

复制代码

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using NLog.Web;namespace NLogDemo
{public class Program{public static void Main(string[] args){// 设置读取指定位置的nlog.config文件NLogBuilder.ConfigureNLog("XmlConfig/nlog.config");CreateHostBuilder(args).Build().Run();}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();})// 配置使用NLog.UseNLog();}
}

复制代码

这样就可以读取XmlConfig文件夹下面的配置文件了。

5、封装

上面的例子中,最后输出的日志格式是根据nlog.config配置文件里面的layout样式输出的,有时候输出的内容可能不满足我们的需求,我们可以对程序中的日志功能模块进行封装,输出我们自己定义的日志格式。

在解决方案中添加一个类库,命名为Nlog.Framework,然后在类库中添加一个Log文件夹,把所有Log相关的文件都放到该文件夹下,添加后的项目结构如下图所示:

添加LogMessage类,里面是要记录的一些信息属性字段:

复制代码

using System;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; }}
}

复制代码

添加一个格式化类,用来格式化日志输出内容:

复制代码

using System.Text;namespace Nlog.Framework.Log
{/// <summary>/// 格式化输出样式/// </summary>public class LogFormat{public static string ErrorFormat(LogMessage logMessage){StringBuilder strInfo = new StringBuilder();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("-----------------------------------------------------------------------------------------------------------------------------\r\n");return strInfo.ToString();}}
}

复制代码

这里使用依赖注入的方式,所以我们首先定义一个接口,代码如下:

复制代码

using System;namespace Nlog.Framework.Log
{public interface INLogHelper{void LogError(Exception ex);}
}

复制代码

然后定义接口的实现类,代码如下:

复制代码

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;namespace Nlog.Framework.Log
{public class NLogHelper : INLogHelper{//public static Logger logger { get; private set; }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;elselogMessage.LogInfo = ex.Message;logMessage.StackTrace = ex.StackTrace;logMessage.OperationTime = DateTime.Now;logMessage.OperationName = "admin";_logger.LogError(LogFormat.ErrorFormat(logMessage));}}
}

复制代码

为了演示效果,我们添加一个全局异常过滤器,代码如下:

复制代码

using Microsoft.AspNetCore.Mvc.Filters;
using Nlog.Framework.Log;
using System.Threading.Tasks;namespace NLogDemo.Filter
{/// <summary>/// 异步版本自定义全局异常过滤器/// </summary>public class CustomerGlobalExceptionFilterAsync : 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 == false){// 记录错误信息_logHelper.LogError(context.Exception);// 设置为true,表示异常已经被处理了,其它捕获异常的地方就不会再处理了context.ExceptionHandled = true;}return Task.CompletedTask;}}
}

复制代码

接着添加一个控制器,在控制器里面模拟发生错误的操作,代码如下:

复制代码

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;namespace NLogDemo.Controllers
{[Route("api/[controller]")][ApiController]public class ValuesController : ControllerBase{/// <summary>/// 日志/// </summary>private readonly ILogger<ValuesController> _logger;public ValuesController(ILogger<ValuesController> logger){_logger = logger;}[HttpGet]public IActionResult Test(){_logger.LogError("测试封装日志");int i = 0;int result = 10 / i;return Ok();}}
}

复制代码

修改Program类:

复制代码

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using NLog;
using NLog.Web;
using System;namespace NLogDemo
{public class Program{public static void Main(string[] args){// 读取指定位置的配置文件var logger = NLogBuilder.ConfigureNLog("XmlConfig/nlog.config").GetCurrentClassLogger();try{logger.Info("Init Main");CreateHostBuilder(args).Build().Run();}catch (Exception ex){logger.Error(ex, "Stopped program because of exception");}finally{LogManager.Shutdown();}}public static IHostBuilder CreateHostBuilder(string[] args) =>Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder =>{webBuilder.UseStartup<Startup>();})// 配置使用NLog.UseNLog();}
}

复制代码

最后在Startup类里面注入:

复制代码

public void ConfigureServices(IServiceCollection services)
{#region 添加异常处理过滤器services.AddControllers(options => options.Filters.Add(typeof(CustomerGlobalExceptionFilterAsync)));#endregionservices.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();services.AddSingleton<INLogHelper, NLogHelper>();// NLogHelper.LoadLogger();services.AddControllers();
}

复制代码

这样就完成了一个简单的封装,运行程序,访问value控制器测试:

上面的例子中,只是封装了Error,如果是其他级别的日志,可以自己封装。

 

测试git地址:https://gitee.com/songjuntao/nlogdemo

这篇关于ASP.NET Core:ASP.NET Core中使用NLog记录日志的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/629490

相关文章

C#使用Spire.XLS快速生成多表格Excel文件

《C#使用Spire.XLS快速生成多表格Excel文件》在日常开发中,我们经常需要将业务数据导出为结构清晰的Excel文件,本文将手把手教你使用Spire.XLS这个强大的.NET组件,只需几行C#... 目录一、Spire.XLS核心优势清单1.1 性能碾压:从3秒到0.5秒的质变1.2 批量操作的优雅

Kotlin 枚举类使用举例

《Kotlin枚举类使用举例》枚举类(EnumClasses)是Kotlin中用于定义固定集合值的特殊类,它表示一组命名的常量,每个枚举常量都是该类的单例实例,接下来通过本文给大家介绍Kotl... 目录一、编程枚举类核心概念二、基础语法与特性1. 基本定义2. 带参数的枚举3. 实现接口4. 内置属性三、

Java List 使用举例(从入门到精通)

《JavaList使用举例(从入门到精通)》本文系统讲解JavaList,涵盖基础概念、核心特性、常用实现(如ArrayList、LinkedList)及性能对比,介绍创建、操作、遍历方法,结合实... 目录一、List 基础概念1.1 什么是 List?1.2 List 的核心特性1.3 List 家族成

Go语言使用Gin处理路由参数和查询参数

《Go语言使用Gin处理路由参数和查询参数》在WebAPI开发中,处理路由参数(PathParameter)和查询参数(QueryParameter)是非常常见的需求,下面我们就来看看Go语言... 目录一、路由参数 vs 查询参数二、Gin 获取路由参数和查询参数三、示例代码四、运行与测试1. 测试编程路

Python使用python-pptx自动化操作和生成PPT

《Python使用python-pptx自动化操作和生成PPT》这篇文章主要为大家详细介绍了如何使用python-pptx库实现PPT自动化,并提供实用的代码示例和应用场景,感兴趣的小伙伴可以跟随小编... 目录使用python-pptx操作PPT文档安装python-pptx基础概念创建新的PPT文档查看

C#和Unity中的中介者模式使用方式

《C#和Unity中的中介者模式使用方式》中介者模式通过中介者封装对象交互,降低耦合度,集中控制逻辑,适用于复杂系统组件交互场景,C#中可用事件、委托或MediatR实现,提升可维护性与灵活性... 目录C#中的中介者模式详解一、中介者模式的基本概念1. 定义2. 组成要素3. 模式结构二、中介者模式的特点

MySQL中优化CPU使用的详细指南

《MySQL中优化CPU使用的详细指南》优化MySQL的CPU使用可以显著提高数据库的性能和响应时间,本文为大家整理了一些优化CPU使用的方法,大家可以根据需要进行选择... 目录一、优化查询和索引1.1 优化查询语句1.2 创建和优化索引1.3 避免全表扫描二、调整mysql配置参数2.1 调整线程数2.

C#中SortedSet的具体使用

《C#中SortedSet的具体使用》SortedSet是.NETFramework4.0引入的一个泛型集合类,它实现了一个自动排序的集合,内部使用红黑树数据结构来维护元素的有序性,下面就来介绍一下如... 目录基础概念主要特性创建和初始化基本创建方式自定义比较器基本操作添加和删除元素查询操作范围查询集合运

C# Opacity 不透明度的具体使用

《C#Opacity不透明度的具体使用》本文主要介绍了C#Opacity不透明度的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录WinFormsOpacity以下是一些使用Opacity属性的示例:设置窗体的透明度:设置按钮的透

java -jar example.jar 产生的日志输出到指定文件的方法

《java-jarexample.jar产生的日志输出到指定文件的方法》这篇文章给大家介绍java-jarexample.jar产生的日志输出到指定文件的方法,本文给大家介绍的非常详细,对大家的... 目录怎么让 Java -jar example.jar 产生的日志输出到指定文件一、方法1:使用重定向1、