mirror of
https://github.com/SigNoz/signoz.git
synced 2026-08-06 13:10:40 +01:00
Some checks failed
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
cacheci / tests (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
- Replace the search() stub: the logs condition builder fans a case-insensitive
match of the term across every searchable column (log columns, body/body_v2,
attribute + resource maps).
- Grammar: searchCall takes a valueList (parser regenerated), so the scoped form
search('term', body, resource) parses and narrows the fan-out to those contexts.
- The visitor emits FilterOperatorSearch and flags the statement scan-heavy; the
statement builder attaches a CostGuard the querier enforces via EXPLAIN ESTIMATE
against a per-shard budget, cumulative across buckets on the window-list path.
- body_v2 gets its own, lower budget (search_max_scan_rows_json_body): toString()
rebuilds every document and no skip index prunes.
- Logs-only: other signals reject search().
- Unit tests for the per-context fan-out SQL and both budgets; integration suites
run the same matrix over the legacy body and over body_v2.
50 lines
2.1 KiB
Go
50 lines
2.1 KiB
Go
package statementbuilder
|
|
|
|
import (
|
|
"github.com/SigNoz/signoz/pkg/errors"
|
|
)
|
|
|
|
// SkipResourceFingerprint configures when the resource fingerprint subquery is skipped in favor of main-table filtering.
|
|
type SkipResourceFingerprint struct {
|
|
Enabled bool `yaml:"enabled" mapstructure:"enabled"`
|
|
// If count of fingerprint is above threshold, skip the fingerprint subquery and filter on main table instead.
|
|
Threshold uint64 `yaml:"threshold" mapstructure:"threshold"`
|
|
}
|
|
|
|
// Config represents the configuration for the statement builders.
|
|
type Config struct {
|
|
// SkipResourceFingerprint configures when the resource fingerprint subquery is skipped in favor of main-table filtering.
|
|
SkipResourceFingerprint SkipResourceFingerprint `yaml:"skip_resource_fingerprint" mapstructure:"skip_resource_fingerprint"`
|
|
// SearchMaxScanRows caps per-shard rows a search() may scan, enforced by the querier
|
|
// via EXPLAIN ESTIMATE (0 disables).
|
|
SearchMaxScanRows int64 `yaml:"search_max_scan_rows" mapstructure:"search_max_scan_rows"`
|
|
// SearchMaxScanRowsJSONBody is the same budget for body_v2, where each row costs far
|
|
// more: toString() rebuilds every document and no skip index prunes (0 disables).
|
|
SearchMaxScanRowsJSONBody int64 `yaml:"search_max_scan_rows_json_body" mapstructure:"search_max_scan_rows_json_body"`
|
|
}
|
|
|
|
func NewConfig() Config {
|
|
return Config{
|
|
SkipResourceFingerprint: SkipResourceFingerprint{
|
|
Enabled: false,
|
|
Threshold: 100000,
|
|
},
|
|
SearchMaxScanRows: 60_000_000,
|
|
SearchMaxScanRowsJSONBody: 6_000_000,
|
|
}
|
|
}
|
|
|
|
// Validate validates the configuration.
|
|
func (c Config) Validate() error {
|
|
if c.SkipResourceFingerprint.Enabled && c.SkipResourceFingerprint.Threshold == 0 {
|
|
return errors.NewInvalidInputf(errors.CodeInvalidInput, "skip_resource_fingerprint.threshold must be > 0 when enabled")
|
|
}
|
|
if c.SearchMaxScanRows < 0 {
|
|
return errors.NewInvalidInputf(errors.CodeInvalidInput, "search_max_scan_rows must not be negative, got %v", c.SearchMaxScanRows)
|
|
}
|
|
if c.SearchMaxScanRowsJSONBody < 0 {
|
|
return errors.NewInvalidInputf(errors.CodeInvalidInput, "search_max_scan_rows_json_body must not be negative, got %v", c.SearchMaxScanRowsJSONBody)
|
|
}
|
|
return nil
|
|
}
|