-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Make FormattedLogValues class public #79149
Comments
Tagging subscribers to this area: @dotnet/area-extensions-logging Issue DetailsBackground and motivationHello. I've decided to create a custom logging provider, that should support structure logging. In the most of the cases, my code uses logging of the format form, e.g.: _logger.LogInformation("Service has started at {StartDateTime}", DateTime.UtcNow); So, I wanted to use named format fields as additional properties to the log. But, the interface After the deeper research into the In sum, the motivation of this feature is to clarify hidden logic, that is used for creating formatted messages. So developers can rely on it and be sure that this logic will not change in the future. API Proposalusing System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading;
namespace Microsoft.Extensions.Logging
{
/// <summary>
/// LogValues to enable formatting options supported by <see cref="string.Format(IFormatProvider, string, object?)"/>.
/// This also enables using {NamedformatItem} in the format string.
/// </summary>
public readonly struct FormattedLogValues : IReadOnlyList<KeyValuePair<string, object?>>
{
// We have to keep the original content as it is for backward compatibility. For example,
// the original format is still the last item of the collection and has the key "{OriginalFormat}".
// But we can extend the interface, giving appropriate ways to get the format and its arguments.
/// Gets the original message format.
public string OriginalFormat
{
get => this["{OriginalFormat}"];
}
/// Gets the collection of the format arguments with their names.
public IEnumerable<KeyValuePair<string, object?>> FormatArgs
{
get
{
for (int i = 0; i < Count - 1; ++i)
{
yield return this[i];
}
}
}
// the rest as it is
...
}
} API Usage public class CustomLogger : ILogger
{
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (state is FormattedLogValues formattedValues)
{
var format = formattedValues.OriginalFormat;
var args = formattedValues.FormatArgs;
...
}
else
{
...
}
}
...
} Alternative DesignsNo response RisksNo response
|
Similar #67577 |
Closing as a duplicate of #67577. @foreverstupid feel free to comment and add any thoughts there. |
Background and motivation
Hello. I've decided to create a custom logging provider, that should support structure logging. In the most of the cases, my code uses logging of the format form, e.g.:
So, I wanted to use named format fields as additional properties to the log. But, the interface
ILogger
of course has only the method that logs a message with a generic state. I've decided to look, how other libraries (e.g. NLog or Serilog) had solved this issue, and it turned out, that they check the type of the state to beIEnumerable<KeyValuePair<string, object>>
and more over they use a "magical" knowledge, that this collection has the format of the message as the last item (or the item, that has the key{OriginalFormat}
). I don't think, that such shadow knowledge is reliable enough to be used.After the deeper research into the
Microsoft.Extensions.Logging
assembly source code, I've found out that all extensions of the formLog***(string format, object[] args)
create an instance of the special classFormattedLogValues
as a message state. So my idea was to check a message state type to beFormattedLogValues
. But unfortunately this class is internal. Therefore my proposal is to make this class public and moreover give it a special property that holds an original message format.In sum, the motivation of this feature is to clarify hidden logic, that is used for creating formatted messages. So developers can rely on it and be sure that this logic will not change in the future.
API Proposal
API Usage
Alternative Designs
No response
Risks
No response
The text was updated successfully, but these errors were encountered: