【问题标题】:Serilog static logger is SilentLogger when there's an exception in MassTransit AddBus()当 MassTransit AddBus() 中出现异常时,Serilog 静态记录器是 SilentLogger
【发布时间】:2021-02-04 12:48:22
【问题描述】:

我们目前正在运行一个使用 MassTransit 的 ASP.NET Core 3 Web 应用程序。我们为我们的日志库选择了 Serilog,它在大多数情况下都很好用。我们发现了一个小的边缘情况,它无法记录某些错误。在我们的Program.cs(下面的代码 sn-p)中,我们在服务仍在启动时初始化静态记录器,它会毫无问题地记录到控制台

如果在Startup.cs 中的ConfigureServices 方法中抛出异常,则服务将被终止并按预期将异常打印到控制台。但是,如果在 MassTransit AddBus() 方法中引发异常,则不会记录任何内容。经过一些调试,我们看到我们在Program.cs 中设置的静态记录器正在被SilentLogger 替换,我们认为这可能是 MassTransit 内部的某些东西导致了这种情况

MassTransit 初始化代码也可以在下面找到

public class Program
{
    public static void Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .Enrich.FromLogContext()
            .WriteTo.Console()
            .CreateLogger();

        try
        {
            Log.Information("Starting up app");
            CreateHostBuilder(args).Build().Run();
        }
        catch (Exception e)
        {
            Log.Fatal(e, "Host terminated unexpectedly");
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}
serviceCollection.AddMassTransit(configurator =>
{
    configurator.AddConsumers(consumerAssembly());

    var queueName = appSettings.QueueName;
    configurator.AddBus(provider =>
    {
        MessageDataDefaults.ExtraTimeToLive = TimeSpan.FromDays(1);
        MessageDataDefaults.Threshold = 2000;
        MessageDataDefaults.AlwaysWriteToRepository = false;

        return Bus.Factory.CreateUsingRabbitMq(cfg =>
            {
                var configHost = appSettings.RabbitMq.Host;
                var configUser = appSettings.RabbitMq.Username;
                var configPassword = appSettings.RabbitMq.Password;

                cfg.Host(new Uri(configHost), h =>
                {
                    h.Username(configUser);
                    h.Password(configPassword);
                });

                cfg.ReceiveEndpoint(queueName, ec => ec.ConfigureConsumers(provider));
            });
    });

    serviceCollection.AddSingleton<IHostedService, BusHostedService>();
});

AddBus 方法中抛出的任何异常都会导致此问题。以下是我们目前使用的版本:

  • 大众运输 7.1.4
  • MassTransit RabbitMq 7.1.4
  • Serilog 2.10.0

也许这里有人以前遇到过这个问题?任何帮助将不胜感激????

【问题讨论】:

    标签: c# asp.net-core serilog masstransit


    【解决方案1】:

    首先,我清理了您的配置,因为它有一些混合用途,通常不受欢迎。

    关于日志记录问题,MassTransit 对 SeriLog 一无所知,但您可以告诉 MassTransit 有关 Serilog 的信息。使用 Serilog.Extensions.Logging 包,并确保使用它们的配置方法将ILoggerFactory/ILogger&lt;&gt; 添加到您的服务集合中。

    serviceCollection.AddMassTransit(configurator =>
    {
        configurator.AddConsumers(consumerAssembly());
    
        configurator.UsingRabbitMq((context,cfg) =>
        {
            // these can actually go anywhere before the bus is created
            MessageDataDefaults.ExtraTimeToLive = TimeSpan.FromDays(1);
            MessageDataDefaults.Threshold = 2000;
            MessageDataDefaults.AlwaysWriteToRepository = false;
    
            var configHost = appSettings.RabbitMq.Host;
            var configUser = appSettings.RabbitMq.Username;
            var configPassword = appSettings.RabbitMq.Password;
    
            cfg.Host(new Uri(configHost), h =>
            {
                h.Username(configUser);
                h.Password(configPassword);
            });
    
            var queueName = appSettings.QueueName;
            cfg.ReceiveEndpoint(queueName, ec => ec.ConfigureConsumers(context));
        });
    });
    serviceCollection.AddSingleton<IHostedService, BusHostedService>();
    

    将 Serilog 添加到容器的可能语法:

    services.TryAddSingleton<ILoggerFactory>(_ => new SerilogLoggerFactory());
    services.TryAddSingleton(typeof(ILogger<>), typeof(Logger<>));
    

    【讨论】:

    • 感谢您的回复。我已经使用您上面提供的 sn-p 更新了 MassTransit 设置,我还将 Serilog 添加到 DI 容器中,但我仍然遇到同样的问题。就在这种情况下,现在在“UsingRabbitMq()”中抛出的任何异常都不会在“Program.cs”中捕获,它只是打印“正在启动应用程序”然后死
    • 抛出了什么异常,没有被捕获?
    • 所以我们在“RabbitMq”对象为空并且抛出了 NullReferenceException 时发现了这一点。之后,我们尝试使用自己的自定义异常并看到同样的事情发生
    • 它可能是在您的 BusHostedService 或其工厂中抛出的,它试图从容器中解析总线,这当然会抛出异常,因为对象的工厂方法抛出了异常。
    • 我们将在那里添加一些 catch 语句,看看我们是否能够捕获异常,但是为了感兴趣,如何阻止异常被记录?
    【解决方案2】:

    我发现了同样的问题,但我认为该问题与 Mass Transit/RabbitMq 代码无关。

    我在一个 .Net 核心控制台应用程序中。我们的共同点是CreateHostBuilder(args).Build().Run(); 代码。当Run() 中发生未捕获的异常并且全局catch (Exception e) 捕获它并且Log.Logger 现在是SilentLogger

    我在我的 catch 语句中解决了重新初始化 Log.Logger 的问题。不幸的是SilentLogger 不是公开的,所以我的检查是基于类名

        catch (Exception e) {
             if (Log.Logger.GetType().Name == "SilentLogger")
             {
                 InitLogger();
             }
             Log.Fatal(e, "Host terminated unexpectedly");
        }
    

    InitLogger() 只是重新初始化记录器,就像在您的示例中一样:

    Log.Logger = new LoggerConfiguration()
                .Enrich.FromLogContext()
                .WriteTo.Console()
                .CreateLogger();
    

    这在我看来像是一个错误,Log.Logger 由于某种原因被过早地拆除了。

    【讨论】:

      猜你喜欢
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 2011-08-21
      • 1970-01-01
      • 2015-02-02
      • 1970-01-01
      • 2018-05-26
      相关资源
      最近更新 更多