ASP.NET Core ---日志

1、日志记录:

     一、日志的做用:html

           程序中记录日志通常有两个目的,故障定位和显示程序运行状态。好的日志记录方式能够提供足够多定位问题的依据。git

 

      二、日志的等级:github

           

            有良好工做习惯的人,工做的时候会将领导交待下来的工做分为:紧急重要、重要不紧急、紧急不重要、不紧急不重要等;一样 ASP.NET Core 定义了如下日志级别(按严重性从低到高排列)。数据库

            每次写入日志时都需指定其 LogLevel。 日志级别指示严重性或重要程度。 例如,若是方法正常结束则写入 Information 日志,若是方法返回 404 返回代码则写入 Warning 日志,若是捕获未知异常则写入 Error 日志。 可使用日志级别控制写入到特定存储介质或显示窗口的日志输出量。 例如在生产中,可将全部 Information 及如下级别的日志放在卷数据存储,将全部 Warning 及以上级别的日志放在值数据存储。 在开发期间,一般要将严重性为 Warning 或以上级别的日志发送到控制台。 须要进行故障排除时,可添加 Debug 级别。json

  • Trace = 0

           表示仅对于开发人员调试问题有价值的信息。 这些消息可能包含敏感应用程序数据,所以不得在生产环境中启用它们。 默认状况下禁用。 示例:Credentials: {"User":"someuser", "Password":"P@ssword"}windows

  • Debug = 1

           表示在开发和调试过程当中短时间有用的信息。 示例:Entering method Configure with flag set to true.。除非要排查问题,不然一般不会在生产中启用 Debug 级别日志,由于日志数量过多。api

  • Information = 2

           用于跟踪应用程序的常规流。 这些日志一般有长期价值。 示例:Request received for path /api/todo服务器

  • Warning = 3

           表示应用程序流中的异常或意外事件。 可能包括不会中断应用程序运行但仍需调查的错误或其余条件。 Warning 日志级别经常使用于已处理的异常。 示例:FileNotFoundException for file quotes.txt.app

  • Error = 4

           表示没法处理的错误和异常。 这些消息指示的是当前活动或操做(如当前 HTTP 请求)中的失败,而不是应用程序范围的失败。日志消息示例:Cannot insert record due to duplicate key violation.asp.net

  • Critical = 5

           须要当即关注的失败。 例如数据丢失、磁盘空间不足。

2、使用内置的Logger

微软官方文档:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1

由于Logger是asp.net core 的内置service,因此咱们就不须要在ConfigureService里面注册了。若是是asp.net core 1.0版本的话,咱们须要配置一个或者多个Logger,可是asp.net core 2.0的话就不须要作这个工做了,由于在CreateDefaultBuilder方法里默认给配置了输出到Console和Debug窗口的Logger。这是源码:

public static IWebHostBuilder CreateDefaultBuilder(string[] args) { var builder = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .ConfigureAppConfiguration((hostingContext, config) => { var env = hostingContext.HostingEnvironment; config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); if (env.IsDevelopment()) { var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName)); if (appAssembly != null) { config.AddUserSecrets(appAssembly, optional: true); } } config.AddEnvironmentVariables(); if (args != null) { config.AddCommandLine(args); } }) .ConfigureLogging((hostingContext, logging) => { logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); logging.AddConsole(); logging.AddDebug(); }) .UseIISIntegration() .UseDefaultServiceProvider((context, options) => { options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); }); if (args != null) { builder.UseConfiguration(new ConfigurationBuilder().AddCommandLine(args).Build()); } return builder; }
View Code

注入Logger

 

 

咱们能够在ProductController里面注入ILoggerFactory而后再建立具体的Logger。可是还有更好的方式,Container能够直接提供一个ILogger<T>的实例,这时候呢Logger就会使用T的名字做为日志的类别:

