mirror of
https://github.com/prometheus/prometheus.git
synced 2026-02-03 20:39:32 -05:00
Replace per-component parser options with default instance
Signed-off-by: Martin Valiente Ainz <64830185+tinitiuset@users.noreply.github.com>
This commit is contained in:
parent
01bfd185bf
commit
c8e0b6f97c
19 changed files with 91 additions and 113 deletions
|
|
@ -632,6 +632,9 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Set the process-wide parser configuration. All components (engine, rules, web) use this.
|
||||
parser.SetDefaultOptions(cfg.parserOpts)
|
||||
|
||||
if agentMode && len(serverOnlyFlags) > 0 {
|
||||
fmt.Fprintf(os.Stderr, "The following flag(s) can not be used in agent mode: %q", serverOnlyFlags)
|
||||
os.Exit(3)
|
||||
|
|
@ -935,7 +938,6 @@ func main() {
|
|||
EnablePerStepStats: cfg.enablePerStepStats,
|
||||
EnableDelayedNameRemoval: cfg.promqlEnableDelayedNameRemoval,
|
||||
EnableTypeAndUnitLabels: cfg.scrape.EnableTypeAndUnitLabels,
|
||||
ParserOptions: cfg.parserOpts,
|
||||
FeatureRegistry: features.DefaultRegistry,
|
||||
}
|
||||
|
||||
|
|
@ -956,7 +958,6 @@ func main() {
|
|||
ResendDelay: time.Duration(cfg.resendDelay),
|
||||
MaxConcurrentEvals: cfg.maxConcurrentEvals,
|
||||
ConcurrentEvalsEnabled: cfg.enableConcurrentRuleEval,
|
||||
ParserOptions: cfg.parserOpts,
|
||||
DefaultRuleQueryOffset: func() time.Duration {
|
||||
return time.Duration(cfgFile.GlobalConfig.RuleQueryOffset)
|
||||
},
|
||||
|
|
@ -974,7 +975,6 @@ func main() {
|
|||
cfg.web.Storage = fanoutStorage
|
||||
cfg.web.ExemplarStorage = localStorage
|
||||
cfg.web.QueryEngine = queryEngine
|
||||
cfg.web.ParserOptions = cfg.parserOpts
|
||||
cfg.web.ScrapeManager = scrapeManager
|
||||
cfg.web.RuleManager = ruleManager
|
||||
cfg.web.Notifier = notifierManager
|
||||
|
|
|
|||
|
|
@ -361,6 +361,7 @@ func main() {
|
|||
}
|
||||
}
|
||||
}
|
||||
parser.SetDefaultOptions(promtoolParserOpts)
|
||||
|
||||
switch parsedCmd {
|
||||
case sdCheckCmd.FullCommand():
|
||||
|
|
@ -869,7 +870,7 @@ func checkRulesFromStdin(ls rulesLintConfig) (bool, bool) {
|
|||
fmt.Fprintln(os.Stderr, " FAILED:", err)
|
||||
return true, true
|
||||
}
|
||||
rgs, errs := rulefmt.Parse(data, ls.ignoreUnknownFields, ls.nameValidationScheme, promtoolParserOpts)
|
||||
rgs, errs := rulefmt.Parse(data, ls.ignoreUnknownFields, ls.nameValidationScheme)
|
||||
if errs != nil {
|
||||
failed = true
|
||||
fmt.Fprintln(os.Stderr, " FAILED:")
|
||||
|
|
@ -903,7 +904,7 @@ func checkRules(files []string, ls rulesLintConfig) (bool, bool) {
|
|||
hasErrors := false
|
||||
for _, f := range files {
|
||||
fmt.Println("Checking", f)
|
||||
rgs, errs := rulefmt.ParseFile(f, ls.ignoreUnknownFields, ls.nameValidationScheme, promtoolParserOpts)
|
||||
rgs, errs := rulefmt.ParseFile(f, ls.ignoreUnknownFields, ls.nameValidationScheme)
|
||||
if errs != nil {
|
||||
failed = true
|
||||
fmt.Fprintln(os.Stderr, " FAILED:")
|
||||
|
|
@ -1345,7 +1346,7 @@ func checkTargetGroupsForScrapeConfig(targetGroups []*targetgroup.Group, scfg *c
|
|||
}
|
||||
|
||||
func formatPromQL(query string) error {
|
||||
expr, err := parser.ParseExpr(query, parser.WithOptions(promtoolParserOpts))
|
||||
expr, err := parser.ParseExpr(query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -1355,7 +1356,7 @@ func formatPromQL(query string) error {
|
|||
}
|
||||
|
||||
func labelsSetPromQL(query, labelMatchType, name, value string) error {
|
||||
expr, err := parser.ParseExpr(query, parser.WithOptions(promtoolParserOpts))
|
||||
expr, err := parser.ParseExpr(query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -1400,7 +1401,7 @@ func labelsSetPromQL(query, labelMatchType, name, value string) error {
|
|||
}
|
||||
|
||||
func labelsDeletePromQL(query, name string) error {
|
||||
expr, err := parser.ParseExpr(query, parser.WithOptions(promtoolParserOpts))
|
||||
expr, err := parser.ParseExpr(query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@ import (
|
|||
|
||||
"github.com/prometheus/prometheus/model/labels"
|
||||
"github.com/prometheus/prometheus/model/rulefmt"
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
"github.com/prometheus/prometheus/promql/promqltest"
|
||||
)
|
||||
|
||||
|
|
@ -188,7 +187,7 @@ func TestCheckDuplicates(t *testing.T) {
|
|||
c := test
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
rgs, err := rulefmt.ParseFile(c.ruleFile, false, model.UTF8Validation, parser.Options{})
|
||||
rgs, err := rulefmt.ParseFile(c.ruleFile, false, model.UTF8Validation)
|
||||
require.Empty(t, err)
|
||||
dups := checkDuplicates(rgs.Groups)
|
||||
require.Equal(t, c.expectedDups, dups)
|
||||
|
|
@ -197,7 +196,7 @@ func TestCheckDuplicates(t *testing.T) {
|
|||
}
|
||||
|
||||
func BenchmarkCheckDuplicates(b *testing.B) {
|
||||
rgs, err := rulefmt.ParseFile("./testdata/rules_large.yml", false, model.UTF8Validation, parser.Options{})
|
||||
rgs, err := rulefmt.ParseFile("./testdata/rules_large.yml", false, model.UTF8Validation)
|
||||
require.Empty(b, err)
|
||||
|
||||
for b.Loop() {
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ func newRuleImporter(logger *slog.Logger, config ruleImporterConfig, apiClient q
|
|||
apiClient: apiClient,
|
||||
ruleManager: rules.NewManager(&rules.ManagerOptions{
|
||||
NameValidationScheme: config.nameValidationScheme,
|
||||
ParserOptions: promtoolParserOpts,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,12 +247,11 @@ func (tg *testGroup) test(testname string, evalInterval time.Duration, groupOrde
|
|||
|
||||
// Load the rule files.
|
||||
opts := &rules.ManagerOptions{
|
||||
QueryFunc: rules.EngineQueryFunc(suite.QueryEngine(), suite.Storage()),
|
||||
Appendable: suite.Storage(),
|
||||
Context: context.Background(),
|
||||
NotifyFunc: func(context.Context, string, ...*rules.Alert) {},
|
||||
Logger: promslog.NewNopLogger(),
|
||||
ParserOptions: promtoolParserOpts,
|
||||
QueryFunc: rules.EngineQueryFunc(suite.QueryEngine(), suite.Storage()),
|
||||
Appendable: suite.Storage(),
|
||||
Context: context.Background(),
|
||||
NotifyFunc: func(context.Context, string, ...*rules.Alert) {},
|
||||
Logger: promslog.NewNopLogger(),
|
||||
}
|
||||
m := rules.NewManager(opts)
|
||||
groupsMap, ers := m.LoadGroups(time.Duration(tg.Interval), tg.ExternalLabels, tg.ExternalURL, nil, ignoreUnknownFields, ruleFiles...)
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ type ruleGroups struct {
|
|||
}
|
||||
|
||||
// Validate validates all rules in the rule groups.
|
||||
func (g *RuleGroups) Validate(node ruleGroups, nameValidationScheme model.ValidationScheme, parserOpts parser.Options) (errs []error) {
|
||||
func (g *RuleGroups) Validate(node ruleGroups, nameValidationScheme model.ValidationScheme) (errs []error) {
|
||||
if err := namevalidationutil.CheckNameValidationScheme(nameValidationScheme); err != nil {
|
||||
errs = append(errs, err)
|
||||
return errs
|
||||
|
|
@ -134,7 +134,7 @@ func (g *RuleGroups) Validate(node ruleGroups, nameValidationScheme model.Valida
|
|||
set[g.Name] = struct{}{}
|
||||
|
||||
for i, r := range g.Rules {
|
||||
for _, node := range r.Validate(node.Groups[j].Rules[i], nameValidationScheme, parserOpts) {
|
||||
for _, node := range r.Validate(node.Groups[j].Rules[i], nameValidationScheme) {
|
||||
var ruleName string
|
||||
if r.Alert != "" {
|
||||
ruleName = r.Alert
|
||||
|
|
@ -198,7 +198,7 @@ type RuleNode struct {
|
|||
}
|
||||
|
||||
// Validate the rule and return a list of encountered errors.
|
||||
func (r *Rule) Validate(node RuleNode, nameValidationScheme model.ValidationScheme, parserOpts parser.Options) (nodes []WrappedError) {
|
||||
func (r *Rule) Validate(node RuleNode, nameValidationScheme model.ValidationScheme) (nodes []WrappedError) {
|
||||
if r.Record != "" && r.Alert != "" {
|
||||
nodes = append(nodes, WrappedError{
|
||||
err: errors.New("only one of 'record' and 'alert' must be set"),
|
||||
|
|
@ -219,7 +219,7 @@ func (r *Rule) Validate(node RuleNode, nameValidationScheme model.ValidationSche
|
|||
err: errors.New("field 'expr' must be set in rule"),
|
||||
node: &node.Expr,
|
||||
})
|
||||
} else if _, err := parser.ParseExpr(r.Expr, parser.WithOptions(parserOpts)); err != nil {
|
||||
} else if _, err := parser.ParseExpr(r.Expr); err != nil {
|
||||
nodes = append(nodes, WrappedError{
|
||||
err: fmt.Errorf("could not parse expression: %w", err),
|
||||
node: &node.Expr,
|
||||
|
|
@ -339,7 +339,7 @@ func testTemplateParsing(rl *Rule) (errs []error) {
|
|||
}
|
||||
|
||||
// Parse parses and validates a set of rules.
|
||||
func Parse(content []byte, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme, parserOpts parser.Options) (*RuleGroups, []error) {
|
||||
func Parse(content []byte, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme) (*RuleGroups, []error) {
|
||||
var (
|
||||
groups RuleGroups
|
||||
node ruleGroups
|
||||
|
|
@ -364,16 +364,16 @@ func Parse(content []byte, ignoreUnknownFields bool, nameValidationScheme model.
|
|||
return nil, errs
|
||||
}
|
||||
|
||||
return &groups, groups.Validate(node, nameValidationScheme, parserOpts)
|
||||
return &groups, groups.Validate(node, nameValidationScheme)
|
||||
}
|
||||
|
||||
// ParseFile reads and parses rules from a file.
|
||||
func ParseFile(file string, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme, parserOpts parser.Options) (*RuleGroups, []error) {
|
||||
func ParseFile(file string, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme) (*RuleGroups, []error) {
|
||||
b, err := os.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, []error{fmt.Errorf("%s: %w", file, err)}
|
||||
}
|
||||
rgs, errs := Parse(b, ignoreUnknownFields, nameValidationScheme, parserOpts)
|
||||
rgs, errs := Parse(b, ignoreUnknownFields, nameValidationScheme)
|
||||
for i := range errs {
|
||||
errs[i] = fmt.Errorf("%s: %w", file, errs[i])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,20 +22,17 @@ import (
|
|||
"github.com/prometheus/common/model"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.yaml.in/yaml/v3"
|
||||
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
)
|
||||
|
||||
func TestParseFileSuccess(t *testing.T) {
|
||||
opts := parser.Options{}
|
||||
_, errs := ParseFile("testdata/test.yaml", false, model.UTF8Validation, opts)
|
||||
_, errs := ParseFile("testdata/test.yaml", false, model.UTF8Validation)
|
||||
require.Empty(t, errs, "unexpected errors parsing file")
|
||||
|
||||
_, errs = ParseFile("testdata/utf-8_lname.good.yaml", false, model.UTF8Validation, opts)
|
||||
_, errs = ParseFile("testdata/utf-8_lname.good.yaml", false, model.UTF8Validation)
|
||||
require.Empty(t, errs, "unexpected errors parsing file")
|
||||
_, errs = ParseFile("testdata/utf-8_annotation.good.yaml", false, model.UTF8Validation, opts)
|
||||
_, errs = ParseFile("testdata/utf-8_annotation.good.yaml", false, model.UTF8Validation)
|
||||
require.Empty(t, errs, "unexpected errors parsing file")
|
||||
_, errs = ParseFile("testdata/legacy_validation_annotation.good.yaml", false, model.LegacyValidation, opts)
|
||||
_, errs = ParseFile("testdata/legacy_validation_annotation.good.yaml", false, model.LegacyValidation)
|
||||
require.Empty(t, errs, "unexpected errors parsing file")
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +41,7 @@ func TestParseFileSuccessWithAliases(t *testing.T) {
|
|||
/
|
||||
sum without(instance) (rate(requests_total[5m]))
|
||||
`
|
||||
rgs, errs := ParseFile("testdata/test_aliases.yaml", false, model.UTF8Validation, parser.Options{})
|
||||
rgs, errs := ParseFile("testdata/test_aliases.yaml", false, model.UTF8Validation)
|
||||
require.Empty(t, errs, "unexpected errors parsing file")
|
||||
for _, rg := range rgs.Groups {
|
||||
require.Equal(t, "HighAlert", rg.Rules[0].Alert)
|
||||
|
|
@ -122,7 +119,7 @@ func TestParseFileFailure(t *testing.T) {
|
|||
if c.nameValidationScheme == model.UnsetValidation {
|
||||
c.nameValidationScheme = model.UTF8Validation
|
||||
}
|
||||
_, errs := ParseFile(filepath.Join("testdata", c.filename), false, c.nameValidationScheme, parser.Options{})
|
||||
_, errs := ParseFile(filepath.Join("testdata", c.filename), false, c.nameValidationScheme)
|
||||
require.NotEmpty(t, errs, "Expected error parsing %s but got none", c.filename)
|
||||
require.ErrorContainsf(t, errs[0], c.errMsg, "Expected error for %s.", c.filename)
|
||||
})
|
||||
|
|
@ -218,7 +215,7 @@ groups:
|
|||
}
|
||||
|
||||
for _, tst := range tests {
|
||||
rgs, errs := Parse([]byte(tst.ruleString), false, model.UTF8Validation, parser.Options{})
|
||||
rgs, errs := Parse([]byte(tst.ruleString), false, model.UTF8Validation)
|
||||
require.NotNil(t, rgs, "Rule parsing, rule=\n"+tst.ruleString)
|
||||
passed := (tst.shouldPass && len(errs) == 0) || (!tst.shouldPass && len(errs) > 0)
|
||||
require.True(t, passed, "Rule validation failed, rule=\n"+tst.ruleString)
|
||||
|
|
@ -245,7 +242,7 @@ groups:
|
|||
annotations:
|
||||
summary: "Instance {{ $labels.instance }} up"
|
||||
`
|
||||
_, errs := Parse([]byte(group), false, model.UTF8Validation, parser.Options{})
|
||||
_, errs := Parse([]byte(group), false, model.UTF8Validation)
|
||||
require.Len(t, errs, 2, "Expected two errors")
|
||||
var err00 *Error
|
||||
require.ErrorAs(t, errs[0], &err00)
|
||||
|
|
|
|||
|
|
@ -335,14 +335,12 @@ func BenchmarkRangeQuery(b *testing.B) {
|
|||
stor := teststorage.New(b)
|
||||
stor.DisableCompactions() // Don't want auto-compaction disrupting timings.
|
||||
|
||||
parser.SetDefaultOptions(parser.Options{EnableExtendedRangeSelectors: true})
|
||||
opts := promql.EngineOpts{
|
||||
Logger: nil,
|
||||
Reg: nil,
|
||||
MaxSamples: 50000000,
|
||||
Timeout: 100 * time.Second,
|
||||
ParserOptions: parser.Options{
|
||||
EnableExtendedRangeSelectors: true,
|
||||
},
|
||||
}
|
||||
engine := promqltest.NewTestEngineWithOpts(b, opts)
|
||||
|
||||
|
|
|
|||
|
|
@ -332,9 +332,6 @@ type EngineOpts struct {
|
|||
// EnableTypeAndUnitLabels will allow PromQL Engine to make decisions based on the type and unit labels.
|
||||
EnableTypeAndUnitLabels bool
|
||||
|
||||
// ParserOptions is the parser configuration used when parsing queries.
|
||||
ParserOptions parser.Options
|
||||
|
||||
// FeatureRegistry is the registry for tracking enabled/disabled features.
|
||||
FeatureRegistry features.Collector
|
||||
}
|
||||
|
|
@ -356,7 +353,6 @@ type Engine struct {
|
|||
enablePerStepStats bool
|
||||
enableDelayedNameRemoval bool
|
||||
enableTypeAndUnitLabels bool
|
||||
parserOptions parser.Options
|
||||
}
|
||||
|
||||
// NewEngine returns a new engine.
|
||||
|
|
@ -463,7 +459,7 @@ func NewEngine(opts EngineOpts) *Engine {
|
|||
r.Enable(features.PromQL, "per_query_lookback_delta")
|
||||
r.Enable(features.PromQL, "subqueries")
|
||||
|
||||
parser.RegisterFeatures(r, opts.ParserOptions)
|
||||
parser.RegisterFeatures(r, parser.DefaultOptions())
|
||||
}
|
||||
|
||||
return &Engine{
|
||||
|
|
@ -479,7 +475,6 @@ func NewEngine(opts EngineOpts) *Engine {
|
|||
enablePerStepStats: opts.EnablePerStepStats,
|
||||
enableDelayedNameRemoval: opts.EnableDelayedNameRemoval,
|
||||
enableTypeAndUnitLabels: opts.EnableTypeAndUnitLabels,
|
||||
parserOptions: opts.ParserOptions,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -528,7 +523,7 @@ func (ng *Engine) NewInstantQuery(ctx context.Context, q storage.Queryable, opts
|
|||
return nil, err
|
||||
}
|
||||
defer finishQueue()
|
||||
expr, err := parser.ParseExpr(qs, parser.WithOptions(ng.parserOptions))
|
||||
expr, err := parser.ParseExpr(qs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -549,7 +544,7 @@ func (ng *Engine) NewRangeQuery(ctx context.Context, q storage.Queryable, opts Q
|
|||
return nil, err
|
||||
}
|
||||
defer finishQueue()
|
||||
expr, err := parser.ParseExpr(qs, parser.WithOptions(ng.parserOptions))
|
||||
expr, err := parser.ParseExpr(qs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1653,7 +1653,7 @@ func TestExtendedRangeSelectors(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestParserConfigIsolation ensures that parser configuration is per-engine and not global.
|
||||
// TestParserConfigIsolation ensures the default parser configuration is respected.
|
||||
func TestParserConfigIsolation(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
storage := promqltest.LoadedStorage(t, `
|
||||
|
|
@ -1662,30 +1662,20 @@ func TestParserConfigIsolation(t *testing.T) {
|
|||
`)
|
||||
t.Cleanup(func() { storage.Close() })
|
||||
|
||||
// Engine with extended range selectors disabled: "smoothed" is not valid.
|
||||
optsDisabled := promql.EngineOpts{
|
||||
MaxSamples: 1000,
|
||||
Timeout: 10 * time.Second,
|
||||
ParserOptions: parser.Options{EnableExtendedRangeSelectors: false},
|
||||
}
|
||||
engineDisabled := promql.NewEngine(optsDisabled)
|
||||
|
||||
// Engine with extended range selectors enabled: "smoothed" is valid.
|
||||
optsEnabled := promql.EngineOpts{
|
||||
MaxSamples: 1000,
|
||||
Timeout: 10 * time.Second,
|
||||
ParserOptions: parser.Options{EnableExtendedRangeSelectors: true},
|
||||
}
|
||||
engineEnabled := promql.NewEngine(optsEnabled)
|
||||
|
||||
query := "metric[10s] smoothed"
|
||||
t.Run("engine_with_feature_disabled_rejects", func(t *testing.T) {
|
||||
_, err := engineDisabled.NewInstantQuery(ctx, storage, nil, query, time.Unix(10, 0))
|
||||
parser.SetDefaultOptions(parser.Options{EnableExtendedRangeSelectors: false})
|
||||
engine := promql.NewEngine(promql.EngineOpts{MaxSamples: 1000, Timeout: 10 * time.Second})
|
||||
t.Cleanup(func() { _ = engine.Close() })
|
||||
_, err := engine.NewInstantQuery(ctx, storage, nil, query, time.Unix(10, 0))
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "parse")
|
||||
})
|
||||
t.Run("engine_with_feature_enabled_accepts", func(t *testing.T) {
|
||||
q, err := engineEnabled.NewInstantQuery(ctx, storage, nil, query, time.Unix(10, 0))
|
||||
parser.SetDefaultOptions(parser.Options{EnableExtendedRangeSelectors: true})
|
||||
engine := promql.NewEngine(promql.EngineOpts{MaxSamples: 1000, Timeout: 10 * time.Second})
|
||||
t.Cleanup(func() { _ = engine.Close() })
|
||||
q, err := engine.NewInstantQuery(ctx, storage, nil, query, time.Unix(10, 0))
|
||||
require.NoError(t, err)
|
||||
defer q.Close()
|
||||
res := q.Exec(ctx)
|
||||
|
|
@ -3868,6 +3858,12 @@ func (s mockSeries) Iterator(it chunkenc.Iterator) chunkenc.Iterator {
|
|||
}
|
||||
|
||||
func TestEvaluationWithDelayedNameRemovalDisabled(t *testing.T) {
|
||||
parser.SetDefaultOptions(parser.Options{
|
||||
EnableExperimentalFunctions: true,
|
||||
ExperimentalDurationExpr: true,
|
||||
EnableExtendedRangeSelectors: true,
|
||||
EnableBinopFillModifiers: true,
|
||||
})
|
||||
opts := promql.EngineOpts{
|
||||
Logger: nil,
|
||||
Reg: nil,
|
||||
|
|
@ -3875,12 +3871,6 @@ func TestEvaluationWithDelayedNameRemovalDisabled(t *testing.T) {
|
|||
MaxSamples: 10000,
|
||||
Timeout: 10 * time.Second,
|
||||
EnableDelayedNameRemoval: false,
|
||||
ParserOptions: parser.Options{
|
||||
EnableExperimentalFunctions: true,
|
||||
ExperimentalDurationExpr: true,
|
||||
EnableExtendedRangeSelectors: true,
|
||||
EnableBinopFillModifiers: true,
|
||||
},
|
||||
}
|
||||
engine := promqltest.NewTestEngineWithOpts(t, opts)
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,20 @@ var parserPool = sync.Pool{
|
|||
},
|
||||
}
|
||||
|
||||
// defaultOptions is the default parser configuration.
|
||||
var defaultOptions Options
|
||||
|
||||
// SetDefaultOptions sets the default parser configuration.
|
||||
// It should be called once at startup before any parsing; after that, the value must not be modified.
|
||||
func SetDefaultOptions(opts Options) {
|
||||
defaultOptions = opts
|
||||
}
|
||||
|
||||
// DefaultOptions returns the default parser configuration.
|
||||
func DefaultOptions() Options {
|
||||
return defaultOptions
|
||||
}
|
||||
|
||||
// Options holds the configuration for the PromQL parser.
|
||||
type Options struct {
|
||||
EnableExperimentalFunctions bool
|
||||
|
|
@ -101,7 +115,7 @@ func NewParser(input string, opts ...Opt) *parser { //nolint:revive // unexporte
|
|||
p.parseErrors = nil
|
||||
p.generatedParserResult = nil
|
||||
p.lastClosing = posrange.Pos(0)
|
||||
p.options = Options{}
|
||||
p.options = DefaultOptions()
|
||||
|
||||
// Clear lexer struct before reusing.
|
||||
p.lex = Lexer{
|
||||
|
|
|
|||
|
|
@ -40,15 +40,15 @@ func TestEvaluations(t *testing.T) {
|
|||
func TestConcurrentRangeQueries(t *testing.T) {
|
||||
stor := teststorage.New(t)
|
||||
|
||||
parser.SetDefaultOptions(parser.Options{
|
||||
EnableExperimentalFunctions: true,
|
||||
EnableExtendedRangeSelectors: true,
|
||||
})
|
||||
opts := promql.EngineOpts{
|
||||
Logger: nil,
|
||||
Reg: nil,
|
||||
MaxSamples: 50000000,
|
||||
Timeout: 100 * time.Second,
|
||||
ParserOptions: parser.Options{
|
||||
EnableExperimentalFunctions: true,
|
||||
EnableExtendedRangeSelectors: true,
|
||||
},
|
||||
}
|
||||
engine := promqltest.NewTestEngineWithOpts(t, opts)
|
||||
|
||||
|
|
|
|||
|
|
@ -88,6 +88,12 @@ func LoadedStorage(t testing.TB, input string) *teststorage.TestStorage {
|
|||
|
||||
// NewTestEngine creates a promql.Engine with enablePerStepStats, lookbackDelta and maxSamples, and returns it.
|
||||
func NewTestEngine(tb testing.TB, enablePerStepStats bool, lookbackDelta time.Duration, maxSamples int) *promql.Engine {
|
||||
parser.SetDefaultOptions(parser.Options{
|
||||
EnableExperimentalFunctions: true,
|
||||
ExperimentalDurationExpr: true,
|
||||
EnableExtendedRangeSelectors: true,
|
||||
EnableBinopFillModifiers: true,
|
||||
})
|
||||
return NewTestEngineWithOpts(tb, promql.EngineOpts{
|
||||
Logger: nil,
|
||||
Reg: nil,
|
||||
|
|
@ -99,12 +105,6 @@ func NewTestEngine(tb testing.TB, enablePerStepStats bool, lookbackDelta time.Du
|
|||
EnablePerStepStats: enablePerStepStats,
|
||||
LookbackDelta: lookbackDelta,
|
||||
EnableDelayedNameRemoval: true,
|
||||
ParserOptions: parser.Options{
|
||||
EnableExperimentalFunctions: true,
|
||||
ExperimentalDurationExpr: true,
|
||||
EnableExtendedRangeSelectors: true,
|
||||
EnableBinopFillModifiers: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,7 +124,6 @@ type ManagerOptions struct {
|
|||
ForGracePeriod time.Duration
|
||||
ResendDelay time.Duration
|
||||
GroupLoader GroupLoader
|
||||
ParserOptions parser.Options
|
||||
DefaultRuleQueryOffset func() time.Duration
|
||||
MaxConcurrentEvals int64
|
||||
ConcurrentEvalsEnabled bool
|
||||
|
|
@ -160,7 +159,7 @@ func NewManager(o *ManagerOptions) *Manager {
|
|||
}
|
||||
|
||||
if o.GroupLoader == nil {
|
||||
o.GroupLoader = FileLoader{ParserOptions: o.ParserOptions}
|
||||
o.GroupLoader = FileLoader{}
|
||||
}
|
||||
|
||||
if o.RuleConcurrencyController == nil {
|
||||
|
|
@ -321,18 +320,15 @@ type GroupLoader interface {
|
|||
}
|
||||
|
||||
// FileLoader is the default GroupLoader implementation. It defers to rulefmt.ParseFile
|
||||
// and parser.ParseExpr with the configured ParserOptions.
|
||||
type FileLoader struct {
|
||||
// ParserOptions is the parser configuration used when parsing rule expressions.
|
||||
ParserOptions parser.Options
|
||||
// and parser.ParseExpr and parser.DefaultOptions.
|
||||
type FileLoader struct{}
|
||||
|
||||
func (FileLoader) Load(identifier string, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme) (*rulefmt.RuleGroups, []error) {
|
||||
return rulefmt.ParseFile(identifier, ignoreUnknownFields, nameValidationScheme)
|
||||
}
|
||||
|
||||
func (fl FileLoader) Load(identifier string, ignoreUnknownFields bool, nameValidationScheme model.ValidationScheme) (*rulefmt.RuleGroups, []error) {
|
||||
return rulefmt.ParseFile(identifier, ignoreUnknownFields, nameValidationScheme, fl.ParserOptions)
|
||||
}
|
||||
|
||||
func (fl FileLoader) Parse(query string) (parser.Expr, error) {
|
||||
return parser.ParseExpr(query, parser.WithOptions(fl.ParserOptions))
|
||||
func (FileLoader) Parse(query string) (parser.Expr, error) {
|
||||
return parser.ParseExpr(query)
|
||||
}
|
||||
|
||||
// LoadGroups reads groups from a list of files.
|
||||
|
|
@ -632,7 +628,7 @@ func ParseFiles(patterns []string, nameValidationScheme model.ValidationScheme)
|
|||
}
|
||||
}
|
||||
for fn, pat := range files {
|
||||
_, errs := rulefmt.ParseFile(fn, false, nameValidationScheme, parser.Options{})
|
||||
_, errs := rulefmt.ParseFile(fn, false, nameValidationScheme)
|
||||
if len(errs) > 0 {
|
||||
return fmt.Errorf("parse rules from file %q (pattern: %q): %w", fn, pat, errors.Join(errs...))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -809,7 +809,7 @@ func TestUpdate(t *testing.T) {
|
|||
}
|
||||
|
||||
// Groups will be recreated if updated.
|
||||
rgs, errs := rulefmt.ParseFile("fixtures/rules.yaml", false, model.UTF8Validation, parser.Options{})
|
||||
rgs, errs := rulefmt.ParseFile("fixtures/rules.yaml", false, model.UTF8Validation)
|
||||
require.Empty(t, errs, "file parsing failures")
|
||||
|
||||
tmpFile, err := os.CreateTemp("", "rules.test.*.yaml")
|
||||
|
|
|
|||
|
|
@ -257,7 +257,6 @@ type API struct {
|
|||
|
||||
codecs []Codec
|
||||
|
||||
parserOptions parser.Options
|
||||
featureRegistry features.Collector
|
||||
openAPIBuilder *OpenAPIBuilder
|
||||
}
|
||||
|
|
@ -300,7 +299,6 @@ func NewAPI(
|
|||
enableTypeAndUnitLabels bool,
|
||||
appendMetadata bool,
|
||||
overrideErrorCode OverrideErrorCode,
|
||||
parserOptions parser.Options,
|
||||
featureRegistry features.Collector,
|
||||
openAPIOptions OpenAPIOptions,
|
||||
) *API {
|
||||
|
|
@ -332,7 +330,6 @@ func NewAPI(
|
|||
notificationsGetter: notificationsGetter,
|
||||
notificationsSub: notificationsSub,
|
||||
overrideErrorCode: overrideErrorCode,
|
||||
parserOptions: parserOptions,
|
||||
featureRegistry: featureRegistry,
|
||||
openAPIBuilder: NewOpenAPIBuilder(openAPIOptions, logger),
|
||||
|
||||
|
|
@ -565,8 +562,8 @@ func (api *API) query(r *http.Request) (result apiFuncResult) {
|
|||
}, nil, warnings, qry.Close}
|
||||
}
|
||||
|
||||
func (api *API) formatQuery(r *http.Request) (result apiFuncResult) {
|
||||
expr, err := parser.ParseExpr(r.FormValue("query"), parser.WithOptions(api.parserOptions))
|
||||
func (*API) formatQuery(r *http.Request) (result apiFuncResult) {
|
||||
expr, err := parser.ParseExpr(r.FormValue("query"))
|
||||
if err != nil {
|
||||
return invalidParamError(err, "query")
|
||||
}
|
||||
|
|
@ -574,8 +571,8 @@ func (api *API) formatQuery(r *http.Request) (result apiFuncResult) {
|
|||
return apiFuncResult{expr.Pretty(0), nil, nil, nil}
|
||||
}
|
||||
|
||||
func (api *API) parseQuery(r *http.Request) apiFuncResult {
|
||||
expr, err := parser.ParseExpr(r.FormValue("query"), parser.WithOptions(api.parserOptions))
|
||||
func (*API) parseQuery(r *http.Request) apiFuncResult {
|
||||
expr, err := parser.ParseExpr(r.FormValue("query"))
|
||||
if err != nil {
|
||||
return invalidParamError(err, "query")
|
||||
}
|
||||
|
|
@ -704,7 +701,7 @@ func (api *API) queryExemplars(r *http.Request) apiFuncResult {
|
|||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
|
||||
expr, err := parser.ParseExpr(r.FormValue("query"), parser.WithOptions(api.parserOptions))
|
||||
expr, err := parser.ParseExpr(r.FormValue("query"))
|
||||
if err != nil {
|
||||
return apiFuncResult{nil, &apiError{errorBadData, err}, nil, nil}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import (
|
|||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/model/labels"
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
"github.com/prometheus/prometheus/promql/promqltest"
|
||||
"github.com/prometheus/prometheus/rules"
|
||||
"github.com/prometheus/prometheus/scrape"
|
||||
|
|
@ -169,7 +168,6 @@ func createPrometheusAPI(t *testing.T, q storage.SampleAndChunkQueryable, overri
|
|||
false,
|
||||
false,
|
||||
overrideErrorCode,
|
||||
parser.Options{},
|
||||
nil,
|
||||
OpenAPIOptions{},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import (
|
|||
|
||||
"github.com/prometheus/common/route"
|
||||
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
"github.com/prometheus/prometheus/web/api/testhelpers"
|
||||
)
|
||||
|
||||
|
|
@ -102,7 +101,6 @@ func newTestAPI(t *testing.T, cfg testhelpers.APIConfig) *testhelpers.APIWrapper
|
|||
false, // enableTypeAndUnitLabels
|
||||
false, // appendMetadata
|
||||
nil, // overrideErrorCode
|
||||
parser.Options{}, // parserOptions
|
||||
nil, // featureRegistry
|
||||
OpenAPIOptions{}, // openAPIOptions
|
||||
)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ import (
|
|||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/notifier"
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
"github.com/prometheus/prometheus/rules"
|
||||
"github.com/prometheus/prometheus/scrape"
|
||||
"github.com/prometheus/prometheus/storage"
|
||||
|
|
@ -304,7 +303,6 @@ type Options struct {
|
|||
|
||||
Gatherer prometheus.Gatherer
|
||||
Registerer prometheus.Registerer
|
||||
ParserOptions parser.Options
|
||||
FeatureRegistry features.Collector
|
||||
}
|
||||
|
||||
|
|
@ -408,7 +406,6 @@ func New(logger *slog.Logger, o *Options) *Handler {
|
|||
o.EnableTypeAndUnitLabels,
|
||||
o.AppendMetadata,
|
||||
nil,
|
||||
o.ParserOptions,
|
||||
o.FeatureRegistry,
|
||||
api_v1.OpenAPIOptions{
|
||||
ExternalURL: o.ExternalURL.String(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue