Closed CDboyOne closed 2 years ago
Writing to multiple files simultaneously is not possible for this FileLoggingProvider
implementation - it is designed to have only one opened file to write log entries.
However, it might be possible to support what do you want in another way. It makes sense to have multiple file logging providers - each one with its own file & configuration - that can filter log messages by a category (INFO, WARNING, ERROR etc). Currently it is possible to achieve this by setting FileLoggerOptions.MinLevel
, and in this way you can have a log file only with, say, ERRORs (MinLevel=LogLevel.Error), and another for all log entries (MinLevel=LogLevel.Debug). This approach is not suitable if you need to have a separate file that contains log messages only for the concrete category (say, only ERROR or only DEBUG) - if you explain your purpose, I'll try to propose a solution.
Thanks for your response, but I think you are misunderstanding. A category is like Microsoft.AspNetCore
or something else, not LogLevel
.
A category is like Microsoft.AspNetCore or something else
that's even easier, as you use the same approach (multiple file loggers) and use message filtering as described here: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/#configure-logging
You can assign a name for each logging provider and configure filtering rules for them separately:
{
"Logging": {
"File": {
"fileLoggingProvider1": {
"LogLevel": "None",
"Microsoft.AspNetCore": "Trace"
}
}
}
}
Thanks for your answer, but I am a little confused about your example. I tried it in my project but it did not produce any log.
Can you give a little example that I can reproduce? Just seperate Microsoft.Hosting
and Microsoft.AspNetCore
into two files.
By the way, I read the microsoft docs and tried this, although it produces same logs for every file:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"MicrosoftLogging": {
"File": {
"LogLevel": {
"Default": "None",
"Microsoft": "Information",
"Microsoft.AspNetCore": "Warning"
},
"Path": "Logs/{0:yyyy}-{0:MM}/{0:yyyy}-{0:MM}-{0:dd}-Dzmms.WebApis.Match-msft.log"
}
},
"DzmmsLogging": {
"File": {
"LogLevel": {
"Default": "None",
"Dzmms": "Information"
},
"Path": "Logs/{0:yyyy}-{0:MM}/{0:yyyy}-{0:MM}-{0:dd}-Dzmms.WebApis.Match-dzmms.log"
}
},
"WarningLogging": {
"File": {
"LogLevel": {
"Default": "Warning"
},
"Path": "Logs/{0:yyyy}-{0:MM}/{0:yyyy}-{0:MM}-{0:dd}-Dzmms.WebApis.Match-warning.log"
}
},
}
Then in C# code:
static string FormatStringWithDateTime(string path) => string.Format(path, DateTime.Now);
services.AddLogging(logbuilder =>
{
logbuilder.AddFile(configuration.GetSection("MicrosoftLogging"),
fileLoggerOpts =>
{
fileLoggerOpts.FormatLogFileName = FormatStringWithDateTime;
});
});
services.AddLogging(logbuilder =>
{
logbuilder.AddFile(configuration.GetSection("DzmmsLogging"),
fileLoggerOpts =>
{
fileLoggerOpts.FormatLogFileName = FormatStringWithDateTime;
});
});
services.AddLogging(logbuilder =>
{
logbuilder.AddFile(configuration.GetSection("WarningLogging"),
fileLoggerOpts =>
{
fileLoggerOpts.FormatLogFileName = FormatStringWithDateTime;
});
});
I will appreciate very much if you could provide me with an example.
Sorry for confusing you, it seems I pointed you to a wrong direction. I though it is possible to use this:
Settings in Logging.{PROVIDER NAME}.LogLevel override settings in Logging.LogLevel, where the {PROVIDER NAME} placeholder is the provider name.
so idea was to use different provider names -- but it seems, it is not possible to do that as provider's name cannot be provided dynamically, say, in ILoggingFactory.AddProvider method.
For now it is not possible to achieve what you want with FileLoggingProvider. Possible solution might be adding smth like
Func<LogMessage, bool> FileLoggerOptions.FilterLogEntry
-- in this way you'll able to use a delegate to define any custom filtering logic.
It seems that there is no Func<LogMessage, bool> FileLoggerOptions.FilterLogEntry
. There is only a Func<LogMessage, string> FileLoggerOptions.FormatLogEntry
, which cannot be used for this purpose.
Maybe it is possible to add a delegate which also takes string
category name or LogMessage
log message as input, and outputs the formatted filename?
It seems that there is no Func<LogMessage, bool> FileLoggerOptions.FilterLogEntry.
This might be a possible solution, without any changes in the code it is not possible to achieve what you asked for. If you know how to implement that your PR is welcome, or I can add it when I'll have a bit of free time.
Regarding
Maybe it is possible to add a delegate which also takes string category name or LogMessage log message as input, and outputs the formatted filename?
File name cannot depend on the log name (category), this will lead to open/close files each time when category changes. This is deadly inefficient and will make FileLoggerProvider non-suitable for production use.
I've added FileLoggerOptions.FilterLogEntry
(shipped in 1.1.5).
How to use: https://github.com/nreco/logging#custom-log-entry-filtering
Now you can have 2 (or more) file loggers and separate log entries between them with your own filtering predicate.
My hero, thank you very much.
When formatting logging filename, I think the category name needs to be added as a parameter, too.