mirror of
				https://github.com/prometheus/prometheus.git
				synced 2025-11-03 18:01:18 +01:00 
			
		
		
		
	There are four label-matching ops for selecting timeseries now: - Equal: = - NotEqual: != - RegexMatch: =~ - RegexNoMatch: !~ Instead of looking up labels by a simple clientmodel.LabelSet (basically an equals op for every key/value pair in the set), timeseries fingerprint selection is now done via a list of metric.LabelMatchers. Change-Id: I510a83f761198e80946146770ebb64e4abc3bb96
		
			
				
	
	
		
			243 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			243 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
// Copyright 2013 Prometheus Team
 | 
						|
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
// you may not use this file except in compliance with the License.
 | 
						|
// You may obtain a copy of the License at
 | 
						|
//
 | 
						|
// http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
//
 | 
						|
// Unless required by applicable law or agreed to in writing, software
 | 
						|
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
// See the License for the specific language governing permissions and
 | 
						|
// limitations under the License.
 | 
						|
 | 
						|
%{
 | 
						|
        package rules
 | 
						|
 | 
						|
        import (
 | 
						|
          clientmodel "github.com/prometheus/client_golang/model"
 | 
						|
 | 
						|
          "github.com/prometheus/prometheus/rules/ast"
 | 
						|
          "github.com/prometheus/prometheus/storage/metric"
 | 
						|
        )
 | 
						|
%}
 | 
						|
 | 
						|
%union {
 | 
						|
        num clientmodel.SampleValue
 | 
						|
        str string
 | 
						|
        ruleNode ast.Node
 | 
						|
        ruleNodeSlice []ast.Node
 | 
						|
        boolean bool
 | 
						|
        labelNameSlice clientmodel.LabelNames
 | 
						|
        labelSet clientmodel.LabelSet
 | 
						|
        labelMatcher *metric.LabelMatcher
 | 
						|
        labelMatchers metric.LabelMatchers
 | 
						|
}
 | 
						|
 | 
						|
/* We simulate multiple start symbols for closely-related grammars via dummy tokens. See
 | 
						|
   http://www.gnu.org/software/bison/manual/html_node/Multiple-start_002dsymbols.html
 | 
						|
   Reason: we want to be able to parse lists of named rules as well as single expressions.
 | 
						|
   */
 | 
						|
%token START_RULES START_EXPRESSION
 | 
						|
 | 
						|
%token <str> IDENTIFIER STRING DURATION METRICNAME
 | 
						|
%token <num> NUMBER
 | 
						|
%token PERMANENT GROUP_OP KEEPING_EXTRA
 | 
						|
%token <str> AGGR_OP CMP_OP ADDITIVE_OP MULT_OP
 | 
						|
%token ALERT IF FOR WITH SUMMARY DESCRIPTION
 | 
						|
 | 
						|
%type <ruleNodeSlice> func_arg_list
 | 
						|
%type <labelNameSlice> label_list grouping_opts
 | 
						|
%type <labelSet> label_assign label_assign_list rule_labels
 | 
						|
%type <labelMatcher> label_match
 | 
						|
%type <labelMatchers> label_match_list label_matches
 | 
						|
%type <ruleNode> rule_expr func_arg
 | 
						|
%type <boolean> qualifier extra_labels_opts
 | 
						|
%type <str> for_duration metric_name label_match_type
 | 
						|
 | 
						|
%right '='
 | 
						|
%left CMP_OP
 | 
						|
%left ADDITIVE_OP
 | 
						|
%left MULT_OP
 | 
						|
%start start
 | 
						|
 | 
						|
%%
 | 
						|
start              : START_RULES rules_stat_list
 | 
						|
                   | START_EXPRESSION saved_rule_expr
 | 
						|
                   ;
 | 
						|
 | 
						|
rules_stat_list    : /* empty */
 | 
						|
                   | rules_stat_list rules_stat
 | 
						|
                   ;
 | 
						|
 | 
						|
