У меня проблемы с корректным завершением работы приложения .NET Core, которое регистрируется в приемнике Serilog ElasticSearch из нескольких потоков.Ниже приведен минимальный рабочий пример:
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 для отправки в ElasticSearch.
Ясно, что я забиваю приемник Serilog ElasticSearch большим количеством одновременных журналов, чем это когда-либо предполагалось обрабатывать, но это кажется раздражающими проблемами для any многопоточное приложение с логированием.В частности:
- Имеет ли ElasticSearch максимальную скорость ведения журнала, которую он может обрабатывать?Есть ли хорошие способы сделать это быстрее?
- Я думал, что общие хосты .NET Core должны были автоматически отключаться через 5 секунд .Как быть с тем, что приемник ElasticSearch не позволяет хосту завершить работу приложения?
- Есть ли способ принудительно отменить Serilog после того, как
Ctrl+C
выдает команду на завершение работы приложения (при условии, что мне нет дела до оставшегося журналасобытия)?
Заранее спасибо!