我在哪里可以记录ASP.NET Core应用程序的启动/停止/错误事件?

gro*_*kky 20 c# asp.net asp.net-core

在旧的ASP.NET中,在Global.asax.cs类中,我会在应用程序启动时记录,停止并抛出未处理的异常:

  • Application_Start()
  • Application_End()
  • Application_Error()

我如何在ASP.NET Core中执行相同的操作?它有一个Startup类,但它用于配置.

我在哪里挂钩应用程序的开始/停止/错误事件?

Set*_*Set 25

您需要使用Microsoft.AspNetCore.Hosting.IApplicationLifetime

    /// <summary>
    /// Triggered when the application host has fully started and is about to wait
    /// for a graceful shutdown.
    /// </summary>
    CancellationToken ApplicationStarted { get; }

    /// <summary>
    /// Triggered when the application host is performing a graceful shutdown.
    /// Requests may still be in flight. Shutdown will block until this event completes.
    /// </summary>
    CancellationToken ApplicationStopping { get; }

    /// <summary>
    /// Triggered when the application host is performing a graceful shutdown.
    /// All requests should be complete at this point. Shutdown will block
    /// until this event completes.
    /// </summary>
    CancellationToken ApplicationStopped { get; }
Run Code Online (Sandbox Code Playgroud)

IApplicationLifetime的实例可以通过Configure方法获得.另外在这里添加ILoggerFactory:

public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime, ILoggerFactory loggerFactory)
{
    // use applicationLifetime
}
Run Code Online (Sandbox Code Playgroud)

拥有ILoggerFactory,您可以创建以下实例ILogger:

var logger = loggerFactory.CreateLogger("StartupLogger"); 
Run Code Online (Sandbox Code Playgroud)

所以你只需要在Startup类中创建一个属性来持久保存实例ILogger(或者ILoggerFactory,如果你想为不同的事件创建不同的ligger实例).总结一下:

public class Startup 
{
    private ILogger _logger;

    public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime, ILoggerFactory loggerFactory) 
    {
        applicationLifetime.ApplicationStopping.Register(OnShutdown);
        ... 
        // add logger providers
        // loggerFactory.AddConsole()
        ...
        _logger = loggerFactory.CreateLogger("StartupLogger");
    }

    private void OnShutdown()
    {
         // use _logger here;
    }
}
Run Code Online (Sandbox Code Playgroud)


Jas*_*dge 12

我不喜欢@neustart47的回答,因为它不必要地复杂,但他是对的,这已经IApplicationLifetime过时了。

摘自微软文档

//  1. Add the interface `IHostedService` to the class you would like
//     to be called during an application event. 
internal class LifetimeEventsHostedService : IHostedService
{
    private readonly ILogger _logger;
    private readonly IHostApplicationLifetime _appLifetime;

    // 2. Inject `IHostApplicationLifetime` through dependency injection in the constructor.
    public LifetimeEventsHostedService(
        ILogger<LifetimeEventsHostedService> logger, 
        IHostApplicationLifetime appLifetime)
    {
        _logger = logger;
        _appLifetime = appLifetime;
    }

    // 3. Implemented by `IHostedService`, setup here your event registration. 
    public Task StartAsync(CancellationToken cancellationToken)
    {
        _appLifetime.ApplicationStarted.Register(OnStarted);
        _appLifetime.ApplicationStopping.Register(OnStopping);
        _appLifetime.ApplicationStopped.Register(OnStopped);

        return Task.CompletedTask;
    }

    // 4. Implemented by `IHostedService`, setup here your shutdown registration.
    //    If you have nothing to stop, then just return `Task.CompletedTask`
    public Task StopAsync(CancellationToken cancellationToken)
    {
        return Task.CompletedTask;
    }

    private void OnStarted()
    {
        _logger.LogInformation("OnStarted has been called.");

        // Perform post-startup activities here
    }

    private void OnStopping()
    {
        _logger.LogInformation("OnStopping has been called.");

        // Perform on-stopping activities here
    }

    private void OnStopped()
    {
        _logger.LogInformation("OnStopped has been called.");

        // Perform post-stopped activities here
    }
}
Run Code Online (Sandbox Code Playgroud)

附加信息

将上面的类添加到您的项目后,转到您的Program.cs文件并添加如下所示的调用以注入服务(并实例化该类): builder.Services.AddHostedService<LifetimeEventsHostedService>();

添加后,再次构建并运行应用程序,您将看到日志语句...

"OnStarted has been called."
Run Code Online (Sandbox Code Playgroud)

ETC。

完毕!

  • 这按预期工作。`LifetimeEventsHostedService` 必须[在启动时注册为托管服务](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-5.0&amp;tabs=visual -工作室)。 (6认同)

Jon*_*ved 5

请参阅CaptureStartupErrors.CaptureStartupErrors(true)可帮助您发现问题的方法。

当某些东西在localhost上运行完美但在Azure中失败时,这特别方便。

这是我通常用于NetCore Web Apps的配置:

public static IWebHost BuildWebHost(string[] args) => WebHost
            .CreateDefaultBuilder(args)
            .CaptureStartupErrors(true)
            .UseKestrel()
            .UseIISIntegration()
            .UseStartup<Startup>()
            .UseAzureAppServices()
            .Build();
Run Code Online (Sandbox Code Playgroud)

然后,在Azure App Service中,您可以在Kudu工具中的日志流中找到日志 https://<appname>.scm.azurewebsites.net/api/logstream

  • 链接页面不再提及“CaptureStartupErrors” - 还需要吗? (2认同)