saved_rule_expr    : rule_expr
 | 
						|
                     { yylex.(*RulesLexer).parsedExpr = $1 }
 | 
						|
                   ;
 | 
						|
 | 
						|
 | 
						|
rules_stat         : qualifier metric_name rule_labels '=' rule_expr
 | 
						|
                     {
 | 
						|
                       rule, err := CreateRecordingRule($2, $3, $5, $1)
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                       yylex.(*RulesLexer).parsedRules = append(yylex.(*RulesLexer).parsedRules, rule)
 | 
						|
                     }
 | 
						|
                   | ALERT IDENTIFIER IF rule_expr for_duration WITH rule_labels SUMMARY STRING DESCRIPTION STRING
 | 
						|
                     {
 | 
						|
                       rule, err := CreateAlertingRule($2, $4, $5, $7, $9, $11)
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                       yylex.(*RulesLexer).parsedRules = append(yylex.(*RulesLexer).parsedRules, rule)
 | 
						|
                     }
 | 
						|
                   ;
 | 
						|
 | 
						|
for_duration       : /* empty */
 | 
						|
                     { $$ = "0s" }
 | 
						|
                   | FOR DURATION
 | 
						|
                     { $$ = $2 }
 | 
						|
                   ;
 | 
						|
 | 
						|
qualifier          : /* empty */
 | 
						|
                     { $$ = false }
 | 
						|
                   | PERMANENT
 | 
						|
                     { $$ = true }
 | 
						|
                   ;
 | 
						|
 | 
						|
metric_name        : METRICNAME
 | 
						|
                     { $$ = $1 }
 | 
						|
                   | IDENTIFIER
 | 
						|
                     { $$ = $1 }
 | 
						|
                   ;
 | 
						|
 | 
						|
rule_labels        : /* empty */
 | 
						|
                     { $$ = clientmodel.LabelSet{} }
 | 
						|
                   | '{' label_assign_list '}'
 | 
						|
                     { $$ = $2  }
 | 
						|
                   | '{' '}'
 | 
						|
                     { $$ = clientmodel.LabelSet{} }
 | 
						|
 | 
						|
label_assign_list  : label_assign
 | 
						|
                     { $$ = $1 }
 | 
						|
                   | label_assign_list ',' label_assign
 | 
						|
                     { for k, v := range $3 { $$[k] = v } }
 | 
						|
                   ;
 | 
						|
 | 
						|
label_assign       : IDENTIFIER '=' STRING
 | 
						|
                     { $$ = clientmodel.LabelSet{ clientmodel.LabelName($1): clientmodel.LabelValue($3) } }
 | 
						|
                   ;
 | 
						|
 | 
						|
label_matches      : /* empty */
 | 
						|
                     { $$ = metric.LabelMatchers{} }
 | 
						|
                   | '{' '}'
 | 
						|
                     { $$ = metric.LabelMatchers{} }
 | 
						|
                   | '{' label_match_list '}'
 | 
						|
                     { $$ = $2 }
 | 
						|
                   ;
 | 
						|
 | 
						|
label_match_list   : label_match
 | 
						|
                     { $$ = metric.LabelMatchers{$1} }
 | 
						|
                   | label_match_list ',' label_match
 | 
						|
                     { $$ = append($$, $3) }
 | 
						|
                   ;
 | 
						|
 | 
						|
label_match        : IDENTIFIER label_match_type STRING
 | 
						|
                     {
 | 
						|
                       var err error
 | 
						|
                       $$, err = newLabelMatcher($2, clientmodel.LabelName($1), clientmodel.LabelValue($3))
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                     }
 | 
						|
                   ;
 | 
						|
 | 
						|
label_match_type   : '='
 | 
						|
                     { $$ = "=" }
 | 
						|
                   | CMP_OP
 | 
						|
                     { $$ = $1 }
 | 
						|
                   ;
 | 
						|
 | 
						|
