简体   繁体   中英

Serilog Dispose/Close log file-stream

Recently I focused in Serilog to point out a templated path based on the current Date of every LogEvent . After figuring how to implement this, I finally resolve the path on the fly by using the Date field into LogEvent by using Serilog.Sinks.Map , such as shown below:

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");

With this, I achieved my goal: writing logs with in a sub folder based on the Date.

The issue is, since Serilog does not know that the pointing path changed, it does not close or dispose the file stream as expected. So, my application leaves files opened day to day, ad infinitum.

It'd be great if someone has faced this approach, to manually close the stream, or if Serilog API exposes somehow automatically close those streams.

Btw, I am using

  • Serilog 2.9.0
  • Serilog.Sinks.File 4.1.0
  • Serilog.Sinks.Map 1.0.1

Edit 05/06/2020 for those reading this afterwards.
Keying every single log event by the Timestamp is a bad idea. By doing so, we are in fact adding an entry per log event (supposing that no events are being emitted at the same time, for simplicity).
Even if we specify the sinkMapCountLimit to 0 , which in theory won't keep any event in our map, if that event is configured to write to file (specially with the RollingFile sink), those sinks won't be disposed nor erased from memory.

So, the chunk of code above is leaking memory (and pretty fast).
The Map.Sink documentation warns about this, indeed.

...but isn't suitable when the set of possible key values is open-ended.

Serilog.Sinks.Map accepts a parameter sinkMapCountLimit to control this:

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);
        },
        sinkMapCountLimit: 5
    );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM