受欢迎的博客标签

How to capture and log Startup Errors in ASP.NET Core

Published

step 

1.Set detailed errors in program.cs to see a stack trace.

2.Log detailed errors into log file in program.cs

3. Implement a custom logging provider in .NET core

Create Your Own Logging Provider to Log to Text Files in .NET Core

4. Register a custom logging provider in program.cs

 

.Net 6.x

ASP.NET Core Web Host

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.CaptureStartupErrors(true);

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-6.0#host-configuration-values

 

.Net 5.x

Step 1:Enabled  the app captures detailed exceptions.

If you're not seeing a detailed error message, you can adjust your Program.cs file to display detailed errors.

Set detailedErrors in code to see a stack trace.

The following bit of code allows for detailed error message, even in production, so use with caution.

   public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)

                 //1.CaptureStartupErrors(true)
                 //use startup error page;Set whether startup errors should be captured in the configuration settings of the web host.
                 //When enabled, startup exceptions will be caught and an error page will be returned.If disabled, startup exceptions will be propagated.
                 // .UseSetting("detailedErrors", "true")
                 //https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-3.1#capture-startup-errors
                 //https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-3.1#detailed-errors
                 //.ConfigureLogging(logging =>
                 //{
                 //    logging.ClearProviders();// 移除.net Core默认注入的日志Providers
                 //    logging.AddNopLogger();//所有日志统一使用NopLogger
                 //    Microsoft.Extensions.Logging.FileLoggerFactoryExtensions.AddFile();


                 //})
                 .ConfigureLogging((hostingContext, logging) =>
                 {
                     //logging.ClearProviders();
                     //logging.AddConsole(options => options.IncludeScopes = true);
                     //logging.AddDebug();
                     // logging.AddNopLogger();
                 })

                // 配置web主机 kestrel

                .ConfigureWebHostDefaults(webBuilder =>
                {
                    //https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-5.0#settings-for-Web-apps
                    webBuilder.CaptureStartupErrors(true);
                    webBuilder.UseSetting(WebHostDefaults.DetailedErrorsKey, "true");



                    webBuilder.UseStartup<Startup>();
                });
    }

 

Useful links

In this article we will learn how to implement Serilog in ASP.NET Core 5.0 Web API Project and save the log in database.

https://www.c-sharpcorner.com/article/how-to-implementation-serilog-in-asp-net-core-5-0-application-with-database/

ASP.NET Core 5   +config  Serilog in Program.cs (ok)

https://jkdev.me/asp-net-core-serilog/

.Net 3.x

 

.NET Core version:ASP.NET Core 3.x

OS:windows server 2012 R2

The hosting layer logs a critical exception。

step 1:Set whether startup errors should be captured in the configuration settings of the web host.

namespace Nop.Web
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)

                .ConfigureLogging((hostingContext, logging) =>
         {
             logging.ClearProviders();
             logging.AddConsole(options => options.IncludeScopes = true);
             logging.AddDebug();
         })
                 .ConfigureWebHost(o =>
                 {
                     o.CaptureStartupErrors(true);
                     o.UseSetting(WebHostDefaults.DetailedErrorsKey, "true");
                 })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });
    }
}

 

step 2: write a custom LoggerProvider

custom LoggerProvider write  log error into Database or file。

using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Nop.Core.Data;
using Nop.Core.Domain.Logging;
using Nop.Core.Infrastructure;
using Nop.Services.Logging;
using System;
using System.IO;
using System.Text;

namespace Nop.Web.Framework.Logging
{
    public class NopLogger : ILogger
    {


        #region Fields

        private readonly IRepository<Log> _logRepository;
       

        #endregion

        #region Ctor

        /// <summary>
        /// Ctor
        /// </summary>
        /// <param name="logRepository">Log repository</param>
        
        //public NopLogger(IRepository<Log> logRepository)
        //{
        //    this._logRepository = logRepository;
            
        //}

        #endregion

       

        public bool IsEnabled(LogLevel logLevel)
        {
            return true;
        }

        public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
        {

            if (exception == null)
            {
                return;
            }

            var builder = new StringBuilder();
           

            if (exception != null)
            {
                builder.Append(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff zzz"));
                builder.Append(" [");
                builder.Append(logLevel.ToString());
                builder.Append("] ");
                // builder.Append(_category);
                builder.Append(": ");
                builder.AppendLine(formatter(state, exception));

                builder.AppendLine(exception.ToString());
            }




            //save to mongodb
            var nopLogger = EngineContext.ServiceProvider.GetRequiredService<INopLogger>();


            Log log = new Log();
            log.FullMessage = $"Log provider NopLogger:{builder.ToString()}";
            log.LogLevelId = (int)LogLevel.Critical;
            log.CreatedOnUtc = DateTime.UtcNow;

            nopLogger.InsertLog(log);


           

            // save to disk 

            var _webHostEnvironment = EngineContext.ServiceProvider.GetRequiredService<IWebHostEnvironment>();

            string path = _webHostEnvironment.ContentRootPath+ "\\log";

            string filename = DateTime.Now.ToString("yyyy-MM-dd") + ".log";

            var directory = Path.GetDirectoryName(path);
            if (!string.IsNullOrWhiteSpace(directory) && !Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }


            //come from :https://stackoverflow.com/questions/35310078/how-to-write-to-a-file-in-net-core
            var logPath = Path.Combine(path, filename);


            var logFile = System.IO.File.Open(logPath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite);


            var logWriter = new System.IO.StreamWriter(logFile);




            logWriter.WriteAsync(builder.ToString());

            logWriter.Flush();
            logFile.Flush(true);


        }



        public IDisposable BeginScope<TState>(TState state)
        {
            return null;
        }
    }
}

 

step 3: register custom LoggerProvider

 

step 4: output

 

c:\log\2018-11-13.log

018-11-13 18:54:34.224 +08:00 [Information] : Connection id "0HLI9APIQ5U8R" bad request data: "Malformed request: invalid headers."
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Malformed request: invalid headers.
   at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
2018-11-13 19:34:48.226 +08:00 [Information] : Connection id "0HLI9BG27RC33" bad request data: "Malformed request: invalid headers."
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Malformed request: invalid headers.
   at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
2018-11-13 19:46:52.268 +08:00 [Information] : Connection id "0HLI9BMQ0U1C8" bad request data: "Malformed request: invalid headers."
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Malformed request: invalid headers.
   at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
2018-11-13 19:46:52.272 +08:00 [Information] : Connection id "0HLI9BMQ0U1C8" bad request data: "Malformed request: invalid headers."
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Malformed request: invalid headers.
   at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
2018-11-13 19:48:45.211 +08:00 [Information] : Connection id "0HLI9BNRM1TE0" bad request data: "Malformed request: invalid headers."
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Malformed request: invalid headers.
   at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)
2018-11-13 20:03:28.081 +08:00 [Information] : Connection id "0HLI9BNRM1TEM" bad request data: "Malformed request: invalid headers."
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Malformed request: invalid headers.
   at Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException.Throw(RequestRejectionReason reason)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)

 

Useful links

.Net 5.x

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-5.0#detailed-errors

 

.Net 3.x

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-3.1

//https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-3.1#capture-startup-errors
//https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-3.1#detailed-errors

.Net Core初识以及启动配置