mirror of
https://github.com/prometheus/prometheus.git
synced 2025-02-21 03:16:00 -08:00
Implement Stringer interface for rules and all their children.
This commit is contained in:
parent
757ab938db
commit
74cb676537
|
@ -13,6 +13,10 @@
|
||||||
|
|
||||||
package model
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// The label name indicating the metric name of a timeseries.
|
// The label name indicating the metric name of a timeseries.
|
||||||
MetricNameLabel = LabelName("name")
|
MetricNameLabel = LabelName("name")
|
||||||
|
@ -50,3 +54,11 @@ func (l LabelNames) Less(i, j int) bool {
|
||||||
func (l LabelNames) Swap(i, j int) {
|
func (l LabelNames) Swap(i, j int) {
|
||||||
l[i], l[j] = l[j], l[i]
|
l[i], l[j] = l[j], l[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l LabelNames) String() string {
|
||||||
|
labelStrings := make([]string, 0, len(l))
|
||||||
|
for _, label := range l {
|
||||||
|
labelStrings = append(labelStrings, string(label))
|
||||||
|
}
|
||||||
|
return strings.Join(labelStrings, ", ")
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
dto "github.com/prometheus/prometheus/model/generated"
|
dto "github.com/prometheus/prometheus/model/generated"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -50,36 +51,14 @@ func (l LabelSet) Merge(other LabelSet) LabelSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l LabelSet) String() string {
|
func (l LabelSet) String() string {
|
||||||
var (
|
labelStrings := make([]string, 0, len(l))
|
||||||
buffer bytes.Buffer
|
for label, value := range l {
|
||||||
labels LabelNames
|
labelStrings = append(labelStrings, fmt.Sprintf("%s='%s'", label, value))
|
||||||
labelCount int = len(l)
|
|
||||||
)
|
|
||||||
|
|
||||||
for name := range l {
|
|
||||||
labels = append(labels, name)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(labels)
|
sort.Strings(labelStrings)
|
||||||
|
|
||||||
fmt.Fprintf(&buffer, "{")
|
return fmt.Sprintf("{%s}", strings.Join(labelStrings, ", "))
|
||||||
for i := 0; i < labelCount; i++ {
|
|
||||||
var (
|
|
||||||
label = labels[i]
|
|
||||||
value = l[label]
|
|
||||||
)
|
|
||||||
|
|
||||||
switch i {
|
|
||||||
case labelCount - 1:
|
|
||||||
fmt.Fprintf(&buffer, "%s=%s", label, value)
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(&buffer, "%s=%s, ", label, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Fprintf(&buffer, "}")
|
|
||||||
|
|
||||||
return buffer.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l LabelSet) ToMetric() Metric {
|
func (l LabelSet) ToMetric() Metric {
|
||||||
|
|
|
@ -147,6 +147,10 @@ func (rule AlertingRule) ToDotGraph() string {
|
||||||
return graph
|
return graph
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rule AlertingRule) String() string {
|
||||||
|
return fmt.Sprintf("ALERT %s IF %s FOR %s WITH %s\n", rule.name, rule.vector, utility.DurationToString(rule.holdDuration), rule.labels)
|
||||||
|
}
|
||||||
|
|
||||||
// Construct a new AlertingRule.
|
// Construct a new AlertingRule.
|
||||||
func NewAlertingRule(name string, vector ast.VectorNode, holdDuration time.Duration, labels model.LabelSet) *AlertingRule {
|
func NewAlertingRule(name string, vector ast.VectorNode, holdDuration time.Duration, labels model.LabelSet) *AlertingRule {
|
||||||
return &AlertingRule{
|
return &AlertingRule{
|
||||||
|
|
|
@ -85,10 +85,13 @@ const (
|
||||||
// Interfaces.
|
// Interfaces.
|
||||||
|
|
||||||
// All node interfaces include the Node interface.
|
// All node interfaces include the Node interface.
|
||||||
|
type Nodes []Node
|
||||||
|
|
||||||
type Node interface {
|
type Node interface {
|
||||||
Type() ExprType
|
Type() ExprType
|
||||||
|
Children() Nodes
|
||||||
NodeTreeToDotGraph() string
|
NodeTreeToDotGraph() string
|
||||||
Children() []Node
|
String() string
|
||||||
}
|
}
|
||||||
|
|
||||||
// All node types implement one of the following interfaces. The name of the
|
// All node types implement one of the following interfaces. The name of the
|
||||||
|
@ -126,7 +129,7 @@ type (
|
||||||
// A function of numeric return type.
|
// A function of numeric return type.
|
||||||
ScalarFunctionCall struct {
|
ScalarFunctionCall struct {
|
||||||
function *Function
|
function *Function
|
||||||
args []Node
|
args Nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
// An arithmetic expression of numeric type.
|
// An arithmetic expression of numeric type.
|
||||||
|
@ -151,13 +154,13 @@ type (
|
||||||
// A function of vector return type.
|
// A function of vector return type.
|
||||||
VectorFunctionCall struct {
|
VectorFunctionCall struct {
|
||||||
function *Function
|
function *Function
|
||||||
args []Node
|
args Nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
// A vector aggregation with vector return type.
|
// A vector aggregation with vector return type.
|
||||||
VectorAggregation struct {
|
VectorAggregation struct {
|
||||||
aggrType AggrType
|
aggrType AggrType
|
||||||
groupBy []model.LabelName
|
groupBy model.LabelNames
|
||||||
vector VectorNode
|
vector VectorNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +197,7 @@ type (
|
||||||
// A function of string return type.
|
// A function of string return type.
|
||||||
StringFunctionCall struct {
|
StringFunctionCall struct {
|
||||||
function *Function
|
function *Function
|
||||||
args []Node
|
args Nodes
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -214,16 +217,16 @@ func (node StringLiteral) Type() ExprType { return STRING }
|
||||||
func (node StringFunctionCall) Type() ExprType { return STRING }
|
func (node StringFunctionCall) Type() ExprType { return STRING }
|
||||||
|
|
||||||
// Node.Children() methods.
|
// Node.Children() methods.
|
||||||
func (node ScalarLiteral) Children() []Node { return []Node{} }
|
func (node ScalarLiteral) Children() Nodes { return Nodes{} }
|
||||||
func (node ScalarFunctionCall) Children() []Node { return node.args }
|
func (node ScalarFunctionCall) Children() Nodes { return node.args }
|
||||||
func (node ScalarArithExpr) Children() []Node { return []Node{node.lhs, node.rhs} }
|
func (node ScalarArithExpr) Children() Nodes { return Nodes{node.lhs, node.rhs} }
|
||||||
func (node VectorLiteral) Children() []Node { return []Node{} }
|
func (node VectorLiteral) Children() Nodes { return Nodes{} }
|
||||||
func (node VectorFunctionCall) Children() []Node { return node.args }
|
func (node VectorFunctionCall) Children() Nodes { return node.args }
|
||||||
func (node VectorAggregation) Children() []Node { return []Node{node.vector} }
|
func (node VectorAggregation) Children() Nodes { return Nodes{node.vector} }
|
||||||
func (node VectorArithExpr) Children() []Node { return []Node{node.lhs, node.rhs} }
|
func (node VectorArithExpr) Children() Nodes { return Nodes{node.lhs, node.rhs} }
|
||||||
func (node MatrixLiteral) Children() []Node { return []Node{} }
|
func (node MatrixLiteral) Children() Nodes { return Nodes{} }
|
||||||
func (node StringLiteral) Children() []Node { return []Node{} }
|
func (node StringLiteral) Children() Nodes { return Nodes{} }
|
||||||
func (node StringFunctionCall) Children() []Node { return node.args }
|
func (node StringFunctionCall) Children() Nodes { return node.args }
|
||||||
|
|
||||||
func (node *ScalarLiteral) Eval(timestamp time.Time, view *viewAdapter) model.SampleValue {
|
func (node *ScalarLiteral) Eval(timestamp time.Time, view *viewAdapter) model.SampleValue {
|
||||||
return node.value
|
return node.value
|
||||||
|
@ -622,7 +625,7 @@ func NewVectorLiteral(labels model.LabelSet) *VectorLiteral {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVectorAggregation(aggrType AggrType, vector VectorNode, groupBy []model.LabelName) *VectorAggregation {
|
func NewVectorAggregation(aggrType AggrType, vector VectorNode, groupBy model.LabelNames) *VectorAggregation {
|
||||||
return &VectorAggregation{
|
return &VectorAggregation{
|
||||||
aggrType: aggrType,
|
aggrType: aggrType,
|
||||||
groupBy: groupBy,
|
groupBy: groupBy,
|
||||||
|
@ -630,7 +633,7 @@ func NewVectorAggregation(aggrType AggrType, vector VectorNode, groupBy []model.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFunctionCall(function *Function, args []Node) (Node, error) {
|
func NewFunctionCall(function *Function, args Nodes) (Node, error) {
|
||||||
if err := function.CheckArgTypes(args); err != nil {
|
if err := function.CheckArgTypes(args); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -654,7 +657,7 @@ func NewFunctionCall(function *Function, args []Node) (Node, error) {
|
||||||
panic("Function with invalid return type")
|
panic("Function with invalid return type")
|
||||||
}
|
}
|
||||||
|
|
||||||
func nodesHaveTypes(nodes []Node, exprTypes []ExprType) bool {
|
func nodesHaveTypes(nodes Nodes, exprTypes []ExprType) bool {
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
correctType := false
|
correctType := false
|
||||||
for _, exprType := range exprTypes {
|
for _, exprType := range exprTypes {
|
||||||
|
@ -670,7 +673,7 @@ func nodesHaveTypes(nodes []Node, exprTypes []ExprType) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewArithExpr(opType BinOpType, lhs Node, rhs Node) (Node, error) {
|
func NewArithExpr(opType BinOpType, lhs Node, rhs Node) (Node, error) {
|
||||||
if !nodesHaveTypes([]Node{lhs, rhs}, []ExprType{SCALAR, VECTOR}) {
|
if !nodesHaveTypes(Nodes{lhs, rhs}, []ExprType{SCALAR, VECTOR}) {
|
||||||
return nil, errors.New("Binary operands must be of vector or scalar type")
|
return nil, errors.New("Binary operands must be of vector or scalar type")
|
||||||
}
|
}
|
||||||
if lhs.Type() == SCALAR && rhs.Type() == VECTOR {
|
if lhs.Type() == SCALAR && rhs.Type() == VECTOR {
|
||||||
|
|
|
@ -23,7 +23,8 @@ type emptyRangeNode struct{}
|
||||||
|
|
||||||
func (node emptyRangeNode) Type() ExprType { return MATRIX }
|
func (node emptyRangeNode) Type() ExprType { return MATRIX }
|
||||||
func (node emptyRangeNode) NodeTreeToDotGraph() string { return "" }
|
func (node emptyRangeNode) NodeTreeToDotGraph() string { return "" }
|
||||||
func (node emptyRangeNode) Children() []Node { return []Node{} }
|
func (node emptyRangeNode) String() string { return "" }
|
||||||
|
func (node emptyRangeNode) Children() Nodes { return Nodes{} }
|
||||||
|
|
||||||
func (node emptyRangeNode) Eval(timestamp time.Time, view *viewAdapter) Matrix {
|
func (node emptyRangeNode) Eval(timestamp time.Time, view *viewAdapter) Matrix {
|
||||||
return Matrix{
|
return Matrix{
|
||||||
|
|
|
@ -45,6 +45,8 @@ func (opType BinOpType) String() string {
|
||||||
NE: "!=",
|
NE: "!=",
|
||||||
GE: ">=",
|
GE: ">=",
|
||||||
LE: "<=",
|
LE: "<=",
|
||||||
|
AND: "AND",
|
||||||
|
OR: "OR",
|
||||||
}
|
}
|
||||||
return opTypeMap[opType]
|
return opTypeMap[opType]
|
||||||
}
|
}
|
||||||
|
@ -71,13 +73,13 @@ func (exprType ExprType) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (vector Vector) String() string {
|
func (vector Vector) String() string {
|
||||||
metricStrings := []string{}
|
metricStrings := make([]string, 0, len(vector))
|
||||||
for _, sample := range vector {
|
for _, sample := range vector {
|
||||||
metricName, ok := sample.Metric[model.MetricNameLabel]
|
metricName, ok := sample.Metric[model.MetricNameLabel]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("Tried to print vector without metric name")
|
panic("Tried to print vector without metric name")
|
||||||
}
|
}
|
||||||
labelStrings := []string{}
|
labelStrings := make([]string, 0, len(sample.Metric)-1)
|
||||||
for label, value := range sample.Metric {
|
for label, value := range sample.Metric {
|
||||||
if label != model.MetricNameLabel {
|
if label != model.MetricNameLabel {
|
||||||
// TODO escape special chars in label values here and elsewhere.
|
// TODO escape special chars in label values here and elsewhere.
|
||||||
|
@ -95,20 +97,20 @@ func (vector Vector) String() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (matrix Matrix) String() string {
|
func (matrix Matrix) String() string {
|
||||||
metricStrings := []string{}
|
metricStrings := make([]string, 0, len(matrix))
|
||||||
for _, sampleSet := range matrix {
|
for _, sampleSet := range matrix {
|
||||||
metricName, ok := sampleSet.Metric[model.MetricNameLabel]
|
metricName, ok := sampleSet.Metric[model.MetricNameLabel]
|
||||||
if !ok {
|
if !ok {
|
||||||
panic("Tried to print matrix without metric name")
|
panic("Tried to print matrix without metric name")
|
||||||
}
|
}
|
||||||
labelStrings := []string{}
|
labelStrings := make([]string, 0, len(sampleSet.Metric)-1)
|
||||||
for label, value := range sampleSet.Metric {
|
for label, value := range sampleSet.Metric {
|
||||||
if label != model.MetricNameLabel {
|
if label != model.MetricNameLabel {
|
||||||
labelStrings = append(labelStrings, fmt.Sprintf("%s='%s'", label, value))
|
labelStrings = append(labelStrings, fmt.Sprintf("%s='%s'", label, value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Strings(labelStrings)
|
sort.Strings(labelStrings)
|
||||||
valueStrings := []string{}
|
valueStrings := make([]string, 0, len(sampleSet.Values))
|
||||||
for _, value := range sampleSet.Values {
|
for _, value := range sampleSet.Values {
|
||||||
valueStrings = append(valueStrings,
|
valueStrings = append(valueStrings,
|
||||||
fmt.Sprintf("\n%v @[%v]", value.Value, value.Timestamp))
|
fmt.Sprintf("\n%v @[%v]", value.Value, value.Timestamp))
|
||||||
|
@ -204,27 +206,6 @@ func EvalToString(node Node, timestamp time.Time, format OutputFormat, storage *
|
||||||
panic("Switch didn't cover all node types")
|
panic("Switch didn't cover all node types")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (node *VectorLiteral) String() string {
|
|
||||||
metricName, ok := node.labels[model.MetricNameLabel]
|
|
||||||
if !ok {
|
|
||||||
panic("Tried to print vector without metric name")
|
|
||||||
}
|
|
||||||
labelStrings := []string{}
|
|
||||||
for label, value := range node.labels {
|
|
||||||
if label != model.MetricNameLabel {
|
|
||||||
labelStrings = append(labelStrings, fmt.Sprintf("%s='%s'", label, value))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sort.Strings(labelStrings)
|
|
||||||
return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ","))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (node *MatrixLiteral) String() string {
|
|
||||||
vectorString := (&VectorLiteral{labels: node.labels}).String()
|
|
||||||
intervalString := fmt.Sprintf("['%s']", utility.DurationToString(node.interval))
|
|
||||||
return vectorString + intervalString
|
|
||||||
}
|
|
||||||
|
|
||||||
func (node *ScalarLiteral) NodeTreeToDotGraph() string {
|
func (node *ScalarLiteral) NodeTreeToDotGraph() string {
|
||||||
return fmt.Sprintf("%#p[label=\"%v\"];\n", node, node.value)
|
return fmt.Sprintf("%#p[label=\"%v\"];\n", node, node.value)
|
||||||
}
|
}
|
||||||
|
@ -268,7 +249,7 @@ func (node *VectorFunctionCall) NodeTreeToDotGraph() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (node *VectorAggregation) NodeTreeToDotGraph() string {
|
func (node *VectorAggregation) NodeTreeToDotGraph() string {
|
||||||
groupByStrings := []string{}
|
groupByStrings := make([]string, 0, len(node.groupBy))
|
||||||
for _, label := range node.groupBy {
|
for _, label := range node.groupBy {
|
||||||
groupByStrings = append(groupByStrings, string(label))
|
groupByStrings = append(groupByStrings, string(label))
|
||||||
}
|
}
|
||||||
|
@ -306,3 +287,64 @@ func (node *StringFunctionCall) NodeTreeToDotGraph() string {
|
||||||
graph += functionArgsToDotGraph(node, node.args)
|
graph += functionArgsToDotGraph(node, node.args)
|
||||||
return graph
|
return graph
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (nodes Nodes) String() string {
|
||||||
|
nodeStrings := make([]string, 0, len(nodes))
|
||||||
|
for _, node := range nodes {
|
||||||
|
nodeStrings = append(nodeStrings, node.String())
|
||||||
|
}
|
||||||
|
return strings.Join(nodeStrings, ", ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *ScalarLiteral) String() string {
|
||||||
|
return fmt.Sprint(node.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *ScalarFunctionCall) String() string {
|
||||||
|
return fmt.Sprintf("%s(%s)", node.function.name, node.args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *ScalarArithExpr) String() string {
|
||||||
|
return fmt.Sprintf("(%s %s %s)", node.lhs, node.opType, node.rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *VectorLiteral) String() string {
|
||||||
|
metricName, ok := node.labels[model.MetricNameLabel]
|
||||||
|
if !ok {
|
||||||
|
panic("Tried to print vector without metric name")
|
||||||
|
}
|
||||||
|
labelStrings := make([]string, 0, len(node.labels)-1)
|
||||||
|
for label, value := range node.labels {
|
||||||
|
if label != model.MetricNameLabel {
|
||||||
|
labelStrings = append(labelStrings, fmt.Sprintf("%s='%s'", label, value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(labelStrings)
|
||||||
|
return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ","))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *VectorFunctionCall) String() string {
|
||||||
|
return fmt.Sprintf("%s(%s)", node.function.name, node.args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *VectorAggregation) String() string {
|
||||||
|
return fmt.Sprintf("%s(%s) BY (%s)", node.aggrType, node.vector, node.groupBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *VectorArithExpr) String() string {
|
||||||
|
return fmt.Sprintf("(%s %s %s)", node.lhs, node.opType, node.rhs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *MatrixLiteral) String() string {
|
||||||
|
vectorString := (&VectorLiteral{labels: node.labels}).String()
|
||||||
|
intervalString := fmt.Sprintf("[%s]", utility.DurationToString(node.interval))
|
||||||
|
return vectorString + intervalString
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *StringLiteral) String() string {
|
||||||
|
return fmt.Sprintf("'%s'", node.str)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *StringFunctionCall) String() string {
|
||||||
|
return fmt.Sprintf("%s(%s)", node.function.name, node.args)
|
||||||
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ func NewFunctionCall(name string, args []ast.Node) (ast.Node, error) {
|
||||||
return functionCall, nil
|
return functionCall, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewVectorAggregation(aggrTypeStr string, vector ast.Node, groupBy []model.LabelName) (*ast.VectorAggregation, error) {
|
func NewVectorAggregation(aggrTypeStr string, vector ast.Node, groupBy model.LabelNames) (*ast.VectorAggregation, error) {
|
||||||
if _, ok := vector.(ast.VectorNode); !ok {
|
if _, ok := vector.(ast.VectorNode); !ok {
|
||||||
return nil, fmt.Errorf("Operand of %v aggregation must be of vector type", aggrTypeStr)
|
return nil, fmt.Errorf("Operand of %v aggregation must be of vector type", aggrTypeStr)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
%{
|
%{
|
||||||
package rules
|
package rules
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
import "github.com/prometheus/prometheus/model"
|
import "github.com/prometheus/prometheus/model"
|
||||||
import "github.com/prometheus/prometheus/rules/ast"
|
import "github.com/prometheus/prometheus/rules/ast"
|
||||||
%}
|
%}
|
||||||
|
@ -25,7 +24,7 @@
|
||||||
ruleNode ast.Node
|
ruleNode ast.Node
|
||||||
ruleNodeSlice []ast.Node
|
ruleNodeSlice []ast.Node
|
||||||
boolean bool
|
boolean bool
|
||||||
labelNameSlice []model.LabelName
|
labelNameSlice model.LabelNames
|
||||||
labelSet model.LabelSet
|
labelSet model.LabelSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,13 +163,13 @@ rule_expr : '(' rule_expr ')'
|
||||||
;
|
;
|
||||||
|
|
||||||
grouping_opts :
|
grouping_opts :
|
||||||
{ $$ = []model.LabelName{} }
|
{ $$ = model.LabelNames{} }
|
||||||
| GROUP_OP '(' label_list ')'
|
| GROUP_OP '(' label_list ')'
|
||||||
{ $$ = $3 }
|
{ $$ = $3 }
|
||||||
;
|
;
|
||||||
|
|
||||||
label_list : IDENTIFIER
|
label_list : IDENTIFIER
|
||||||
{ $$ = []model.LabelName{model.LabelName($1)} }
|
{ $$ = model.LabelNames{model.LabelName($1)} }
|
||||||
| label_list ',' IDENTIFIER
|
| label_list ',' IDENTIFIER
|
||||||
{ $$ = append($$, model.LabelName($3)) }
|
{ $$ = append($$, model.LabelName($3)) }
|
||||||
;
|
;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
|
|
||||||
//line parser.y:15
|
//line parser.y:15
|
||||||
package rules
|
package rules
|
||||||
|
import __yyfmt__ "fmt"
|
||||||
import "fmt"
|
//line parser.y:15
|
||||||
|
|
||||||
import "github.com/prometheus/prometheus/model"
|
import "github.com/prometheus/prometheus/model"
|
||||||
import "github.com/prometheus/prometheus/rules/ast"
|
import "github.com/prometheus/prometheus/rules/ast"
|
||||||
|
|
||||||
//line parser.y:22
|
//line parser.y:21
|
||||||
type yySymType struct {
|
type yySymType struct {
|
||||||
yys int
|
yys int
|
||||||
num model.SampleValue
|
num model.SampleValue
|
||||||
|
@ -14,7 +15,7 @@ type yySymType struct {
|
||||||
ruleNode ast.Node
|
ruleNode ast.Node
|
||||||
ruleNodeSlice []ast.Node
|
ruleNodeSlice []ast.Node
|
||||||
boolean bool
|
boolean bool
|
||||||
labelNameSlice []model.LabelName
|
labelNameSlice model.LabelNames
|
||||||
labelSet model.LabelSet
|
labelSet model.LabelSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ const yyEofCode = 1
|
||||||
const yyErrCode = 2
|
const yyErrCode = 2
|
||||||
const yyMaxDepth = 200
|
const yyMaxDepth = 200
|
||||||
|
|
||||||
//line parser.y:189
|
//line parser.y:188
|
||||||
|
|
||||||
|
|
||||||
//line yacctab:1
|
//line yacctab:1
|
||||||
|
@ -182,12 +183,13 @@ type yyLexer interface {
|
||||||
const yyFlag = -1000
|
const yyFlag = -1000
|
||||||
|
|
||||||
func yyTokname(c int) string {
|
func yyTokname(c int) string {
|
||||||
if c > 0 && c <= len(yyToknames) {
|
// 4 is TOKSTART above
|
||||||
if yyToknames[c-1] != "" {
|
if c >= 4 && c-4 < len(yyToknames) {
|
||||||
return yyToknames[c-1]
|
if yyToknames[c-4] != "" {
|
||||||
|
return yyToknames[c-4]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("tok-%v", c)
|
return __yyfmt__.Sprintf("tok-%v", c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func yyStatname(s int) string {
|
func yyStatname(s int) string {
|
||||||
|
@ -196,7 +198,7 @@ func yyStatname(s int) string {
|
||||||
return yyStatenames[s]
|
return yyStatenames[s]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("state-%v", s)
|
return __yyfmt__.Sprintf("state-%v", s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func yylex1(lex yyLexer, lval *yySymType) int {
|
func yylex1(lex yyLexer, lval *yySymType) int {
|
||||||
|
@ -229,7 +231,7 @@ out:
|
||||||
c = yyTok2[1] /* unknown char */
|
c = yyTok2[1] /* unknown char */
|
||||||
}
|
}
|
||||||
if yyDebug >= 3 {
|
if yyDebug >= 3 {
|
||||||
fmt.Printf("lex %U %s\n", uint(char), yyTokname(c))
|
__yyfmt__.Printf("lex %U %s\n", uint(char), yyTokname(c))
|
||||||
}
|
}
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
@ -256,7 +258,7 @@ ret1:
|
||||||
yystack:
|
yystack:
|
||||||
/* put a state and value onto the stack */
|
/* put a state and value onto the stack */
|
||||||
if yyDebug >= 4 {
|
if yyDebug >= 4 {
|
||||||
fmt.Printf("char %v in %v\n", yyTokname(yychar), yyStatname(yystate))
|
__yyfmt__.Printf("char %v in %v\n", yyTokname(yychar), yyStatname(yystate))
|
||||||
}
|
}
|
||||||
|
|
||||||
yyp++
|
yyp++
|
||||||
|
@ -325,8 +327,8 @@ yydefault:
|
||||||
yylex.Error("syntax error")
|
yylex.Error("syntax error")
|
||||||
Nerrs++
|
Nerrs++
|
||||||
if yyDebug >= 1 {
|
if yyDebug >= 1 {
|
||||||
fmt.Printf("%s", yyStatname(yystate))
|
__yyfmt__.Printf("%s", yyStatname(yystate))
|
||||||
fmt.Printf("saw %s\n", yyTokname(yychar))
|
__yyfmt__.Printf("saw %s\n", yyTokname(yychar))
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
|
|
||||||
|
@ -345,7 +347,7 @@ yydefault:
|
||||||
|
|
||||||
/* the current p has no shift on "error", pop stack */
|
/* the current p has no shift on "error", pop stack */
|
||||||
if yyDebug >= 2 {
|
if yyDebug >= 2 {
|
||||||
fmt.Printf("error recovery pops state %d\n", yyS[yyp].yys)
|
__yyfmt__.Printf("error recovery pops state %d\n", yyS[yyp].yys)
|
||||||
}
|
}
|
||||||
yyp--
|
yyp--
|
||||||
}
|
}
|
||||||
|
@ -354,7 +356,7 @@ yydefault:
|
||||||
|
|
||||||
case 3: /* no shift yet; clobber input char */
|
case 3: /* no shift yet; clobber input char */
|
||||||
if yyDebug >= 2 {
|
if yyDebug >= 2 {
|
||||||
fmt.Printf("error recovery discards %s\n", yyTokname(yychar))
|
__yyfmt__.Printf("error recovery discards %s\n", yyTokname(yychar))
|
||||||
}
|
}
|
||||||
if yychar == yyEofCode {
|
if yychar == yyEofCode {
|
||||||
goto ret1
|
goto ret1
|
||||||
|
@ -366,7 +368,7 @@ yydefault:
|
||||||
|
|
||||||
/* reduction by production yyn */
|
/* reduction by production yyn */
|
||||||
if yyDebug >= 2 {
|
if yyDebug >= 2 {
|
||||||
fmt.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate))
|
__yyfmt__.Printf("reduce %v in:\n\t%v\n", yyn, yyStatname(yystate))
|
||||||
}
|
}
|
||||||
|
|
||||||
yynt := yyn
|
yynt := yyn
|
||||||
|
@ -393,133 +395,133 @@ yydefault:
|
||||||
switch yynt {
|
switch yynt {
|
||||||
|
|
||||||
case 5:
|
case 5:
|
||||||
//line parser.y:67
|
//line parser.y:66
|
||||||
{ yylex.(*RulesLexer).parsedExpr = yyS[yypt-0].ruleNode }
|
{ yylex.(*RulesLexer).parsedExpr = yyS[yypt-0].ruleNode }
|
||||||
case 6:
|
case 6:
|
||||||
//line parser.y:71
|
//line parser.y:70
|
||||||
{
|
{
|
||||||
rule, err := CreateRecordingRule(yyS[yypt-3].str, yyS[yypt-2].labelSet, yyS[yypt-0].ruleNode, yyS[yypt-4].boolean)
|
rule, err := CreateRecordingRule(yyS[yypt-3].str, yyS[yypt-2].labelSet, yyS[yypt-0].ruleNode, yyS[yypt-4].boolean)
|
||||||
if err != nil { yylex.Error(err.Error()); return 1 }
|
if err != nil { yylex.Error(err.Error()); return 1 }
|
||||||
yylex.(*RulesLexer).parsedRules = append(yylex.(*RulesLexer).parsedRules, rule)
|
yylex.(*RulesLexer).parsedRules = append(yylex.(*RulesLexer).parsedRules, rule)
|
||||||
}
|
}
|
||||||
case 7:
|
case 7:
|
||||||
//line parser.y:77
|
//line parser.y:76
|
||||||
{
|
{
|
||||||
rule, err := CreateAlertingRule(yyS[yypt-5].str, yyS[yypt-3].ruleNode, yyS[yypt-2].str, yyS[yypt-0].labelSet)
|
rule, err := CreateAlertingRule(yyS[yypt-5].str, yyS[yypt-3].ruleNode, yyS[yypt-2].str, yyS[yypt-0].labelSet)
|
||||||
if err != nil { yylex.Error(err.Error()); return 1 }
|
if err != nil { yylex.Error(err.Error()); return 1 }
|
||||||
yylex.(*RulesLexer).parsedRules = append(yylex.(*RulesLexer).parsedRules, rule)
|
yylex.(*RulesLexer).parsedRules = append(yylex.(*RulesLexer).parsedRules, rule)
|
||||||
}
|
}
|
||||||
case 8:
|
case 8:
|
||||||
//line parser.y:85
|
//line parser.y:84
|
||||||
{ yyVAL.str = "0s" }
|
{ yyVAL.str = "0s" }
|
||||||
case 9:
|
case 9:
|
||||||
//line parser.y:87
|
//line parser.y:86
|
||||||
{ yyVAL.str = yyS[yypt-0].str }
|
{ yyVAL.str = yyS[yypt-0].str }
|
||||||
case 10:
|
case 10:
|
||||||
//line parser.y:91
|
//line parser.y:90
|
||||||
{ yyVAL.boolean = false }
|
{ yyVAL.boolean = false }
|
||||||
case 11:
|
case 11:
|
||||||
//line parser.y:93
|
//line parser.y:92
|
||||||
{ yyVAL.boolean = true }
|
{ yyVAL.boolean = true }
|
||||||
case 12:
|
case 12:
|
||||||
//line parser.y:97
|
//line parser.y:96
|
||||||
{ yyVAL.labelSet = model.LabelSet{} }
|
{ yyVAL.labelSet = model.LabelSet{} }
|
||||||
case 13:
|
case 13:
|
||||||
//line parser.y:99
|
//line parser.y:98
|
||||||
{ yyVAL.labelSet = yyS[yypt-1].labelSet }
|
{ yyVAL.labelSet = yyS[yypt-1].labelSet }
|
||||||
case 14:
|
case 14:
|
||||||
//line parser.y:101
|
//line parser.y:100
|
||||||
{ yyVAL.labelSet = model.LabelSet{} }
|
{ yyVAL.labelSet = model.LabelSet{} }
|
||||||
case 15:
|
case 15:
|
||||||
//line parser.y:104
|
//line parser.y:103
|
||||||
{ yyVAL.labelSet = yyS[yypt-0].labelSet }
|
{ yyVAL.labelSet = yyS[yypt-0].labelSet }
|
||||||
case 16:
|
case 16:
|
||||||
//line parser.y:106
|
//line parser.y:105
|
||||||
{ for k, v := range yyS[yypt-0].labelSet { yyVAL.labelSet[k] = v } }
|
{ for k, v := range yyS[yypt-0].labelSet { yyVAL.labelSet[k] = v } }
|
||||||
case 17:
|
case 17:
|
||||||
//line parser.y:110
|
//line parser.y:109
|
||||||
{ yyVAL.labelSet = model.LabelSet{ model.LabelName(yyS[yypt-2].str): model.LabelValue(yyS[yypt-0].str) } }
|
{ yyVAL.labelSet = model.LabelSet{ model.LabelName(yyS[yypt-2].str): model.LabelValue(yyS[yypt-0].str) } }
|
||||||
case 18:
|
case 18:
|
||||||
//line parser.y:115
|
//line parser.y:114
|
||||||
{ yyVAL.ruleNode = yyS[yypt-1].ruleNode }
|
{ yyVAL.ruleNode = yyS[yypt-1].ruleNode }
|
||||||
case 19:
|
case 19:
|
||||||
//line parser.y:117
|
//line parser.y:116
|
||||||
{ yyS[yypt-0].labelSet[model.MetricNameLabel] = model.LabelValue(yyS[yypt-1].str); yyVAL.ruleNode = ast.NewVectorLiteral(yyS[yypt-0].labelSet) }
|
{ yyS[yypt-0].labelSet[model.MetricNameLabel] = model.LabelValue(yyS[yypt-1].str); yyVAL.ruleNode = ast.NewVectorLiteral(yyS[yypt-0].labelSet) }
|
||||||
case 20:
|
case 20:
|
||||||
//line parser.y:119
|
//line parser.y:118
|
||||||
{
|
{
|
||||||
var err error
|
var err error
|
||||||
yyVAL.ruleNode, err = NewFunctionCall(yyS[yypt-3].str, yyS[yypt-1].ruleNodeSlice)
|
yyVAL.ruleNode, err = NewFunctionCall(yyS[yypt-3].str, yyS[yypt-1].ruleNodeSlice)
|
||||||
if err != nil { yylex.Error(err.Error()); return 1 }
|
if err != nil { yylex.Error(err.Error()); return 1 }
|
||||||
}
|
}
|
||||||
case 21:
|
case 21:
|
||||||
//line parser.y:125
|
//line parser.y:124
|
||||||
{
|
{
|
||||||
var err error
|
var err error
|
||||||
yyVAL.ruleNode, err = NewFunctionCall(yyS[yypt-2].str, []ast.Node{})
|
yyVAL.ruleNode, err = NewFunctionCall(yyS[yypt-2].str, []ast.Node{})
|
||||||
if err != nil { yylex.Error(err.Error()); return 1 }
|
if err != nil { yylex.Error(err.Error()); return 1 }
|
||||||
}
|
}
|
||||||
case 22:
|
case 22:
|
||||||
//line parser.y:131
|
//line parser.y:130
|
||||||
{
|
{
|
||||||
var err error
|
var err error
|
||||||
yyVAL.ruleNode, err = NewMatrix(yyS[yypt-3].ruleNode, yyS[yypt-1].str)
|
yyVAL.ruleNode, err = NewMatrix(yyS[yypt-3].ruleNode, yyS[yypt-1].str)
|
||||||
if err != nil { yylex.Error(err.Error()); return 1 }
|
if err != nil { yylex.Error(err.Error()); return 1 }
|
||||||
}
|
}
|
||||||
case 23:
|
case 23:
|
||||||
//line parser.y:137
|
//line parser.y:136
|
||||||
{
|
{
|
||||||
var err error
|
var err error
|
||||||
yyVAL.ruleNode, err = NewVectorAggregation(yyS[yypt-4].str, yyS[yypt-2].ruleNode, yyS[yypt-0].labelNameSlice)
|
yyVAL.ruleNode, err = NewVectorAggregation(yyS[yypt-4].str, yyS[yypt-2].ruleNode, yyS[yypt-0].labelNameSlice)
|
||||||
if err != nil { yylex.Error(err.Error()); return 1 }
|
if err != nil { yylex.Error(err.Error()); return 1 }
|
||||||
}
|
}
|
||||||
case 24:
|
case 24:
|
||||||
//line parser.y:145
|
//line parser.y:144
|
||||||
{
|
{
|
||||||
var err error
|
var err error
|
||||||
yyVAL.ruleNode, err = NewArithExpr(yyS[yypt-1].str, yyS[yypt-2].ruleNode, yyS[yypt-0].ruleNode)
|
yyVAL.ruleNode, err = NewArithExpr(yyS[yypt-1].str, yyS[yypt-2].ruleNode, yyS[yypt-0].ruleNode)
|
||||||
if err != nil { yylex.Error(err.Error()); return 1 }
|
if err != nil { yylex.Error(err.Error()); return 1 }
|
||||||
}
|
}
|
||||||
case 25:
|
case 25:
|
||||||
//line parser.y:151
|
//line parser.y:150
|
||||||
{
|
{
|
||||||
var err error
|
var err error
|
||||||
yyVAL.ruleNode, err = NewArithExpr(yyS[yypt-1].str, yyS[yypt-2].ruleNode, yyS[yypt-0].ruleNode)
|
yyVAL.ruleNode, err = NewArithExpr(yyS[yypt-1].str, yyS[yypt-2].ruleNode, yyS[yypt-0].ruleNode)
|
||||||
if err != nil { yylex.Error(err.Error()); return 1 }
|
if err != nil { yylex.Error(err.Error()); return 1 }
|
||||||
}
|
}
|
||||||
case 26:
|
case 26:
|
||||||
//line parser.y:157
|
//line parser.y:156
|
||||||
{
|
{
|
||||||
var err error
|
var err error
|
||||||
yyVAL.ruleNode, err = NewArithExpr(yyS[yypt-1].str, yyS[yypt-2].ruleNode, yyS[yypt-0].ruleNode)
|
yyVAL.ruleNode, err = NewArithExpr(yyS[yypt-1].str, yyS[yypt-2].ruleNode, yyS[yypt-0].ruleNode)
|
||||||
if err != nil { yylex.Error(err.Error()); return 1 }
|
if err != nil { yylex.Error(err.Error()); return 1 }
|
||||||
}
|
}
|
||||||
case 27:
|
case 27:
|
||||||
//line parser.y:163
|
//line parser.y:162
|
||||||
{ yyVAL.ruleNode = ast.NewScalarLiteral(yyS[yypt-0].num)}
|
{ yyVAL.ruleNode = ast.NewScalarLiteral(yyS[yypt-0].num)}
|
||||||
case 28:
|
case 28:
|
||||||
//line parser.y:167
|
//line parser.y:166
|
||||||
{ yyVAL.labelNameSlice = []model.LabelName{} }
|
{ yyVAL.labelNameSlice = model.LabelNames{} }
|
||||||
case 29:
|
case 29:
|
||||||
//line parser.y:169
|
//line parser.y:168
|
||||||
{ yyVAL.labelNameSlice = yyS[yypt-1].labelNameSlice }
|
{ yyVAL.labelNameSlice = yyS[yypt-1].labelNameSlice }
|
||||||
case 30:
|
case 30:
|
||||||
//line parser.y:173
|
//line parser.y:172
|
||||||
{ yyVAL.labelNameSlice = []model.LabelName{model.LabelName(yyS[yypt-0].str)} }
|
{ yyVAL.labelNameSlice = model.LabelNames{model.LabelName(yyS[yypt-0].str)} }
|
||||||
case 31:
|
case 31:
|
||||||
//line parser.y:175
|
//line parser.y:174
|
||||||
{ yyVAL.labelNameSlice = append(yyVAL.labelNameSlice, model.LabelName(yyS[yypt-0].str)) }
|
{ yyVAL.labelNameSlice = append(yyVAL.labelNameSlice, model.LabelName(yyS[yypt-0].str)) }
|
||||||
case 32:
|
case 32:
|
||||||
//line parser.y:179
|
//line parser.y:178
|
||||||
{ yyVAL.ruleNodeSlice = []ast.Node{yyS[yypt-0].ruleNode} }
|
{ yyVAL.ruleNodeSlice = []ast.Node{yyS[yypt-0].ruleNode} }
|
||||||
case 33:
|
case 33:
|
||||||
//line parser.y:181
|
//line parser.y:180
|
||||||
{ yyVAL.ruleNodeSlice = append(yyVAL.ruleNodeSlice, yyS[yypt-0].ruleNode) }
|
{ yyVAL.ruleNodeSlice = append(yyVAL.ruleNodeSlice, yyS[yypt-0].ruleNode) }
|
||||||
case 34:
|
case 34:
|
||||||
//line parser.y:185
|
//line parser.y:184
|
||||||
{ yyVAL.ruleNode = yyS[yypt-0].ruleNode }
|
{ yyVAL.ruleNode = yyS[yypt-0].ruleNode }
|
||||||
case 35:
|
case 35:
|
||||||
//line parser.y:187
|
//line parser.y:186
|
||||||
{ yyVAL.ruleNode = ast.NewStringLiteral(yyS[yypt-0].str) }
|
{ yyVAL.ruleNode = ast.NewStringLiteral(yyS[yypt-0].str) }
|
||||||
}
|
}
|
||||||
goto yystack /* stack new state and value */
|
goto yystack /* stack new state and value */
|
||||||
|
|
|
@ -67,6 +67,10 @@ func (rule RecordingRule) ToDotGraph() string {
|
||||||
return graph
|
return graph
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rule RecordingRule) String() string {
|
||||||
|
return fmt.Sprintf("%s%s = %s\n", rule.name, rule.labels, rule.vector)
|
||||||
|
}
|
||||||
|
|
||||||
// Construct a new RecordingRule.
|
// Construct a new RecordingRule.
|
||||||
func NewRecordingRule(name string, labels model.LabelSet, vector ast.VectorNode, permanent bool) *RecordingRule {
|
func NewRecordingRule(name string, labels model.LabelSet, vector ast.VectorNode, permanent bool) *RecordingRule {
|
||||||
return &RecordingRule{
|
return &RecordingRule{
|
||||||
|
|
|
@ -31,4 +31,6 @@ type Rule interface {
|
||||||
Eval(timestamp time.Time, storage *metric.TieredStorage) (ast.Vector, error)
|
Eval(timestamp time.Time, storage *metric.TieredStorage) (ast.Vector, error)
|
||||||
// ToDotGraph returns a Graphviz dot graph of the rule.
|
// ToDotGraph returns a Graphviz dot graph of the rule.
|
||||||
ToDotGraph() string
|
ToDotGraph() string
|
||||||
|
// String returns a human-readable string representation of the rule.
|
||||||
|
String() string
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue