День 2322. #ЧтоНовенького
Запись Логов по Требованию с Буферизацией. Начало
Обычно нужны подробные логи, когда что-то идёт не так, но когда всё хорошо, зачем платить за хранение логов, которые никогда не проверяются. Хотя выборка логов (log sampling) помогает сократить их объём, сохраняя только часть, иногда нужен другой подход.
Буферизация логов в .NET 9 временно сохраняет логи в памяти и позволяет позже решить, записывать ли их. Буферизация даёт контекстный контроль над тем, какие логи сохраняются на основе фактических результатов выполнения.
Концепция
Буферизация логов представляет новый шаблон потока:
1. Код генерирует логи обычным образом,
2. Нужные логи сохраняются в памяти, а не пишутся немедленно,
3. Позже, на основе определённых условий, вы решаете:
- Очистить буфер и записать все захваченные логи,
- Дать времени жизни буфера истечь, фактически отбрасывая ненужные логи.
Так, например, вы можете буферизировать подробные логи для транзакции, сохраняя их только в случае сбоя транзакции и отбрасывая в случае её успеха.
Две стратегии буферизации
.NET 9 предоставляет две стратегии буферизации: глобальная и по запросу.
1. Глобальная буферизация
Хранит логи в кольцевых буферах, общих для всего приложения. Это подходит для буферизации логов, связанных с длительными процессами или фоновыми задачами. Для базовых сценариев включите буферизацию:
builder.Logging
.AddGlobalLogBuffer(LogLevel.Information);
Эта конфигурация буферизует все логи от уровня Information. Для более сложных сценариев определите конкретные правила:
builder.Logging.AddGlobalBuffer(o =>
{
// Буферизация логов уровня Information, категории "PaymentService"
o.Rules.Add(
new LogBufferingFilterRule(
categoryName: "PaymentService",
logLevel: LogLevel.Information));
o.MaxBufferSizeInBytes = 100 * 1024 * 1024;
o.MaxLogRecordSizeInBytes = 50 * 1024;
o.AutoFlushDuration = TimeSpan.FromSeconds(30);
});
- MaxBufferSizeInBytes – максимальный размер буфера.
- MaxLogRecordSizeInBytes – максимальный размер отдельных записей лога.
- AutoFlushDuration – как долго буферизация лога будет оставаться отключенной после запуска операции записи (flush). В примере выше буферизация будет оставаться отключенной в течение 30 секунд, что позволит приложению нормально писать все логи.
Запись глобального буфера
Чтобы записать буферизованные логи, внедрите класс GlobalLogBuffer и вызовите его метод Flush():
public class PaymentService
{
private ILogger<PaymentService> _logger;
private GlobalLogBuffer _buffer;
public PaymentService(
ILogger<PaymentService> logger,
GlobalLogBuffer buffer)
{
_logger = logger;
_buffer = buffer;
}
public async Task ProcessPayment(
PaymentRequest req)
{
try
{
_logger.LogInformation(
"Старт обработки платежа для транзакции {TransId}", req.TransactionId);
// Обработка платежа...
_logger.LogInformation("Платёж обработан");
}
catch (Exception ex)
{
_logger.LogError(ex, "Сбой обработки");
// Записываем буфер для записи детальных логов
_buffer.Flush();
throw;
}
}
}
В этом примере подробные логи о процессе оплаты сохраняются только в случае возникновения исключения.
Окончание следует…
Источник: https://devblogs.microsoft.com/dotnet/emit-logs-on-demand-with-log-buffering/
>>Click here to continue<<