ASP.net:如何从 CreateHostBuilder() 中登录?

uri*_*rig 5 .net configuration logging exception asp.net-core

我有一个 ASP.net Core 3.1 Web 应用程序。在Program.cs类中,我实现了CreateHostBuilder()与此类似的静态方法:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host
        .CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((context, config) =>
        {
            try 
            {
                // do some configuration work that might fail
            }
            catch (Exception ex)
            {
                // how can I write to a log from here?
            }
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });
}
Run Code Online (Sandbox Code Playgroud)

如果在配置应用程序时引发异常,我如何使用ILogger捕获它时记录它?

uri*_*rig 5

微软的“登录.NET Core和ASP.NET Core ”文档文章说:

不直接支持主机构建期间的日志记录。然而,可以使用单独的记录器。

他们继续使用Serilog给出这个例子:

public static IHostBuilder CreateHostBuilder(string[] args)
{
    var builtConfig = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json")
        .AddCommandLine(args)
        .Build();

    Log.Logger = new LoggerConfiguration()
        .WriteTo.Console()
        .WriteTo.File(builtConfig["Logging:FilePath"])
        .CreateLogger();

    try
    {
        return Host.CreateDefaultBuilder(args)
            .ConfigureServices((context, services) =>
            {
                services.AddRazorPages();
            })
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddConfiguration(builtConfig);
            })
            .ConfigureLogging(logging =>
            {   
                logging.AddSerilog();
            })
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
    }
    catch (Exception ex)
    {
        Log.Fatal(ex, "Host builder error");

        throw;
    }
    finally
    {
        Log.CloseAndFlush();
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 3

将记录器放在 Main 方法之外,以便可以从 CreateHostBuilder 访问它

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using NLog.Common;
using System;
using System.IO;

namespace WebApplication1
{
    public class Program
    {
        // Place your logger outside Main to make it accessible from CreateHostBuilder
        private static NLog.Logger logger;

        public static void Main(string[] args)
        {
            // Manually setup your desired logger.
            // I've used NLog for demonstration purposes but you can use your own preferred logger.
            var today = DateTime.Today.ToString("yyyy-MM-dd");
            var binDirectory = GetBinDirectory<Program>();
            var nLogInternalFullPath = Path.Combine(binDirectory, "NLog", $"{today}-internal.log");

            InternalLogger.LogFile = nLogInternalFullPath;

            // Assign logger. Make sure you have the file NLog.config
            // https://github.com/NLog/NLog/wiki/File-target
            logger = NLog.LogManager.LoadConfiguration("NLog.config").GetCurrentClassLogger();

            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((context, config) =>
                {
                    try
                    {
                        // do some configuration work that might fail
                    }
                    catch (Exception ex)
                    {
                        // Log errors
                        logger.Error(ex, "Unhandled error in ConfigureAppConfiguration.");
                    }
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                });

        public static string GetBinDirectory<T>()
        {
            return Path.GetDirectoryName(typeof(T).Assembly.Location);
        }
    }
}

Run Code Online (Sandbox Code Playgroud)