namespace CoreBackend.Api.Controllers { [Route("api/[controller]")] public class ProductController : Controller { private ILogger<ProductController> _logger; public ProductController(ILogger<ProductController> logger) { _logger = logger; } ......

若是经过Constructor注入的方式不可用,那么咱们也能够直接从Container请求来获得它:HttpContext.RequestServices.GetService(typeof(ILogger<ProductController>)); 若是你在Constructor写这句话可能会空指针,由于这个时候HttpContext应该是null吧。

不过仍是建议使用Constructor注入的方式!!!

而后咱们记录一些日志吧:

[Route("{id}", Name = "GetProduct")] public IActionResult GetProduct(int id) { var product = ProductService.Current.Products.SingleOrDefault(x => x.Id == id); if (product == null) { _logger.LogInformation($"Id为{id}的产品没有被找到.."); return NotFound(); } return Ok(product); }

Log记录时通常都分几个等级,这点我假设你们都知道吧,就不介绍了。

而后试一下:经过Postman访问一个不存在的产品:‘/api/product/22’,而后看看Debug输出窗口:

嗯,出现了,前边是分类,也就是ILogger<T>里面T的名字,而后是级别 Information,而后就是咱们记录的Log内容。

再Log一个Exception:

[Route("{id}", Name = "GetProduct")] public IActionResult GetProduct(int id) { try { throw new Exception("来个异常!!!"); var product = ProductService.Current.Products.SingleOrDefault(x => x.Id == id); if (product == null) { _logger.LogInformation($"Id为{id}的产品没有被找到.."); return NotFound(); } return Ok(product); } catch (Exception ex) { _logger.LogCritical($"查找Id为{id}的产品时出现了错误!!", ex); return StatusCode(500, "处理请求的时候发生了错误!"); } }

记录Exception就建议使用LogCritical了,这里须要注意的是Exception的发生就表示服务器发生了错误,咱们应该处理这个exception并返回500。使用StatusCode这个方法返回特定的StatusCode,而后能够加一个参数来解释这个错误(这里通常不建议返回exception的细节)。

运行试试:

OK。

Log到Debug窗口或者Console窗口仍是比较方便的,可是正式生产环境中这确定不够用。

正式环境应该Log到文件或者数据库。虽然asp.net core 的log内置了记录到Windows Event的方法,可是因为Windows Event是windows系统独有的,因此这个方法没法跨平台,也就不建议使用了。

官方文档上列出了这几个建议使用的第三发Log Provider:

把这几个Log provider注册到asp.net core的方式几乎是一摸同样的,因此介绍一个就行。咱们就用比较火的NLog吧。

 

 

3、NLog

官方文档:https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-Core-2

首先经过nuget安装Nlog: 

注意要勾上include prerelease,目前还不是正式版。

装完以后,咱们就须要为Nlog添加配置文件了。默认状况下Nlog会在根目录寻找一个叫作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">
  <targets>
    <target name="logfile" xsi:type="File" fileName="logs/${shortdate}.log" />

  </targets>
  <rules>
    <logger name="*" minlevel="Info" writeTo="logfile" />
  </rules>
</nlog>

而后设置该文件的属性以下:

对于Nlog的配置就不进行深刻介绍了。具体请看官方文档的.net core那部分。

而后须要把Nlog集成到asp.net core,也就是把Nlog注册到ILoggerFactory里面。因此打开Startup.cs,首先注入ILoggerFactory,而后对ILoggerFactory进行配置,为其注册NLog的Provider:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { // loggerFactory.AddProvider(new NLogLoggerProvider());
 loggerFactory.AddNLog(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler(); } app.UseStatusCodePages(); app.UseMvc(); }

针对LoggerFactory.AddProvider()这种写法,Nlog一个简单的ExtensionMethod作了这个工做,就是AddNlog();

添加完NLog,其他的代码都不须要改,而后咱们试下:

在如图所示的位置出现了log文件。内容以下:

 

4、Serilog

           官方文档:    Asp.net core  https://github.com/serilog/serilog-aspnetcore         

                             Sinks-file: https://github.com/serilog/serilog-sinks-file       

                             Sinks-Console:https://github.com/serilog/serilog-sinks-console

          (1) 添加:Serilog

                       

 

 

 

 

 参考资料:

           https://www.cnblogs.com/cgzl/p/7652413.html

           https://v.qq.com/x/page/m0762gzo2l6.html

           https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.1

相关文章
相关标签/搜索