0

I need to log custom dimensions to Application Insights for which I'm using ILogger.BeginScope(). That works perfectly. That is:

using (logger.BeginScope(new Dictionary<string, object> { "key": "value" }))
{
    logger.LogInformation("message");
}

My issue is that I need to call other methods in other classes, and I'm injecting the ILogger into all my classes. So how can I persist the logging scope among all my classes?

I could surely do ILogger.BeginScope() in all my classes, but I would need to pass the custom properties to classes that don't really need that information. Is there a pattern I could use?

user11081980
  • 3,059
  • 4
  • 30
  • 48

1 Answers1

1

If you call BeginScope multiple times in multiple classes within the same execution path, you will get one aggregated scope. There is no need to manually pass the properties. ILogger is injected as a singleton by default (see source code).

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

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.

Alex AIT
  • 17,361
  • 3
  • 36
  • 73
  • In my use it appears that when I enter a subsequent call, such as OnAfterRenderAsync, the scope I set earlier has been removed. Any idea how to avoid that? – David Thielen Jun 29 '23 at 18:06
  • @DavidThielen I'd have to check the blazor life cycle in more detail. but I'd probably collect all the disposables and only dispose them when the page itself is disposed. – Alex AIT Jun 30 '23 at 17:11
  • I came up with a solution that I think works really well - https://stackoverflow.com/a/76584828/509627 – David Thielen Jul 01 '23 at 00:16