Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Since ILogger<T> is a singleton, how different threads can use BeginScope() without affecting others?

This is related to this question. Context: .Net Core 3.1, using Microsoft.Extensions.Logging

Loggers are singletons in the application's IHost. If I inject (DI) an ILogger<T> into my class or method, the injected object is the same instance other classes or methods receive if they ask for ILogger<T>. This poses the question of what happens when I use logger.BeginScope($"Processing {transactionId}") in one thread. What happens with the other threads? Do they change the logging scope as well? Do logging scopes get mixed up? If they don't: how does that work, being their loggers the same object? If they do mix scopes, how can I make two threads use different logging scopes for a given ILogger<T> type?

like image 403
Guillermo Prandi Avatar asked Jan 25 '26 07:01

Guillermo Prandi


1 Answers

This depends on the logger implementation, but typically they're implemented using a type of stack held within an AsyncLocal.

A call to BeginScope will put a new item onto that stack, and the adjoining Dispose will pop it off of that stack.

When the logger is invoked via LogInformation or otherwise, the data of the current stack object will be copied to write it to the console or whatever output that logger instance is configured to do.

The AsyncLocal is what gives the framework the ability to store information across threads and tasks.

For reference, check out the Microsoft.Extensions.Logging.Console source code:

  • ConsoleLogger.cs#L67
  • LoggerExternalScopeProvider.cs#L14
like image 129
Matthew Avatar answered Jan 28 '26 06:01

Matthew



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!