dotnet / docs

This repository contains .NET Documentation.
https://learn.microsoft.com/dotnet
Creative Commons Attribution 4.0 International
4.18k stars 5.85k forks source link

State processing unclear, fragments left in document #41327

Open ygoe opened 1 month ago

ygoe commented 1 month ago

Type of issue

Missing information

Description

In the article there's a code block that just contains:

TState state,
Exception? exception,

It is not referenced or explained by the surrounding text. It looks like this article is an editor's draft and not meant to be published.

Also, exactly this state handling is unclear. I want to use the structured logging in my custom logger and therefore I need to access 1. the original log message and 2. the log values with name and value. I can have the values list by casting the internal type FormattedLogValues to the list type it implements (and that I only know from digging into the Microsoft source code or doing some runtime type reverse engineering). Feels like a hack but it's not documented. But the original message with the placeholders is inaccessible. Everything is internal, sealed and locked down. As if Microsoft doesn't want me to implement a custom logger. Then why does this article even exist if that shouldn't be possible?

Page URL

https://learn.microsoft.com/en-us/dotnet/core/extensions/custom-logging-provider

Content source URL

https://github.com/dotnet/docs/blob/main/docs/core/extensions/custom-logging-provider.md

Document Version Independent Id

e111baf5-04b7-c497-ce86-eb687e121751

Article author

@IEvangelist

Metadata

ygoe commented 1 month ago

This is from Bing Chat that has a surprisingly detailed knowledge about this issue:

The template string with unresolved placeholders is not directly accessible from the state object. However, the state object is actually an instance of a private class FormattedLogValues in the Microsoft.Extensions.Logging.Abstractions namespace, which does contain the original message template.

Unfortunately, because FormattedLogValues is a private class, you can’t directly cast the state object to it and access its properties. But you can use reflection to access the private _originalMessage field which contains the original message template.

After proving the code to do that, it rightly goes on:

This will print the original message template with unresolved placeholders in curly braces. Please note that using reflection to access private fields is generally not recommended as it can lead to brittle code that breaks when the library is updated. This is just a workaround to access the original message template due to the current limitations of the ILogger interface. It’s always a good idea to check if there are any updates or changes in the newer versions of the library.

This seems to be the only way to implement a custom structured logger. I've tried to follow NLog's code but that's too complicated and I couldn't find anything in there. I'm not sure if it supports that at all.