探索ASP.Net Core 3.0系列六:ASP.NET Core 3.0新特性啓動信息中的結構化日誌

原文: 探索ASP.Net Core 3.0系列六:ASP.NET Core 3.0新特性啓動信息中的結構化日誌

前言:在本文中,我將聊聊在ASP.NET Core 3.0中細小的變化——啓動時記錄消息的方式進行小的更改。 如今,ASP.NET Core再也不將消息直接記錄到控制檯,而是正確使用了logging 基礎結構,來生成結構化日誌。html

 翻譯: Andrew Lock   https://andrewlock.net/new-in-aspnetcore-3-structured-logging-for-startup-messages/app

 

 

探索ASP.NET Core 3.0系列一:新的項目文件、Program.cs和generic host異步

探索ASP.Net Core 3.0系列二:聊聊ASP.Net Core 3.0 中的Startup.cside

探索 ASP.Net Core 3.0系列三:ASP.Net Core 3.0中的Service provider validationui

探索ASP.Net Core 3.0系列四:在ASP.NET Core 3.0的應用中啓動時運行異步任務this

探索 ASP.Net Core 3.0系列五:引入IHostLifetime並弄清Generic Host啓動交互url

1、ASP.NET Core 2.x中惱人的非結構化日誌

當您在ASP.NET Core 2.x中啓動應用程序時,默認狀況下,ASP.NET Core會將一些有關您的應用程序的信息輸出到控制檯,例如當前環境,內容根路徑以及Kestrel正在監聽的URL。:spa

 

 這些消息由WebHostBuilder寫入的,目的是爲您提供了應用程序的便捷概述,但它直接寫入控制檯中。.net

 

這有兩個主要缺點:翻譯

  •  這些有用的信息僅寫入控制檯,所以不會寫入任何其餘日誌記錄基礎結構。
  • 寫入控制檯的消息是非結構化的,它們的格式將與寫入控制檯的任何其餘日誌不一樣。 他們甚至沒有日誌級別或源。

最後一點特別煩人,由於在Docker中運行時一般將結構化日誌寫入標準輸出(控制檯),而後讓另外一個進程讀取這些日誌並將其發送到中央位置(例如使用fluentd),這很常見。

 

幸運的是,在ASP.NET Core 2.1中,有一種方法可使用環境變量禁用這些消息,如我在上一篇文章中所展現的。 惟一的缺點是消息被徹底禁用,所以根本不會記錄任何方便的信息,詳細請參考這邊文章:

https://andrewlock.net/suppressing-the-startup-and-shutdown-messages-in-asp-net-core/

 

幸運的是,ASP.NET Core 3.0中的微小變化爲咱們提供了一箭雙鵰的方法!

 

2、在ASP.NET Core 3.0中正確記錄日誌

若是使用dotnet run啓動ASP.NET Core 3.0應用程序,您會注意到寫入控制檯的日誌消息中的細微差異:

 

 如今,使用結構化日誌記錄啓動消息! 可是並不像使用Logger替代Console那樣簡單。 在ASP.NET Core 2.x中,由WebHost負責記錄這些消息。 在ASP.NET Core 3.0中,這些消息由ConsoleLifetime記錄,ConsoleLifetime是通用主機註冊的默認IHostLifetime。

我在上一篇文章中描述了IhostLifetime(尤爲是ConsoleLifetime)的做用,但總而言之,該類負責偵聽控制檯中的Ctrl + C按鍵,並啓動關閉過程。

ConsoleLifetime還在其WaitForStartAsync()方法期間註冊回調,這些回調在觸發ApplicationLifetime.ApplicationStarted事件以及觸發ApplicationLifetime.ApplicationStopping事件時調用:

複製代碼
public Task WaitForStartAsync(CancellationToken cancellationToken)
{
    if (!Options.SuppressStatusMessages)
    {
        // Register the callbacks for ApplicationStarted
        _applicationStartedRegistration = ApplicationLifetime.ApplicationStarted.Register(state =>
        {
            ((ConsoleLifetime)state).OnApplicationStarted();
        },
        this);

        // Register the callbacks for ApplicationStopping
        _applicationStoppingRegistration = ApplicationLifetime.ApplicationStopping.Register(state =>
        {
            ((ConsoleLifetime)state).OnApplicationStopping();
        },
        this);
    }

    // ...

    return Task.CompletedTask;
}
複製代碼

這些回調運行簡單地寫入日誌記錄基礎結構的OnApplicationStarted()和OnApplicationStopping()方法(以下所示):

複製代碼
private void OnApplicationStarted()
{
    Logger.LogInformation("Application started. Press Ctrl+C to shut down.");
    Logger.LogInformation("Hosting environment: {envName}", Environment.EnvironmentName);
    Logger.LogInformation("Content root path: {contentRoot}", Environment.ContentRootPath);
}

private void OnApplicationStopping()
{
    Logger.LogInformation("Application is shutting down...");
}
複製代碼

儘管確切的消息略有不一樣,可是System Lifetime和Windows ServiceLifetime實現使用相同的方法經過標準日誌記錄基礎結構來寫入日誌文件。

 

3、使用ConsoleLifetime抑制啓動消息

ConsoleLifetime建立的啓動消息引發的一個使人驚訝的變化是,您將沒法再按照我在上一篇文章中描述的方式隱藏消息。 設置ASPNETCORE_SUPPRESSSTATUSMESSAGES顯然沒有任何效果-不管是否設置了環境變量,消息都將繼續記錄!

正如我已經指出的那樣,因爲使用Microsoft.Extensions.Logging基礎結構正確記錄了消息,所以這如今並非什麼大問題。 可是,若是這些消息因爲某種緣由冒犯了您,而且您真的想擺脫它們,則能夠在Startup.cs中配置ConsoleLifetimeOptions:

複製代碼
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // ... other configuration
        services.Configure<ConsoleLifetimeOptions>(opts => opts.SuppressStatusMessages = true);
    }
}
複製代碼

 

 

 如今只顯示結構化的日誌信息了。

若是須要,您甚至能夠根據ASPNETCORE_SUPPRESSSTATUSMESSAGES環境變量的存在來設置SuppressStatusMessages字段:

複製代碼
public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration) => Configuration = configuration;

    public void ConfigureServices(IServiceCollection services)
    {
        // ... other configuration
        services.Configure<ConsoleLifetimeOptions>(opts 
                => opts.SuppressStatusMessages = Configuration["SuppressStatusMessages"] != null);
    }
}
複製代碼

若是您確實選擇不顯示消息,請注意,Kestrel仍會記錄其正在監聽的URL;不然,您將保留其記錄。 沒有辦法抑制這些:

info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://0.0.0.0:5000
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: https://0.0.0.0:5001

4、總結

在本文中,我展現瞭如何在3.0中記錄結構化日誌,避免在ASP.NET Core 2.x應用程序啓動時煩人的非結構化日誌。 這樣能夠確保將日誌寫入全部已配置的記錄器,而且在寫入控制檯時具備標準格式。 我在日誌消息中描述了IhostLifetime的角色,並說明了如何配置ConsoleLifetimeOptions以根據須要禁止顯示狀態消息。

 

好了,這個系列 的文章就到此結束,後面我會再補充6篇文章,該系列就徹底結束了,剩下的 就是繼續搞秒殺項目(ASP.Net Core )的CI/CD,爭取 年前能搞定吧。

 

翻譯: Andrew Lock   https://andrewlock.net/new-in-aspnetcore-3-structured-logging-for-startup-messages/

 

做者:郭崢

出處:http://www.cnblogs.com/runningsmallguo/

本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文連接。

相關文章
相關標籤/搜索