nreco / logging

Generic file logger for .NET Core (FileLoggerProvider) with minimal dependencies
MIT License
284 stars 56 forks source link

Get rolling file name index #53

Open Crypt32 opened 1 year ago

Crypt32 commented 1 year ago

This is related to #5, but not exactly. Here is my NReco.Logging registration with .NET DI:

services.AddLogging(loggingBuilder => {
        loggingBuilder.AddFile("Logs\\app_{0:yyyy}-{0:MM}-{0:dd}.log", fileLoggerOpts => {
        fileLoggerOpts.FormatLogFileName = getLogFileName;
        fileLoggerOpts.FileSizeLimitBytes = 1 * 1024 * 1024; // 1MB
        fileLoggerOpts.MaxRollingFiles = 10;
        fileLoggerOpts.UseUtcTimestamp = true;
    });
})

<...>
// callback for FormatLogFileName 
static String getLogFileName(String fName) {
    // cache current file name in static property:
    LogFilePath = String.Format(fName, DateTime.UtcNow);

    return LogFilePath;
}

Everything works ok with one exception: I loose current file name tracking when log file is rolled. By looking in Logs directory, I see that file names are appended with rolling index: image

And I have no idea how to access this index so I reference to actual current file in LogFilePath property. Any ideas?

VitaliyMF commented 1 year ago

By looking in Logs directory, I see that file names are appended with rolling index:

When log file size limit is reached next filename is generated by adding an 'index' suffix. Number of indexes are limited by "MaxRollingFiles" setting. If you want to guarantee that log file remains the same you may set "FileSizeLimitBytes" = 0 (means 'no limit') + your "FormatLogFileName" handler can check current log file size from time to time (not on each call -- as this will add too much overhead) and return different filename if needed.

And I have no idea how to access this index so I reference to actual current file in LogFilePath property. Any ideas?

The latest log file = the file with the latest 'last write' timestamp.

Crypt32 commented 1 year ago

If you want to guarantee that log file remains the same

this is not my intention. My intention is to get somewhere current index value so I can get actual file name the provider writes into. Would be nice if you can expose this information in callback function as a parameter.

The latest log file = the file with the latest 'last write' timestamp.

this is silly, but I guess there is no better way, right?

VitaliyMF commented 1 year ago

Normally Microsoft.Logging.Extensions infractructure works as a 'black box' from app's code (that generates log messages) - as your app is fully isolated by ILogger interface from concrete logging providers (that handle these log messages somehow). For example, when you use ConsoleLoggerProvider you don't have an access to its implementation internals.

However, I may assume that your app has some specifics and it should 'know' some internal details of the concrete logging provider. For instance, this can be a public property in FileLoggerProvider like 'CurrentLogFileName' that simply returns a value of FileWriter.LogFileName field (which holds currently opened log file name) -- if this is what you need your PR is welcome.

Crypt32 commented 1 year ago

However, I may assume that your app has some specifics and it should 'know' some internal details of the concrete logging provider.

right, there is a specific requirement in my case.

For instance, this can be a public property in FileLoggerProvider like 'CurrentLogFileName' that simply returns a value of FileWriter.LogFileName field (which holds currently opened log file name) -- if this is what you need your PR is welcome.

understood, thanks! I will see how this is important to us, maybe I can deal with sorting files by LastWriteTime to get the latest (with some assumptions like there are no other files in the target folder).