In last two articles, we have seen how the logging providers can be configured in .NET console app and .NET core web app. This article explains a bit about how the logging internally works and how logging levels can be configured in appsettings.json
.
What is Log Category ?
When an ILogger object is created, a log category is specified. This category is included with each log message created by the ILogger instance. This category name can be any random string. But generally, the fully qualified class name is used as a log category.
When ILogger<T> is injected in the constructor, it uses fully qualified name of type T as the log category.
When a Generic Host is setup, there are two ways to acquire the instances of ILogger instance:
- ILogger<T> can be injected in type T and then use it for writing logs. In this case, fully qualified name of type T would be used as log category.
- ILoggerFactory can be injected in any type. Then ILoggerFactory.CreateLogger can be used to specify the category name.
In some applications, ILoggerFactory injection might be helpful as it allows you to specify custom category name. This can be helpful to view the logged messages organized by log category.
Below code example shows both ways of getting an ILogger instance.
What is Log Level ?
Before understanding to the configurations, let’s have a quick look at log levels.
LogLevel enum defines different type of log levels. The log level can be Trace
, Debug
, Warning
, Information
, Error
, Critical
, etc.
Depending on purpose of information being logged, appropriate log level can be assigned with every logged message. For writing log message with a log level, you can use Log{LogLevelValue}
methods from ILogger instance.
Why so many log levels ?
There are multiple log levels and it can be very confusing sometimes to a new person to decide which log level should be used for a log message.
Log Levels are used by logging providers to decide which data should be written in the log storage medium. How ? We will look at this part in the next section.
Generally, Trace
, Information
, Debug
levels are meant for additional information that is required for debugging. We should always try to either limit the information logged under these log levels. It can be limited to specific categories at least to reduce the data being stored in log storage medium. This might help to optimize the storage costs.
Generally Warning
, Error
, Critical
log levels should be associated with the log messages which are logged to notify some problems in the application functionality. So generally the information generated by these log levels should be quite lesser than the other log levels.
I think this information should be enough for us to decide which log level should be assigned to a log message.
What is Log Provider ?
Log provider decides where the log messages should be sent to (e.g. console or event viewer or txt file or database, etc).
While writing log messages, the Log provider uses the configuration to find out whether the message should be written or not.
If the log level in configuration is lower or equal to the log level of the message, then the message is written. Otherwise, the message is skipped.
Configurations
Now, let’s understand how can we instruct logging providers to log only specific log levels to storage medium (i.e. where logs are written). The configuration basically revolves around the three concepts discussed earlier.
In configuration we can specify minimum log level. Any log messages those have higher log level associated, would be written to the log storage medium.
This minimum log level can be specified at three levels
- at whole application level
- at log category level
- at log provider level
Below example shows a sample appsettings.json
file and shows which level is applicable for which level.
How does it work ?
The most specific log level is used. For ex. application level log level is applicable if no other configuration exist for logging provider and log category. If the logging provider specific configuration exists in configuration, then it is used for that specific logging provider.
Any logs below the minimum level are not:
- Passed to the provider.
- Logged or displayed.
One More Trick…
To suppress all logs, specify LogLevel.None. LogLevel.None
has a value of 6, which is higher than LogLevel.Critical
(5).
Have you used these configurations before ? Let me know your thoughts.
Great!
Exactly what I searched.
Thank you.
Hello Mr Codeblogger. I’ve just written my first gRPC client/server windows application (the server runs as a windows service). Do you know how to make gRPC write to custome windows event logs please?
Hi ,
I think you may just need to hook the addEventLog method somehow in startup. Below is a sample code: I have not tried this specifically with gRPC, but I think it should work. Let me know if this helps.
var builder = WebApplication.CreateBuilder();
builder.Host.ConfigureLogging(logging =>
{
logging.AddEventLog(eventLogSettings =>
{
eventLogSettings.SourceName = “MyLogs”;
});
});