Недавно я сосредоточился на Serilog
, чтобы указать шаблонный путь на основе текущей даты каждого LogEvent
. После того, как я понял, как это реализовать, я, наконец, определил путь на лету, используя поле Дата в LogEvent
, используя Serilog.Sinks.Map
, как показано ниже:
return new LoggerConfiguration().WriteTo
.Map(
// Log key
(LogEvent le) => le.Timestamp.Date,
// Log Action
(DateTime date, LoggerSinkConfiguration lc) =>
{
string path = GetFilesPath(date, logName);
lc.File(path);
}
);
public string GetFilePath(DateTime date, string logName) =>
Path.Combine("./Logs", $"{date:yyyy-MM-dd}", $"{logName}.log");
С этим, Я достиг своей цели: запись журналов в подпапку на основе даты.
Проблема в том, что Serilog
не знает, что указательный путь изменился, он не закрывает и не удаляет файловый поток как ожидается. Итак, мое приложение оставляет файлы открытыми изо дня в день, до бесконечности.
Было бы замечательно, если бы кто-то сталкивался с таким подходом, чтобы вручную закрыть поток, или если Serilog
API предоставляет каким-то образом автоматически закрыть эти потоки .
Кстати, я использую
- Serilog 2.9.0
- Serilog.Sinks.File 4.1.0
- Serilog.Sinks.Map 1.0.1
Редактировать 05/06/2020 для тех, кто читает это позже.
Пометка каждого отдельного события журнала с помощью Timestamp плохая идея. Таким образом, мы фактически добавляем запись для каждого события журнала (для простоты предположим, что события не генерируются одновременно).
Даже если мы указываем от sinkMapCountLimit
до 0
, что в теории не будет сохранять события на нашей карте, если это событие настроено на запись в файл (особенно с приемником RollingFile
), эти приемники не будут удалены или удалены из памяти.
Итак, Часть кода, приведенного выше, вызывает утечку памяти (и довольно быстро).
Документация Map.Sink
действительно предупреждает об этом.
... но не подходит когда набор возможных значений ключа является открытым.