github.com/muhammadn/cortex@v1.9.1-0.20220510110439-46bb7000d03d/pkg/configs/legacy_promql/printer.go (about)

     1  // Copyright 2015 The Prometheus Authors
     2  // Licensed under the Apache License, Version 2.0 (the "License");
     3  // you may not use this file except in compliance with the License.
     4  // You may obtain a copy of the License at
     5  //
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package promql
    15  
    16  import (
    17  	"fmt"
    18  	"sort"
    19  	"strings"
    20  	"time"
    21  
    22  	"github.com/prometheus/common/model"
    23  	"github.com/prometheus/prometheus/pkg/labels"
    24  )
    25  
    26  // Tree returns a string of the tree structure of the given node.
    27  func Tree(node Node) string {
    28  	return tree(node, "")
    29  }
    30  
    31  func tree(node Node, level string) string {
    32  	if node == nil {
    33  		return fmt.Sprintf("%s |---- %T\n", level, node)
    34  	}
    35  	typs := strings.Split(fmt.Sprintf("%T", node), ".")[1]
    36  
    37  	var t string
    38  	// Only print the number of statements for readability.
    39  	if stmts, ok := node.(Statements); ok {
    40  		t = fmt.Sprintf("%s |---- %s :: %d\n", level, typs, len(stmts))
    41  	} else {
    42  		t = fmt.Sprintf("%s |---- %s :: %s\n", level, typs, node)
    43  	}
    44  
    45  	level += " · · ·"
    46  
    47  	switch n := node.(type) {
    48  	case Statements:
    49  		for _, s := range n {
    50  			t += tree(s, level)
    51  		}
    52  	case *AlertStmt:
    53  		t += tree(n.Expr, level)
    54  
    55  	case *EvalStmt:
    56  		t += tree(n.Expr, level)
    57  
    58  	case *RecordStmt:
    59  		t += tree(n.Expr, level)
    60  
    61  	case Expressions:
    62  		for _, e := range n {
    63  			t += tree(e, level)
    64  		}
    65  	case *AggregateExpr:
    66  		t += tree(n.Expr, level)
    67  
    68  	case *BinaryExpr:
    69  		t += tree(n.LHS, level)
    70  		t += tree(n.RHS, level)
    71  
    72  	case *Call:
    73  		t += tree(n.Args, level)
    74  
    75  	case *ParenExpr:
    76  		t += tree(n.Expr, level)
    77  
    78  	case *UnaryExpr:
    79  		t += tree(n.Expr, level)
    80  
    81  	case *MatrixSelector, *NumberLiteral, *StringLiteral, *VectorSelector:
    82  		// nothing to do
    83  
    84  	default:
    85  		panic("promql.Tree: not all node types covered")
    86  	}
    87  	return t
    88  }
    89  
    90  func (stmts Statements) String() (s string) {
    91  	if len(stmts) == 0 {
    92  		return ""
    93  	}
    94  	for _, stmt := range stmts {
    95  		s += stmt.String()
    96  		s += "\n\n"
    97  	}
    98  	return s[:len(s)-2]
    99  }
   100  
   101  func (node *AlertStmt) String() string {
   102  	s := fmt.Sprintf("ALERT %s", node.Name)
   103  	s += fmt.Sprintf("\n\tIF %s", node.Expr)
   104  	if node.Duration > 0 {
   105  		s += fmt.Sprintf("\n\tFOR %s", model.Duration(node.Duration))
   106  	}
   107  	if len(node.Labels) > 0 {
   108  		s += fmt.Sprintf("\n\tLABELS %s", node.Labels)
   109  	}
   110  	if len(node.Annotations) > 0 {
   111  		s += fmt.Sprintf("\n\tANNOTATIONS %s", node.Annotations)
   112  	}
   113  	return s
   114  }
   115  
   116  func (node *EvalStmt) String() string {
   117  	return "EVAL " + node.Expr.String()
   118  }
   119  
   120  func (node *RecordStmt) String() string {
   121  	s := fmt.Sprintf("%s%s = %s", node.Name, node.Labels, node.Expr)
   122  	return s
   123  }
   124  
   125  func (es Expressions) String() (s string) {
   126  	if len(es) == 0 {
   127  		return ""
   128  	}
   129  	for _, e := range es {
   130  		s += e.String()
   131  		s += ", "
   132  	}
   133  	return s[:len(s)-2]
   134  }
   135  
   136  func (node *AggregateExpr) String() string {
   137  	aggrString := node.Op.String()
   138  
   139  	if node.Without {
   140  		aggrString += fmt.Sprintf(" without(%s) ", strings.Join(node.Grouping, ", "))
   141  	} else {
   142  		if len(node.Grouping) > 0 {
   143  			aggrString += fmt.Sprintf(" by(%s) ", strings.Join(node.Grouping, ", "))
   144  		}
   145  	}
   146  
   147  	aggrString += "("
   148  	if node.Op.isAggregatorWithParam() {
   149  		aggrString += fmt.Sprintf("%s, ", node.Param)
   150  	}
   151  	aggrString += fmt.Sprintf("%s)", node.Expr)
   152  
   153  	return aggrString
   154  }
   155  
   156  func (node *BinaryExpr) String() string {
   157  	returnBool := ""
   158  	if node.ReturnBool {
   159  		returnBool = " bool"
   160  	}
   161  
   162  	matching := ""
   163  	vm := node.VectorMatching
   164  	if vm != nil && (len(vm.MatchingLabels) > 0 || vm.On) {
   165  		if vm.On {
   166  			matching = fmt.Sprintf(" on(%s)", strings.Join(vm.MatchingLabels, ", "))
   167  		} else {
   168  			matching = fmt.Sprintf(" ignoring(%s)", strings.Join(vm.MatchingLabels, ", "))
   169  		}
   170  		if vm.Card == CardManyToOne || vm.Card == CardOneToMany {
   171  			matching += " group_"
   172  			if vm.Card == CardManyToOne {
   173  				matching += "left"
   174  			} else {
   175  				matching += "right"
   176  			}
   177  			matching += fmt.Sprintf("(%s)", strings.Join(vm.Include, ", "))
   178  		}
   179  	}
   180  	return fmt.Sprintf("%s %s%s%s %s", node.LHS, node.Op, returnBool, matching, node.RHS)
   181  }
   182  
   183  func (node *Call) String() string {
   184  	return fmt.Sprintf("%s(%s)", node.Func.Name, node.Args)
   185  }
   186  
   187  func (node *MatrixSelector) String() string {
   188  	vecSelector := &VectorSelector{
   189  		Name:          node.Name,
   190  		LabelMatchers: node.LabelMatchers,
   191  	}
   192  	offset := ""
   193  	if node.Offset != time.Duration(0) {
   194  		offset = fmt.Sprintf(" offset %s", model.Duration(node.Offset))
   195  	}
   196  	return fmt.Sprintf("%s[%s]%s", vecSelector.String(), model.Duration(node.Range), offset)
   197  }
   198  
   199  func (node *NumberLiteral) String() string {
   200  	return fmt.Sprint(node.Val)
   201  }
   202  
   203  func (node *ParenExpr) String() string {
   204  	return fmt.Sprintf("(%s)", node.Expr)
   205  }
   206  
   207  func (node *StringLiteral) String() string {
   208  	return fmt.Sprintf("%q", node.Val)
   209  }
   210  
   211  func (node *UnaryExpr) String() string {
   212  	return fmt.Sprintf("%s%s", node.Op, node.Expr)
   213  }
   214  
   215  func (node *VectorSelector) String() string {
   216  	labelStrings := make([]string, 0, len(node.LabelMatchers)-1)
   217  	for _, matcher := range node.LabelMatchers {
   218  		// Only include the __name__ label if its no equality matching.
   219  		if matcher.Name == labels.MetricName && matcher.Type == labels.MatchEqual {
   220  			continue
   221  		}
   222  		labelStrings = append(labelStrings, matcher.String())
   223  	}
   224  	offset := ""
   225  	if node.Offset != time.Duration(0) {
   226  		offset = fmt.Sprintf(" offset %s", model.Duration(node.Offset))
   227  	}
   228  
   229  	if len(labelStrings) == 0 {
   230  		return fmt.Sprintf("%s%s", node.Name, offset)
   231  	}
   232  	sort.Strings(labelStrings)
   233  	return fmt.Sprintf("%s{%s}%s", node.Name, strings.Join(labelStrings, ","), offset)
   234  }