c# - Serilog - 多线程日志记录会阻止应用程序取消
问题描述
我无法正常关闭从多个线程登录到 Serilog ElasticSearch 接收器的 .NET Core 应用程序。下面是一个最小的工作示例:
Program.cs
:
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Serilog;
public class Program
{
public static async Task Main() =>
await new HostBuilder()
.UseConsoleLifetime()
.ConfigureLogging((context, logging) => logging.AddSerilog(
new LoggerConfiguration()
.WriteTo.Console()
.WriteTo.Elasticsearch(
nodeUris: "http://example.com:9200",
indexFormat: "derp-{0:yyyy.MM.dd}",
typeName: "_doc"
)
.CreateLogger(), dispose: true)
)
.ConfigureServices((context, services) =>
{
services.AddHostedService<DerpService>();
})
.Build()
.RunAsync();
}
DerpService.cs
:
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
public class DerpService : BackgroundService
{
private readonly ILogger<DerpService> _logger;
public DerpService(ILogger<DerpService> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken) =>
await Task.WhenAll(Enumerable
.Range(0, 100)
.Select(i =>
Task.Run(() =>
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation($"Task {i} is here!");
}
}, stoppingToken)
));
}
当我运行这个应用程序时,Serilog 立即开始向控制台写入一大堆Task i is here!
消息,但几分钟内没有任何内容记录到 ElasticSearch。一旦 ElasticSearch 日志启动,它们就会随着应用程序的继续运行而逐渐落后。此外,应用程序的内存消耗会随着Serilog.Events.LogEvent
实例而激增,似乎没有限制。最后,当我尝试Ctrl+C
在控制台窗口中取消应用程序时,控制台日志停止,内存消耗逐渐减少,但应用程序仍然存活了几分钟,大概是在 Serilog 咀嚼LogEvent
s 的积压发送到弹性搜索。
很明显,我正在用比以往更多的并发日志来锤击 Serilog ElasticSearch 接收器,但是对于任何具有日志记录的多线程应用程序来说,这些似乎都是潜在的烦人问题。具体来说:
- ElasticSearch 是否具有可以处理的最大日志记录速率?有什么好方法可以让它更快吗?
- 我认为 .NET Core 通用主机应该在 5 秒后自动关闭。ElasticSearch 接收器阻止主机关闭应用程序怎么办?
- 在指示应用程序关闭后,有什么方法可以强制取消 Serilog
Ctrl+C
(假设我不关心剩余的日志事件)?
提前致谢!
解决方案
推荐阅读
- javascript - Ajax 响应数据分别获取
- line-breaks - “如何修复 MathJax 换行?”
- c++ - 成功注册dll,但在regedit表中没有任何改变
- lua - 如何从 table.remove(x) 中插入 table.insert(x)
- jquery - Azure 图形查询
- oracle - 错误 ORA-06502 WHEN-BUTTON-PRESSED oracle 表单
- spotfire - 当值低于零时,返回零
- android - net.sqlcipher.database.SQLiteException:错误代码 100:另一行可用
- javascript - 提交表单、克隆表单、仅提交新表单、克隆表单等
- html - 如何在不使用 flexbox 的情况下将不同的内容组织在页面的左侧和右侧?