web-api启动时如何注入和使用Serilog(Ilogger)

Posted

技术标签:

【中文标题】web-api启动时如何注入和使用Serilog(Ilogger)【英文标题】:How to inject and use Serilog (Ilogger) when web-api startup 【发布时间】:2021-08-13 17:58:53 【问题描述】:

我正在开发一个 .NET core 3.1 控制台应用程序 (web-api)。 我使用 Serilog 服务(它基本上是使用 Microsoft.Extensions.Logging)。 Serilog 被注入并且可以在 FW Controllers 方法中使用。 现在 - 我需要一些不同的东西 - 每当系统启动(关闭后)我需要发出一个 http post 请求 - 你可以在执行 ConnectionInitiator.Initiate() 时看到它,在 启动 方法中。在同一范围内(方法\类) - 我需要使用记录器来记录一些数据。现在 - 如果请求将通过控制器 - 记录器将可用(通过 DI)。 长话短说——我需要以某种方式将 Ilogger 注入课堂或以其他方式使其可用。我试过在启动时使用记录器,但这似乎是不可能的(因为.net core 3.0 - 如果我理解正确的话) 查看我的代码:

程序.cs:

public class Program
    
        public static void Main(string[] args)
        
            var loggerConfig = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();
            //Reading the appconfig.json
            Log.Logger = new LoggerConfiguration().ReadFrom.Configuration(loggerConfig).CreateLogger();
            try
            
                Log.Information("System Started up");
                CreateWebHostBuilder(args).Build().Run();
            
            catch (Exception ex)
            
                Log.Fatal(ex, "THE APPLICATION FAILED TO START UP");
            
            finally
            
                Log.CloseAndFlush();
            

        

        public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        
            return WebHost.CreateDefaultBuilder(args).ConfigureLogging((context, logging) =>
            
                logging.ClearProviders();
            ).UseSerilog().UseStartup<Startup>();
        
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                
                    webBuilder.UseStartup<Startup>();
                );
    

StartUp.cs

public class Startup

    public Startup(IConfiguration configuration/*, Microsoft.Extensions.Logging.ILogger logger*/)
    
        Configuration = configuration;
        ConnectionInitiator.Initiate(configuration/*, logger*/);
    


    public IConfiguration Configuration  get; 

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    
        services.AddCors();

        services.AddControllers();
        services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(dispose: true));
    

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    

        app.UseCors(builder => builder.AllowAnyHeader().AllowAnyMethod().SetIsOriginAllowed((host) => true).AllowCredentials());
        if (env.IsDevelopment())
        
            app.UseDeveloperExceptionPage();
        
        app.UseRouting();
        app.UseAuthentication();
        app.UseEndpoints(endpoints =>
        
            endpoints.MapControllers();
        );
    

ConnectionInitiator.cs:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

using System.Threading.Tasks;

namespace AAA.BL

    public static class ConnectionInitiator
    

        private static readonly object threadlock = new object();
        private static MyConfig myConfig;
        private static ILogger ilogger;
        /*
        public ConnectionInitiator(ILogger _logger)
        
            ilogger = _logger;
        
        */
        public static void/*async Task*/ Initiate(IConfiguration configuration/*, ILogger ilogger*/)
        
            HttpRequester httpRequester = new HttpRequester();
            if (myConfig == null)
            
                myConfig = new myConfig(configuration);
            

            IssueOTPResponse response = /*await*/ httpRequester.PostSomething(myConfig, ilogger).Result;            //Double check thread safe singleton implementation
            if (response.ststuacode != 200)
            
                ilogger.logcritical($"critical error when initiate connection (connectioninitiator): response.statusdescription");
            

        
    

【问题讨论】:

【参考方案1】:

似乎答案比我预期的要简单得多 - 通过使用 Serilog 并在 Configure 方法中作为服务添加 - 可以全局访问(在namepsace的每个地方)通过使用静态类Log及其静态方法Logger,例如: Log.Logger.Information("XXXXX");

【讨论】:

以上是关于web-api启动时如何注入和使用Serilog(Ilogger)的主要内容,如果未能解决你的问题,请参考以下文章

嵌套类中的依赖注入

Serilog:如何仅在文件开头写入文件头?

如何从 Serilog 中排除特定的异常类型?

无法从Windows服务中托管的Asp.net核心网站启动多个Serilog接收器

如何在 appsettings.json 中使用多个单独的记录器 Serilog 文件

使用serilog和Castle winsdor日志时,Logger.InfoFormat没有记录第一个参数。