-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
LoggerMessage.Define doesn't support repeating the same named parameter in the message template #51054
Comments
Tagging subscribers to this area: @maryamariyan Issue DetailsDescription
LoggerMessage.Define<string>(LogLevel.Information, new(0, "LogSomething"), "Hello {Name}. How are you {Name}"); This throws, and it should work. Regression?No Other information
|
This also affects direct calls to var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
var logger = loggerFactory.CreateLogger("Foo");
logger.LogInformation("Hello {Name}. How are you {Name}", "David"); Blows up with:
|
Thinking about why this isn't supported today, there could be some difficulty aligning template holes and specified arguments: logger.LogInformation("Hello {Name}. Are you {Age} years old? How are you {Name}", "David", 100);
logger.LogInformation("Are you {Age} years old? How are you {Name}. Hello {Name}", 100, "David"); The first template would translate to: string.Format("Hello {0}. Are you {1} years old? How are you {0}", "David", 100); The second would be: string.Format("Are you {0} years old? How are you {1}. Hello {1}", 100, "David"); Essentially, holes get a number based on the first time they occur in the template. |
Both (LoggerMessage.Define and the LogXyz-extension method) go down to runtime/src/libraries/Microsoft.Extensions.Logging.Abstractions/src/LogValuesFormatter.cs Line 26 in b05a892
Recently I wondered about the same 😉, but then I thought it's better to be explicit: it's another hole in the format string, so there must be another argument provided. Even if it's the same one. And how likely is it actually to have the same parameter name multiple times? Further: LoggerMessage.Define delegates are quite often wrapped by an extension method. So that method could handle the multiple parameters. Picking from your first example: private static readonly Action<ILogger, string, Exception?> s_greet = LoggerMessage.Define<string, string>(LogLevel.Information, new(0, "LogSomething"), "Hello {Name}. How are you {Name}");
public static void Greet(this ILogger logger, string name) => s_greet(logger, name, name, null); I'm not sure what's the correct behavior though. A really quick fix would be to use a Dictionary<string, int> in the This would work according to
|
I'm aware 😉 The only thing that gives me pause is the fact that this hasn't been reported before. I wonder if what we have is simpler now and might result in more ambiguity. |
It was more for the record, than for you 😃
Maybe because it is an artificial problem, not a real world one? (As it was in my case by testing the new overloads with skipEnabledCheck) |
Possibly, but it's come up again because of the source generator generating LoggerMessage.Define calls. Will it show up more then? public static class Log
{
[LoggerMessage(Message = "Hello {Name}. Are you {Age} years old? How are you {Name}")]
public void SayHello(string name, int age);
} |
This is still a artificial example. Have you seen something in the wild? For semantic logging the count of provided parameters must match the count of placeholders. For the example from the source generator IMO the produced code should double the |
A similar case |
So in example, LoggerMessage.Define<string>(LogLevel.Information, new(0, "LogSomething"), "Hello {Name}. How are you {Name}"); The runtime exception shown in this issue description is happening because the Define API expected one string argument but we see two named placeholders ( The runtime exception above can be safely prevented, with the logging analyzer shipped in 6.0 SDK. This analyzer verifies the number of named placeholders in the message template match the number of arguments To get unblocked with this issue, I think today if someone wanted to repeat the same argument they would also have to add more arguments to the Define argument. So for: LoggerMessage.Define<string>(LogLevel.Information, new(0, "LogSomething"), "Hello {Name}. How are you {Name}"); the code could update to: LoggerMessage.Define<string, string>(LogLevel.Information, new(0, "LogSomething"), "Hello {Name}. How are you {Name}"); This would need to move to 7.0. Fixing this issue involves updating the newly shipped logging analyzer so that it would not complain about mismatched number of arguments with count of named placeholders, when the same number of argument gets repeated. |
To give an example from "something in the wild" - this is what I just tried and then stumbled upon this problem:
(which translates to "New balance for {registerId} after deposit of {sum} {currency}: {total} {currency}") |
Description
LoggerMessage.Define
blows up if the number of parameters doesn't match the specified template parameters even if the parameters used in the template are the same.This throws, and it should work.
Regression?
No
Other information
The text was updated successfully, but these errors were encountered: