简体   繁体   English

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

[英]Where can I log an ASP.NET Core app's start/stop/error events?

In old ASP.NET, in the Global.asax.cs class, I would log when the app starts, stops and throws unhandled exceptions:在旧的 ASP.NET 中,在Global.asax.cs类中,我会记录应用程序何时启动、停止和抛出未处理的异常:

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

How do I do the same in ASP.NET Core?我如何在 ASP.NET Core 中做同样的事情? It has a Startup class, but it is for configuration.它有一个Startup类,但它用于配置。

Where do I hook into the app's start/stop/error events?我在哪里挂钩到应用程序的开始/停止/错误事件?

You need to use Microsoft.AspNetCore.Hosting.IApplicationLifetime您需要使用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; }

Instance of IApplicationLifetime could be obtained in Configure method. IApplicationLifetime 的实例可以在Configure方法中获得。 Also add ILoggerFactory here:还要在这里添加 ILoggerFactory:

public void Configure(IApplicationBuilder app, IApplicationLifetime applicationLifetime, ILoggerFactory loggerFactory)
{
    // use applicationLifetime
}

Having ILoggerFactory , you can create instance of ILogger :拥有ILoggerFactory ,您可以创建ILogger实例:

var logger = loggerFactory.CreateLogger("StartupLogger"); 

So you just need to create a property in the Startup class to persist the instance of ILogger (or ILoggerFactory , if you would like to create different ligger instance for different events).所以你只需要在 Startup 类中创建一个属性来持久化ILogger的实例(或ILoggerFactory ,如果你想为不同的事件创建不同的 ligger 实例)。 To summarize:总结一下:

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;
    }
}

Please see CaptureStartupErrors and the method .CaptureStartupErrors(true) that will help you find issues.请参阅CaptureStartupErrors和方法.CaptureStartupErrors(true) ,这将有助于你找到问题。

This is especially handy when something runs perfect on localhost but fails in Azure.当某些东西在 localhost 上运行完美但在 Azure 中失败时,这尤其方便。

Here is my usual config for NetCore Web Apps:这是我对 NetCore Web Apps 的常用配置:

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

In Azure App Service you can then find the logs in the log stream in Kudu Tools https://<appname>.scm.azurewebsites.net/api/logstream在 Azure 应用服务中,您可以在 Kudu 工具的日志流中找到日志https://<appname>.scm.azurewebsites.net/api/logstream

I didn't like @neustart47 answer as it was unnecessarily complex but he is right that IApplicationLifetime is obsolete.我不喜欢@neustart47 的回答,因为它不必要地复杂,但他说IApplicationLifetime已经过时是对的。

Taken from the Microsoft Docs取自Microsoft Docs

//  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
    }
}

Done!完毕!

Using Microsoft.AspNetCore.Hosting.IApplicationLifetime suggested in the top answer now is obsolete.使用顶部答案中建议的Microsoft.AspNetCore.Hosting.IApplicationLifetime现在已过时。

[Obsolete("This type is obsolete and will be removed in a future version. The recommended alternative is Microsoft.Extensions.Hosting.IHostApplicationLifetime.", false)]
public interface IApplicationLifetime

Use IHostApplicationLifetime to fire callback when the application shuts down.使用IHostApplicationLifetime在应用程序关闭时触发回调。

Add somewhere:在某处添加:

public static async Task WaitForShutdownAsync(this IHost host)
{
    // Get the lifetime object from the DI container
    var applicationLifetime = host.Services.GetService<IHostApplicationLifetime>();

    // Create a new TaskCompletionSource called waitForStop
    var waitForStop = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);

    // Register a callback with the ApplicationStopping cancellation token
    applicationLifetime.ApplicationStopping.Register(obj =>
    {
        var tcs = (TaskCompletionSource<object>)obj;

        //PUT YOUR CODE HERE 

        // When the application stopping event is fired, set 
        // the result for the waitForStop task, completing it
        tcs.TrySetResult(null);
    }, waitForStop);

    // Await the Task. This will block until ApplicationStopping is triggered,
    // and TrySetResult(null) is called
    await waitForStop.Task;

    // We're shutting down, so call StopAsync on IHost
    await host.StopAsync();
}

Then I use it in Program.cs:然后我在 Program.cs 中使用它:

var host = CreateHostBuilder(args).Build();
host.WaitForShutdownAsync();

The same for other callbacks.其他回调也是如此。 More info you can find here您可以在此处找到更多信息

If I missed something please let me know如果我错过了什么,请告诉我

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在启用Windows身份验证的情况下以编程方式启动和停止ASP.NET Core 2.1应用程序? - How to start and stop an ASP.NET Core 2.1 app programmatically with Windows Authentication enabled? ASP.NET 核心 IHostedService 手动启动/停止/暂停(?) - ASP.NET Core IHostedService manual start/stop/pause(?) 在 asp.net 核心控制台应用程序中使用 log4net 进行日志记录 - Logging with log4net in asp.net core console app ASP.Net核心应用程序502.3错误 - ASP.Net Core app 502.3 error 我应该在哪里开始ASP.NET Core中的持久后台任务? - Where am I supposed to start persistent background tasks in ASP.NET Core? BouncyCastle 部署错误:HTTP 错误 500.30 - ASP.NET 核心应用程序无法启动 - BouncyCastle deployment error: HTTP Error 500.30 - ASP.NET Core app failed to start ASP.NET Core Web App 将 404 请求记录为警告 - ASP.NET Core Web App log 404 requests as warning IIS 出现“HTTP 错误 500.30 - ASP.NET Core 应用程序无法启动” - “HTTP Error 500.30 - ASP.NET Core app failed to start” with IIS 覆盖默认错误页面 500.30 - ASP.NET 核心应用程序无法启动 - Override the default error page 500.30 - ASP.NET Core app failed to start 我可以在非 ASP.NET Core 的 .NET.core 应用程序中使用 HttpClientFactory 吗? - Can I use HttpClientFactory in a .NET.core app which is not ASP.NET Core?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM