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

相關文章
相關標籤/搜索