getsentry / getsentry/sentry-dotnet
Connecting Queries with Code - Queries in Sentry show banner"could not find query source"
- Dominant language
- C#
- Stars
- 770
- Forks
- 248
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 49
Description
## Feature Request
> Could not find query source in the selected date range. Learn more in our [documentation](https://docs.sentry.io/product/performance/queries/#query-sources).

Docs does mention it's only supported in a few SDKs and .NET isn't one of those
### Solution
To add the query source, you can add additional data attributes to the span:
```
code.filepath: ...
code.function: ...
code.lineno: ...
```
Furthermore, two additional settings must be added to the SDK, which allows users to opt-out or alter the threshold. Please make sure to run some benchmarks about how much runtime overhead this adds and adjust the threshold accordingly.
```
sql_origin: true // enabled by default
sql_origin_threshold_ms: 100ms // default threshold
```
### Summary
Add support for [query source](https://docs.sentry.io/product/insights/backend/queries/#query-sources) attributes to database spans created by the EF Core and SqlClient diagnostic source integrations.
### Motivation
The Sentry Queries module can display the source code location that triggered a database query, helping developers quickly identify slow queries in their codebase. This feature is currently supported in the Python SDK (enabled by default) and Laravel SDK.
Currently, the .NET SDK's `SentryEFCoreListener` and `SentrySqlListener` create spans with `db.system`, `db.name`, and `server.address` attributes, but do not include code location attributes (`code.filepath`, `code.lineno`, `code.function`, `code.namespace`).
### Proposed Solution
Similar to the [Python SDK implementation](https://github.com/getsentry/sentry-python/blob/master/sentry_sdk/tracing_utils.py#L186-L222):
1. When a database span finishes, walk the stack trace to find the first "in-app" frame
2. Extract code location from that frame and set:
- `code.filepath` (relative to project root)
- `code.lineno`
- `code.function`
- `code.namespace`
### Configuration Options
Following Python SDK conventions:
- `EnableDbQuerySource` (bool, default: `true`) - Enable/disable query source capture
- `DbQuerySourceThresholdMs` (int, default: `100`) - Only capture query source for queries slower than this threshold (to minimize performance impact)
### Performance Considerations
Stack trace capture has overhead, so:
1. Only capture for queries exceeding the duration threshold
2. Consider caching frame analysis results
3. In Release builds without PDB files, line numbers may be unavailable (graceful degradation)
### Example Output
```json
{
"op": "db.query",
"description": "SELECT * FROM users WHERE id = @p0",
"data": {
"db.system": "postgresql",
"code.filepath": "src/MyApp/Services/UserService.cs",
"code.function": "GetUserAsync",
"code.lineno": 42,
"code.namespace": "MyApp.Services.UserService"
}
}
```
### References
- Python SDK implementation: [`add_query_source`](https://github.com/getsentry/sentry-python/blob/master/sentry_sdk/tracing_utils.py#L186)
- Sentry docs: [Query Sources](https://docs.sentry.io/product/insights/backend/queries/#query-sources)
- OpenTelemetry semantic conventions: [Code attributes](https://github.com/open-telemetry/semantic-conventions/blob/main/docs/general/attributes.md#source-code-attributes)
- [SDK Issue](https://github.com/getsentry/team-sdks/issues/40)
- [Docs](https://docs.sentry.io/product/performance/queries/#query-sources)
- [Span Data Conventions](https://develop.sentry.dev/sdk/telemetry/traces/span-data-conventions/#general)
- Maybe useful: [Compiler Services Attributes](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callermembernameattribute?view=net-9.0)
Contributor guide
Assessment
This issue has not been assessed yet.