-
Notifications
You must be signed in to change notification settings - Fork 0
Advanced Query Processing Architecture #7
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -46,10 +46,10 @@ import { LokiQuery } from './types'; | |||||
| */ | ||||||
|
|
||||||
| export function runShardSplitQuery(datasource: LokiDatasource, request: DataQueryRequest<LokiQuery>) { | ||||||
| const queries = datasource | ||||||
| .interpolateVariablesInQueries(request.targets, request.scopedVars) | ||||||
| const queries = request.targets | ||||||
| .filter((query) => query.expr) | ||||||
| .filter((query) => !query.hide); | ||||||
| .filter((query) => !query.hide) | ||||||
| .map((query) => datasource.applyTemplateVariables(query, request.scopedVars, request.filters)); | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Similar to time-based splitting, shard splitting now calls Severity Level: Major
|
||||||
| .map((query) => datasource.applyTemplateVariables(query, request.scopedVars, request.filters)); | |
| .map((query) => datasource.applyTemplateVariables(query, request.scopedVars)); |
Steps of Reproduction ✅
1. Enable Loki shard splitting so `LokiDatasource.query()` routes through
`runShardSplitQuery()` when sharding is supported: see
`public/app/plugins/datasource/loki/datasource.ts:299-344`, especially the branch at
`datasource.ts:336-338` calling `runShardSplitQuery(this, fixedRequest)` when
`config.featureToggles.lokiShardSplitting` is true and
`requestSupportsSharding(fixedRequest.targets)` is satisfied.
2. Issue a Loki dashboard/explore query that (a) supports sharding and (b) has ad hoc
filters populated into `request.filters` (standard Grafana ad hoc UI). At runtime this
yields a `DataQueryRequest<LokiQuery>` where `filters` is non-empty, as exercised in
`datasource.test.ts` around the "When using adhoc filters" and `addAdHocFilters` tests
(`datasource.test.ts:229-307, 1232-1315`) and where `targets` contain a log or
metric-over-logs expression.
3. In `runShardSplitQuery()` (`shardQuerySplitting.ts:48-55`), the code builds `queries`
from `request.targets` and calls `datasource.applyTemplateVariables(query,
request.scopedVars, request.filters)` for each target (line 52).
`LokiDatasource.applyTemplateVariables()` (`datasource.ts:1110-1140`) internally calls
`addAdHocFilters()` (`datasource.ts:1073-1091`), which in turn uses `addLabelToQuery()`
(`modifyQuery.ts:147-213`) to splice ad hoc filters into the query expression. For log
queries with a parser (e.g. `{bar="baz"} | logfmt`) and ad hoc filters on labels not
already in the stream selector, `addLabelToQuery()` falls into the
`addFilterAsLabelFilter()` path (`modifyQuery.ts:185-195, 511-540`) which has no
deduplication, so the expression now contains a `| label op` pipeline segment for each ad
hoc filter.
4. Later in the same request, shard splitting creates per-shard sub-requests in
`splitQueriesByStreamShard()` (`shardQuerySplitting.ts:57-209`). For each group, it
computes `targets` from `groups[group].targets` (which are the already-templated
`queries`) and builds `subRequest = { ...request, targets:
interpolateShardingSelector(targets, shardsToQuery) }` at
`shardQuerySplitting.ts:152-155`. This `subRequest` is passed into
`runSplitQuery(datasource, subRequest, ...)` (`shardQuerySplitting.ts:163`), where
`runSplitQuery()` (`querySplitting.ts:291-300`) *again* maps `request.targets` through
`datasource.applyTemplateVariables(query, request.scopedVars, request.filters)`. Because
`subRequest.filters` is the original `request.filters` and the expressions already contain
ad hoc filters from step 3, this second call adds another identical set of label filters
via `addFilterAsLabelFilter()`. The resulting per-shard queries sent via
`datasource.runQuery(subRequest)` contain duplicated ad hoc pipeline filters (e.g. `... |
job=\`grafana\` | job=\`grafana\``), confirming that sharded queries can have ad hoc
filters applied twice in the current code.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** public/app/plugins/datasource/loki/shardQuerySplitting.ts
**Line:** 52:52
**Comment:**
*Logic Error: Similar to time-based splitting, shard splitting now calls `applyTemplateVariables` with `request.filters` before delegating to `runSplitQuery`, but `runSplitQuery`'s sub-requests are executed via `datasource.runQuery`, which applies `applyTemplateVariables` again with the same filters, resulting in duplicated ad hoc label filters on sharded queries; using filters only at execution time avoids double application while still letting shard lookup see an interpolated selector.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: The splitting logic now pre-applies
applyTemplateVariableswithrequest.filters, butdatasource.runQuery(viaDataSourceWithBackend.query) will applyapplyTemplateVariablesagain with the same filters, causing ad hoc filters to be injected twice into the split Loki queries; this can lead to duplicated label filters and unintended query semantics, so the pre-interpolation used only for splitting decisions should not passrequest.filters. [logic error]Severity Level: Major⚠️
Steps of Reproduction ✅
Prompt for AI Agent 🤖