探索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启动交互spa

1、ASP.NET Core 2.x中恼人的非结构化日志

当您在ASP.NET Core 2.x中启动应用程序时,默认状况下,ASP.NET Core会将一些有关您的应用程序的信息输出到控制台,例如当前环境,内容根路径以及Kestrel正在监听的URL。:.net

 

 这些消息由WebHostBuilder写入的,目的是为您提供了应用程序的便捷概述,但它直接写入控制台中。翻译

 

这有两个主要缺点:日志

  •  这些有用的信息仅写入控制台,所以不会写入任何其余日志记录基础结构。
  • 写入控制台的消息是非结构化的,它们的格式将与写入控制台的任何其余日志不一样。 他们甚至没有日志级别或源。

最后一点特别烦人,由于在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/

本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文连接。

相关文章
相关标签/搜索