rule_expr          : '(' rule_expr ')'
 | 
						|
                     { $$ = $2 }
 | 
						|
                   | metric_name label_matches
 | 
						|
                     {
 | 
						|
                       var err error
 | 
						|
                       m, err := metric.NewLabelMatcher(metric.Equal, clientmodel.MetricNameLabel, clientmodel.LabelValue($1))
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                       $2 = append($2, m)
 | 
						|
                       $$ = ast.NewVectorSelector($2)
 | 
						|
                     }
 | 
						|
                   | IDENTIFIER '(' func_arg_list ')'
 | 
						|
                     {
 | 
						|
                       var err error
 | 
						|
                       $$, err = NewFunctionCall($1, $3)
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                     }
 | 
						|
                   | IDENTIFIER '(' ')'
 | 
						|
                     {
 | 
						|
                       var err error
 | 
						|
                       $$, err = NewFunctionCall($1, []ast.Node{})
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                     }
 | 
						|
                   | rule_expr '[' DURATION ']'
 | 
						|
                     {
 | 
						|
                       var err error
 | 
						|
                       $$, err = NewMatrixSelector($1, $3)
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                     }
 | 
						|
                   | AGGR_OP '(' rule_expr ')' grouping_opts extra_labels_opts
 | 
						|
                     {
 | 
						|
                       var err error
 | 
						|
                       $$, err = NewVectorAggregation($1, $3, $5, $6)
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                     }
 | 
						|
                   /* Yacc can only attach associativity to terminals, so we
 | 
						|
                    * have to list all operators here. */
 | 
						|
                   | rule_expr ADDITIVE_OP rule_expr
 | 
						|
                     {
 | 
						|
                       var err error
 | 
						|
                       $$, err = NewArithExpr($2, $1, $3)
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                     }
 | 
						|
                   | rule_expr MULT_OP rule_expr
 | 
						|
                     {
 | 
						|
                       var err error
 | 
						|
                       $$, err = NewArithExpr($2, $1, $3)
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                     }
 | 
						|
                   | rule_expr CMP_OP rule_expr
 | 
						|
                     {
 | 
						|
                       var err error
 | 
						|
                       $$, err = NewArithExpr($2, $1, $3)
 | 
						|
                       if err != nil { yylex.Error(err.Error()); return 1 }
 | 
						|
                     }
 | 
						|
                   | NUMBER
 | 
						|
                     { $$ = ast.NewScalarLiteral($1)}
 | 
						|
                   ;
 | 
						|
 | 
						|
extra_labels_opts  :
 | 
						|
                     { $$ = false }
 | 
						|
                   | KEEPING_EXTRA
 | 
						|
                     { $$ = true }
 | 
						|
                   ;
 | 
						|
 | 
						|
grouping_opts      :
 | 
						|
                     { $$ = clientmodel.LabelNames{} }
 | 
						|
                   | GROUP_OP '(' label_list ')'
 | 
						|
                     { $$ = $3 }
 | 
						|
                   ;
 | 
						|
 | 
						|
label_list         : IDENTIFIER
 | 
						|
                     { $$ = clientmodel.LabelNames{clientmodel.LabelName($1)} }
 | 
						|
                   | label_list ',' IDENTIFIER
 | 
						|
                     { $$ = append($$, clientmodel.LabelName($3)) }
 | 
						|
                   ;
 | 
						|
 | 
						|
func_arg_list      : func_arg
 | 
						|
                     { $$ = []ast.Node{$1} }
 | 
						|
                   | func_arg_list ',' func_arg
 | 
						|
                     { $$ = append($$, $3) }
 | 
						|
                   ;
 | 
						|
 | 
						|
func_arg           : rule_expr
 | 
						|
                     { $$ = $1 }
 | 
						|
                   | STRING
 | 
						|
                     { $$ = ast.NewStringLiteral($1) }
 | 
						|
                   ;
 | 
						|
%%
 |