《ASP.NET Core技术内幕与项目实战》精简集-基础组件1.4:日志
本节内容,涉及3.3(P70-P74),书中内容较少,Nlog、Serilog及集中化日志,需要看配套视频。主要NuGet包
- Microsoft.Extensions.Logging
- Microsoft.Extensions.Logging.Console
- Nlog.Extensions.Logging
- NLog.Web.AspNetCore
- Serilog.AspNetCore
- ...
一、.NET内置日志提供程序Console的使用
1 //Program.cs类,使用了Net6的顶级语句 2 ServiceCollection services = new ServiceCollection(); 3 services.AddLogging(logBuilder => 4 { 5 logBuilder.AddConsole(); 6 }); 7 8 9 using var sp = services.BuildServiceProvider(); 10 var logger = sp.GetRequiredService<ILogger<Program>>(); 11 logger.LogDebug("这是一条调试信息"); 12 logger.LogWarning("这是一条警告信息"); 13 logger.LogError("这是一条错误信息"); 14 15 string name = "functionMC"; 16 logger.LogInformation($"姓名是{name}"); 17 18 try 19 { 20 int i = int.Parse(name); 21 } 22 catch (Exception ex) 23 { 24 25 logger.LogError(ex, "解析字符串失败"); 26 }
代码解读:
3-5行:在依赖注入容器中注册Logging服务,并设置日志提供程序为.NET框架内置的Console(控制台日志)
9-10行:通过服务定位器的方式,获取ILogger<T>服务对象logger
11-26行:向控制台输出不同级别的日志信息
补充说明:
①ILogger<T>,是框架抽像出来的服务类,可以配置不同的实现类(日志提供程序),可以替换成Nlog等,体现了面向接口编程
②日志输入级别包括了:Trace、Debug、Information、Warning、Error、Critical,中间四个比较常用
③在ASP.NET Core中使用时,框架默认注册了日志服务,可以直接注入"ILogger<T> logger"使用
二、Nlog日志提供程序的使用
1 //项目根目录下,新建nlog.config配置文件 2 <?xml version="1.0" encoding="utf-8" ?> 3 <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 autoReload="true" 6 internalLogLevel="Info" 7 internalLogFile="c:\temp\internal-nlog-AspNetCore.txt"> 8 <extensions> 9 <add assembly="NLog.Web.AspNetCore"/> 10 </extensions> 11 12 13 <!-- 配置日志写入的目标Target --> 14 <targets> 15 <!-- 目标类型为file,目标名称为allfile,文件目录fileName...,日志格式layout...,最大文件大小archiveAboveSize...,最多文件数maxArchiveFiles... --> 16 <target xsi:type="File" name="allfile" fileName="d:\temp\nlog-AspNetCore-all-${shortdate}.log" archiveAboveSize="100000" maxArchiveFiles="3" 17 layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}" /> 18 <!-- 目标类型为file,目标名称为ownFile-web,文件目录fileName...,日志格式layout... --> 19 <target xsi:type="File" name="ownFile-web" fileName="d:\temp\nlog-AspNetCore-own-${shortdate}.log" 20 layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}" /> 21 <!--目标类型为Console,目标名称为lifetimeConsole,日志格式layout... --> 22 <target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" /> 23 </targets> 24 25 26 <!-- 根据不同规则,将日志写入相应的目标 --> 27 <rules> 28 <!--目标-allfile,日志名称-所有, 日志等级-Trace及以上--> 29 <logger name="*" minlevel="Trace" writeTo="allfile" /> 30 <!--目标-lifetimeConsole和ownFile-web,日志名称-Microsoft.Hosting.Lifetime, 日志等级-Trace及以上,是否是匹配终点-是 --> 31 <logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole, ownFile-web" final="true" /> 32 <!--跳过Microsoft内置的非关键日志,所以只记录应用自定义的日志 --> 33 <logger name="Microsoft.*" maxlevel="Info" final="true" /> 34 <logger name="System.Net.Http.*" maxlevel="Info" final="true" /> 35 <logger name="*" minlevel="Trace" writeTo="ownFile-web" /> 36 </rules> 37 </nlog> 38 39 40 //Program.cs中配置Nlog,使用logger 41 var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); 42 logger.Debug("在Program中使用logger"); 43 44 var builder = WebApplication.CreateBuilder(args); 45 builder.Logging.ClearProviders(); 46 builder.Host.UseNLog(); 47 48 var app = builder.Build(); 49 app.MapGet("/", (ILogger<Program> logger) => 50 { 51 logger.LogWarning("这是警告信息!"); 52 }); 53 54 app.Run();
代码解读:
2-37行:Nlog的配置文件,注意配置的文件名称为nlog.config(要小写)
14-23行:配置Nlog的日志输出目标,主要包括目标名称、目标类型、文件目录、日志格式、最大文件大小、最多文件数等属性
27-36行:配置日志处理的规则,即规定哪些日志输出到哪些目标。
41-42行:通过NLog.LogManager,创建logger对象。在Program类中输出日志
45-46行:清除ASP.NET Core框架内置的日志提供程序,使用Nlog日志提供程序。其中builder.Host返回ConfigureHostBuilder
49-52行:在minimalAPI中,参数注入ILogger,并输入日志
补充说明:
①官方推荐使用nlog.config进行Nlog的配置,但Nlog也可以在appsettings中进行配置
②Nlog输出日志的方式有两种:一是使用Nlog.LogManager创建logger对象;二是通过依赖注入获得logger对象
③Nlog的输出目标有很多,比如常见的console、file、database、email等,甚至也可以输出到集中化日志提供商
④日志处理规则rules的基本逻辑:当ILogger输出一条日志后,交给Nlog。Nlog从上到下,依次对照每条rule,符合规则的,就写入相应目标。一条日志,可能符合多条规则。特殊的是设置了final=true的规则,如果日志符合这条规则,则不再向下匹配
⑤注册Nlog的方式还有好几种,如:builder.Logging.AddNLog();再如:builder.Services.AddLogging(logBuilder =>{ logBuilder.AddNLog(); });
⑥无论是Nlog还是Serilog的使用,了解和掌握基本原理即可,具体使用的时候可以再查文档,更多时候,像ABP或者MASA等框架时,都已经帮我们封装好。
三、Serilog日志提供程序的使用
1 //注册和配置Serilog日志提供程序 2 //Program.cs 3 public class Program 4 { 5 public static void Main(string[] args) 6 { 7 var builder = WebApplication.CreateBuilder(args); 8 9 // 注册和配置Serilog 10 //builder.Logging.ClearProviders(); 11 builder.Services.AddLogging(logBuilder => 12 { 13 Log.Logger = new LoggerConfiguration() 14 .MinimumLevel.Warning() 15 .Enrich.FromLogContext() 16 .WriteTo.Console(new JsonFormatter()) 17 .CreateLogger(); 18 logBuilder.AddSerilog(); 19 20 }); 21 22 builder.Services.AddControllers(); 23 builder.Services.AddEndpointsApiExplorer(); 24 builder.Services.AddSwaggerGen(); 25 26 var app = builder.Build(); 27 if (app.Environment.IsDevelopment()) 28 { 29 app.UseSwagger(); 30 app.UseSwaggerUI(); 31 } 32 app.UseHttpsRedirection(); 33 app.UseAuthorization(); 34 app.MapControllers(); 35 app.Run(); 36 } 37 } 38 39 40 //在控制器中输出日志 41 //HomeController.cs 42 [ApiController] 43 [Route("api/[controller]/[action]")] 44 public class HomeController : ControllerBase 45 { 46 private readonly ILogger<HomeController> logger; 47 public HomeController(ILogger<HomeController> logger) 48 { 49 this.logger = logger; 50 } 51 52 [HttpGet] 53 public string LogPerson() 54 { 55 logger.LogWarning("这是Serilog的警告信息"); 56 var person = new { name = "functionMC" }; 57 var age = 23; 58 logger.LogError("姓名: {@Person} , 年龄: {Age}", person, age); 59 60 return "请到控制台查看日志"; 61 } 62 }
代码解读:
11-20行:注册和配置Serilog
46-50行:在控制器中,注入ILogger服务
55-58行:输入日志
补充说明:
①Serilog与Nlog的最大区别,Serilog通过简单的方式,实现了日志的结构化输出(Json格式),方便进行日志信息的检索和加工处理
②以上案例仅展示了Serilog最简单的配置,和Nlog一样,它也可以实现复杂的配置,具体使用时可以查阅文档
③Console、Nlog、Serilog,三者均可以通过builder.Services.AddLogging()进行注册,这是推荐方式
四、集中化日志提供程序的使用(略)
特别说明:
1、本系列内容主要基于杨中科老师的书籍《ASP.NET Core技术内幕与项目实战》及配套的B站视频视频教程,同时会增加极少部分的小知识点
2、本系列教程主要目的是提炼知识点,追求快准狠,以求快速复习,如果说书籍学习的效率是视频的2倍,那么“简读系列”应该做到再快3-5倍