getsentry / getsentry/sentry-dotnet
Parameter name conflict in structured logs
- Dominant language
- C#
- Stars
- 770
- Forks
- 248
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 49
Description
### Package
Sentry
### .NET Flavor
.NET
### .NET Version
10.0.100
### OS
Any (not platform specific)
### OS Version
Azure app service
### Development Environment
Rider 2025.x (Windows)
### SDK Version
5.16.2
### Self-Hosted Sentry Version
_No response_
### Workload Versions
-
### UseSentry or SentrySdk.Init call
```
builder.WebHost.UseSentry(options =>
{
options.Debug = true;
options.Dsn = config.Dsn;
options.Release = config.CommitHash;
options.Environment = config.Environment;
options.TracesSampleRate = 1.0d;
options.SampleRate = 1.0f;
options.SendDefaultPii = true; // sending info about users
options.MaxRequestBodySize = RequestSize.Medium; // includes request body
options.MinimumEventLevel = LogLevel.Warning;
options.CaptureFailedRequests = false;
options.DisableDiagnosticSourceIntegration(); // Should prevent multiple spans for db calls.
options.DisableSentryHttpMessageHandler = true; // Should prevent duplicate httpclient errors
options.AddExceptionFilterForType();
options.SetBeforeSend(sentryEvent =>
{
// This happens when the client terminates a request. We can ignore this as there's not much we can about it.
if (sentryEvent.Exception is BadHttpRequestException bre && bre.Message.Contains("Unexpected end of request content"))
{
return null;
}
return sentryEvent;
});
options.EnableLogs = true;
options.CaptureFailedRequests = false;
options.UseOpenTelemetry();
});
```
### Steps to Reproduce
I'm using scopes to define properties for logs that make it easier to filter specific logs like this. LogInfo is a collection of KeyValuePairs.
```
using var _ = logger.BeginScope(new LogInfo(("Queue.HandlerName", "JobService")));
```
However when I log inside the scope and provide a parameter with the same name as in the scope like this:
```
logger.LogInformation("{Queue.HandlerName} - starting inner scope of {QueueItem.Name} processing.", typeof(TThisHandler).Name, item.Name);
```
It starts producing weird results.
Note: I'm providing the parameter, because my IDE complains when I log with placeholders and not provide values. It's hard for it to validate that the parameter is actually present in the scope when you're a couple methods down the stack. And any change to the scope would break the logging.
Example code:
```
[HttpGet("test")]
public IActionResult TestMethod()
{
var queueHandlerForScope = "JobProcessorFromScope";
var queueHandlerForLogs = "JobProcessor";
logger.LogInformation("Testing some log before using with the handlerName {Queue.HandlerName}", queueHandlerForLogs);
using var __ = logger.BeginScope(new Dictionary
{
{ "Queue.HandlerName", queueHandlerForScope }
});
logger.LogInformation("Testing some log after using with the handlerName {Queue.HandlerName}", queueHandlerForLogs);
logger.LogInformation("Testing some log after using with no handlerName");
return Ok("Returned.");
}
```
### Expected Result
I'd expect that
- the original value is sent to the `property` part of the sentry message
- the message parameter is send in the `message.parameter` part of the sentry message
Alternatively, I'd be okay with just the latest value provided to the message being sent to both places.
But I do expect the `property.Queue.HandlerName` to have a value, so that I can use that for my searching, dashboards etc. I expect all the logs inside the scope of the BeginScope to have these structured data properties.
### Actual Result
Sentry is smart, so it doesn't send the value twice. it simply removes `property.Queue.HandlerName`. This breaks searching the logs by using the structured data.
Contributor guide
Assessment
This issue has not been assessed yet.