getsentry / getsentry/sentry-dotnet

Connecting Queries with Code - Queries in Sentry show banner"could not find query source"

Open
#3,227 23 comments 1 reaction 1 assignee Claimed by @jamescrosswell View on GitHub
.NET Improvement Spans
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).

![image](https://github.com/getsentry/sentry-dotnet/assets/1633368/e266de34-6112-4042-aa06-d2832fbc88d3)

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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.