我正在尝试为 Serilog 设置一个接收器,通过 MassTransit 发布日志消息。 当我尝试在启动时创建接收器时遇到问题。接收器创建会导致无限循环。
我应该如何注册依赖注入(inject)来解决这个问题?
我认为这是因为 MassTransit.IBus 使用 ILogger。因此,当创建记录器时,它会要求我的 IBus 接收器,IBus 要求记录器,记录器要求 IBus,等等。
Program.cs中的启动代码
//Code that sets up my mass transit. IBus is registered as part of it.
builder.Host.SetupMassTransit();
builder.Host.UseSerilog((ctx, services, lc) =>
{
lc.WriteTo.Sink(new MassTransitSink(services.GetService<IBus>())); //Set a breakpoint here
});
在lc.WriteTo.Sink(...
上设置断点你会看到它被重复调用。
大众运输汇
public class MassTransitSink : ILogEventSink
{
private readonly IBus bus;
public MassTransitSink(IBus bus)
{
this.bus = bus;
}
public async void Emit(LogEvent logEvent)
{
await bus.Publish<MyLog>(new MyLog("Hello World"));
}
}
public class MyLog
{
public MyLog(string message)
{
Message = message;
}
public string Message { get; set; }
}
最佳答案
这是一种解决方法,不允许您使用 Microsoft 的 ILogger,接受的答案是一个修复程序,允许您使用 Serilog.ILogger 和 Microsoft.Extension.Logging.ILogger
我能够通过手动将 Serilog.ILogger
实例添加到依赖项容器来解决此问题。
替换program.cs
的UseSerilog
部分:
builder.Host.UseSerilog((ctx, services, lc) =>
{
lc.WriteTo.Sink(new MassTransitSink(services.GetService<IBus>()));
});
使用代码手动添加 ILogger
实例。
builder.Host.ConfigureServices(services =>
{
services.AddSingleton<Serilog.ILogger>(sp =>
{
var bus = sp.GetRequiredService<IBus>();
return new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Sink(new MassTransitSink(bus))
.CreateLogger();
});
services.AddLogging(configure => configure.ClearProviders().AddSerilog());
});
Serilog.ILogger
现在可以在调试器中工作。但是,Microsoft.Extensions.Logging.ILogger
不起作用,尽管它在安装程序使用 .UseSerilog()
时通常可用。
我想我会在这里发布这个以防其他人遇到同样的问题。我花了几个小时才解决这个问题。
有人知道更具可读性和/或可以使用 Microsoft.Extensions.Logging.ILogger 和 Serilog.ILogger 的解决方案吗?
关于dependency-injection - Serilog Sink with MassTransit - IBus 服务解析导致无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75075839/