org.sonar.plugins.csharp.S6673.html Maven / Gradle / Ivy
The positions of arguments in a logging call should match the positions of their message template
placeholders.
Why is this an issue?
The placeholders of a message template are defined by their name and their position. Log methods specify
the values for the placeholder at runtime by passing them in a params array:
logger.LogError("{First} placeholder and {Second} one.", first, second);
This rule raises an issue if the position of an argument does not match the position of the corresponding placeholder:
// 'first' and 'second' are swapped
logger.LogError("{First} placeholder and {Second} one.", second, first);
// ^^^^^^ ^^^^^
What is the potential impact?
Logging providers use placeholder names to create key/value pairs in the log entry. The key corresponds to the placeholder and the value is the
argument passed in the log call.
If the positions of the placeholder and the argument do not match, the value is associated with the wrong key. This corrupts the logs entry and
makes log analytics unreliable.
How to fix it
Make sure that the placeholder positions and the argument positions match. Use local variables, fields, or properties for the arguments and name
the placeholders accordingly.
Code examples
Noncompliant code example
'path' and 'fileName' are swapped and therefore assigned to the wrong placeholders.
logger.LogError("File {FileName} not found in folder {Path}", path, fileName);
// ^^^^ ^^^^^^^^
Compliant solution
Swap the arguments.
logger.LogError("File {FileName} not found in folder {Path}", fileName, path);
Noncompliant code example
'Name' is detected but 'Folder' is not. The placeholder’s name should correspond to the name from the argument.
logger.LogError("File {Name} not found in folder {Folder}", file.DirectoryName, file.Name);
// ^^^^
Compliant solution
Swap the arguments and rename the placeholder to 'DirectoryName'.
logger.LogError("File {Name} not found in folder {DirectoryName}", file.Name, file.DirectoryName);
Noncompliant code example
Not detected: A name for the arguments can not be inferred. Use locals to support detection.
logger.LogError("Sum is {Sum} and product is {Product}", x * y, x + y); // Not detected
Compliant solution
Help detection by using arguments with a name.
var sum = x + y;
var product = x * y;
logger.LogError("Sum is {Sum} and product is {Product}", sum, product);
Resources
Documentation
- Message Templates - Message template specification
- Microsoft Learn - Log message
template
- Serilog - Structured Data
- NLog - How to use structured logging