• 探索ASP.Net Core 3.0系列六:ASP.NET Core 3.0新特性启动信息中的结构化日志


    前言:在本文中,我将聊聊在ASP.NET Core 3.0中细小的变化——启动时记录消息的方式进行小的更改。 现在,ASP.NET Core不再将消息直接记录到控制台,而是正确使用了logging 基础结构,来生成结构化日志。

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

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

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

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

    探索ASP.Net Core 3.0系列四:在ASP.NET Core 3.0的应用中启动时运行异步任务

    探索 ASP.Net Core 3.0系列五:引入IHostLifetime并弄清Generic Host启动交互

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

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

     这些消息由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中的微小变化为我们提供了两全其美的方法!

    二、在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实现使用相同的方法通过标准日志记录基础结构来写入日志文件。

    三、使用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

    四、总结

    在本文中,我展示了如何在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/

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

  • 相关阅读:
    杀死JS错误提示
    年月日时分秒加星期即时显示的JS日期时间特效
    用JS自动缩小超出大小的图片
    实现简单的FAQ折叠效果
    复制本贴地址传给QQ/MSN好友的代码
    java初学者笔记总结day1
    java初学者笔记总结day2
    java初学者笔记总结day3
    IIS7.5应用程序池集成模式和经典模式的区别介绍
    div模拟textarea文本域轻松实现高度自适应
  • 原文地址:https://www.cnblogs.com/runningsmallguo/p/11618312.html
Copyright © 2020-2023  润新知