У меня есть сервер .NET7 с несколькими webapi, который регистрирует запросы и ответы на файлы журналов с помощью NLog. Не хочу тратить время на логирование, поэтому в контроллерах добавляю сообщение в
ConcurrentQueue<LogText> logTextsQueque
Сюда
var logText = new LogText { deviceSerial= deviceSerial, message = message };
logTextsQueque.Enqueue(logText);
и в Main.cs я добавил этот цикл, который эффективно записывает журнал на диск:
_ = Task.Run(async () =>
{
while (true)
{
try
{
if (logTextsQueque.TryDequeue(out LogText result))
{
LogOut(result.deviceSerial, result.message);
}
}
catch (Exception ex)
{
LogManager.GetCurrentClassLogger().Error($"C3 Background thread error: {ex.Message}");
}
finally
{
}
}
});
Это своего рода очередь сообщений. Кажется, это работает, но есть ли что-то, о чем мне следует беспокоиться с этой простой реализацией?
Спасибо
NLog имеет встроенную очередь сообщений под названием AsyncWrapper, которую можно легко включить в NLog.config
с помощью <targets async = "true">
:
По умолчанию он использует overflowAction = "Discard"
, чтобы предотвратить сбой приложения из-за проблем с ведением журнала.
AsyncWrapper гарантирует, что NLog Context будет правильно захватывать ${threadid}
и регистрировать идентификатор потока приложения-потока (а не фонового потока, обрабатывающего очередь сообщений).
МММ спасибо! Я не знал об этой функции и попытался изобрести велосипед. Я вернулся к обычному протоколированию, но на случай, если я буду использовать эту процедуру для откладывания чего-то еще, записи чего-то в БД или на диск (конечно, с добавлением управления исключениями), правильно ли это или что-то не так?
@MattiaDurli Рекомендуется отложить внешнее общение до фонового потока, особенно когда он запущен и забыт. Microsoft обычно рекомендует использовать асинхронные задачи, которые хорошо работают при обработке запросов, управляемых пользователем, и позволяют возвращать сбои задач. Если вы хотите иметь ограничение дроссельной заслонки, повторные попытки и аварийное переключение, вам нужно ввести Polly или SemaphoreSlim. Если вы хотите иметь обратное давление и пакетную обработку, следует учитывать очередь сообщений. Много книг было написано и много пальцев/часов было сожжено на альтернативном параллелизме.
Обратите внимание, что
while (true)
заставит один поток задач выполнять интенсивное вращение и постоянно использовать все ядро процессора, когда в очереди ничего нет.