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

后端 未结 4 1567
孤独总比滥情好
孤独总比滥情好 2020-12-14 16:24

In old ASP.NET, in the Global.asax.cs class, I would log when the app starts, stops and throws unhandled exceptions:

  • Application_Start()
相关标签:
4条回答
  • 2020-12-14 16:59

    I didn't like @neustart47 answer as it was unnecessarily complex but he is right that IApplicationLifetime is obsolete.

    Taken from the 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!

    0 讨论(0)
  • 2020-12-14 17:02

    Please see CaptureStartupErrors and the method .CaptureStartupErrors(true) that will help you find issues.

    This is especially handy when something runs perfect on localhost but fails in Azure.

    Here is my usual config for 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

    0 讨论(0)
  • 2020-12-14 17:19

    You need to use 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. Also add ILoggerFactory here:

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

    Having ILoggerFactory, you can create instance of 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). 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;
        }
    }
    
    0 讨论(0)
  • 2020-12-14 17:19

    Using Microsoft.AspNetCore.Hosting.IApplicationLifetime suggested in the top answer now is obsolete.

    [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.

    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:

    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

    0 讨论(0)
提交回复
热议问题