Merge pull request #204 from prometheus/julius-dotgraph-templates

Cleanup and idiomaticize rule/expression dot graph output.
This commit is contained in:
juliusv 2013-04-29 05:16:54 -07:00
commit aaf15fe625
4 changed files with 50 additions and 35 deletions

View file

@ -14,6 +14,7 @@
package rules
import (
"fmt"
"github.com/prometheus/prometheus/model"
"github.com/prometheus/prometheus/rules/ast"
"github.com/prometheus/prometheus/utility"
@ -131,6 +132,15 @@ func (rule AlertingRule) Eval(timestamp time.Time) (vector ast.Vector, err error
return
}
func (rule AlertingRule) ToDotGraph() string {
graph := fmt.Sprintf(`digraph "Rules" {
%#p[shape="box",label="ALERT %s IF FOR %s"];
%#p -> %#p;
%s
}`, &rule, rule.name, utility.DurationToString(rule.holdDuration), &rule, rule.vector, rule.vector.NodeTreeToDotGraph())
return graph
}
// Construct a new AlertingRule.
func NewAlertingRule(name string, vector ast.VectorNode, holdDuration time.Duration, labels model.LabelSet) *AlertingRule {
return &AlertingRule{

View file

@ -30,7 +30,7 @@ const (
JSON
)
func binOpTypeToString(opType BinOpType) string {
func (opType BinOpType) String() string {
opTypeMap := map[BinOpType]string{
ADD: "+",
SUB: "-",
@ -47,7 +47,7 @@ func binOpTypeToString(opType BinOpType) string {
return opTypeMap[opType]
}
func aggrTypeToString(aggrType AggrType) string {
func (aggrType AggrType) String() string {
aggrTypeMap := map[AggrType]string{
SUM: "SUM",
AVG: "AVG",
@ -57,7 +57,7 @@ func aggrTypeToString(aggrType AggrType) string {
return aggrTypeMap[aggrType]
}
func exprTypeToString(exprType ExprType) string {
func (exprType ExprType) String() string {
exprTypeMap := map[ExprType]string{
SCALAR: "scalar",
VECTOR: "vector",
@ -78,12 +78,12 @@ func (vector Vector) String() string {
for label, value := range sample.Metric {
if label != model.MetricNameLabel {
// TODO escape special chars in label values here and elsewhere.
labelStrings = append(labelStrings, fmt.Sprintf("%v='%v'", label, value))
labelStrings = append(labelStrings, fmt.Sprintf("%s='%s'", label, value))
}
}
sort.Strings(labelStrings)
metricStrings = append(metricStrings,
fmt.Sprintf("%v{%v} => %v @[%v]",
fmt.Sprintf("%s{%s} => %v @[%v]",
metricName,
strings.Join(labelStrings, ","),
sample.Value, sample.Timestamp))
@ -101,7 +101,7 @@ func (matrix Matrix) String() string {
labelStrings := []string{}
for label, value := range sampleSet.Metric {
if label != model.MetricNameLabel {
labelStrings = append(labelStrings, fmt.Sprintf("%v='%v'", label, value))
labelStrings = append(labelStrings, fmt.Sprintf("%s='%s'", label, value))
}
}
sort.Strings(labelStrings)
@ -111,7 +111,7 @@ func (matrix Matrix) String() string {
fmt.Sprintf("\n%v @[%v]", value.Value, value.Timestamp))
}
metricStrings = append(metricStrings,
fmt.Sprintf("%v{%v} => %v",
fmt.Sprintf("%s{%s} => %s",
metricName,
strings.Join(labelStrings, ","),
strings.Join(valueStrings, ", ")))
@ -202,16 +202,16 @@ func (node *VectorLiteral) String() string {
labelStrings := []string{}
for label, value := range node.labels {
if label != model.MetricNameLabel {
labelStrings = append(labelStrings, fmt.Sprintf("%v='%v'", label, value))
labelStrings = append(labelStrings, fmt.Sprintf("%s='%s'", label, value))
}
}
sort.Strings(labelStrings)
return fmt.Sprintf("%v{%v}", metricName, strings.Join(labelStrings, ","))
return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ","))
}
func (node *MatrixLiteral) String() string {
vectorString := (&VectorLiteral{labels: node.labels}).String()
intervalString := fmt.Sprintf("['%v']", utility.DurationToString(node.interval))
intervalString := fmt.Sprintf("['%s']", utility.DurationToString(node.interval))
return vectorString + intervalString
}
@ -231,26 +231,28 @@ func functionArgsToDotGraph(node Node, args []Node) string {
}
func (node *ScalarFunctionCall) NodeTreeToDotGraph() string {
graph := fmt.Sprintf("%#p[label=\"%v\"];\n", node, node.function.name)
graph := fmt.Sprintf("%#p[label=\"%s\"];\n", node, node.function.name)
graph += functionArgsToDotGraph(node, node.args)
return graph
}
func (node *ScalarArithExpr) NodeTreeToDotGraph() string {
graph := fmt.Sprintf("%#p[label=\"%v\"];\n", node, binOpTypeToString(node.opType))
graph += fmt.Sprintf("%#p -> %#p;\n", node, node.lhs)
graph += fmt.Sprintf("%#p -> %#p;\n", node, node.rhs)
graph += node.lhs.NodeTreeToDotGraph()
graph += node.rhs.NodeTreeToDotGraph()
graph := fmt.Sprintf(`
%#p[label="%s"];
%#p -> %#p;
%#p -> %#p;
%s
%s
}`, node, node.opType, node, node.lhs, node, node.rhs, node.lhs.NodeTreeToDotGraph(), node.rhs.NodeTreeToDotGraph())
return graph
}
func (node *VectorLiteral) NodeTreeToDotGraph() string {
return fmt.Sprintf("%#p[label=\"%v\"];\n", node, node.String())
return fmt.Sprintf("%#p[label=\"%s\"];\n", node, node)
}
func (node *VectorFunctionCall) NodeTreeToDotGraph() string {
graph := fmt.Sprintf("%#p[label=\"%v\"];\n", node, node.function.name)
graph := fmt.Sprintf("%#p[label=\"%s\"];\n", node, node.function.name)
graph += functionArgsToDotGraph(node, node.args)
return graph
}
@ -261,9 +263,9 @@ func (node *VectorAggregation) NodeTreeToDotGraph() string {
groupByStrings = append(groupByStrings, string(label))
}
graph := fmt.Sprintf("%#p[label=\"%v BY (%v)\"]\n",
graph := fmt.Sprintf("%#p[label=\"%s BY (%s)\"]\n",
node,
aggrTypeToString(node.aggrType),
node.aggrType,
strings.Join(groupByStrings, ", "))
graph += fmt.Sprintf("%#p -> %#p;\n", node, node.vector)
graph += node.vector.NodeTreeToDotGraph()
@ -271,24 +273,26 @@ func (node *VectorAggregation) NodeTreeToDotGraph() string {
}
func (node *VectorArithExpr) NodeTreeToDotGraph() string {
graph := fmt.Sprintf("%#p[label=\"%v\"];\n", node, binOpTypeToString(node.opType))
graph += fmt.Sprintf("%#p -> %#p;\n", node, node.lhs)
graph += fmt.Sprintf("%#p -> %#p;\n", node, node.rhs)
graph += node.lhs.NodeTreeToDotGraph()
graph += node.rhs.NodeTreeToDotGraph()
graph := fmt.Sprintf(`
%#p[label="%s"];
%#p -> %#p;
%#p -> %#p;
%s
%s
`, node, node.opType, node, node.lhs, node, node.rhs, node.lhs.NodeTreeToDotGraph(), node.rhs.NodeTreeToDotGraph())
return graph
}
func (node *MatrixLiteral) NodeTreeToDotGraph() string {
return fmt.Sprintf("%#p[label=\"%v\"];\n", node, node.String())
return fmt.Sprintf("%#p[label=\"%s\"];\n", node, node)
}
func (node *StringLiteral) NodeTreeToDotGraph() string {
return fmt.Sprintf("%#p[label=\"'%v'\"];\n", node, node.str)
return fmt.Sprintf("%#p[label=\"'%s'\"];\n", node, node.str)
}
func (node *StringFunctionCall) NodeTreeToDotGraph() string {
graph := fmt.Sprintf("%#p[label=\"%v\"];\n", node, node.function.name)
graph := fmt.Sprintf("%#p[label=\"%s\"];\n", node, node.function.name)
graph += functionArgsToDotGraph(node, node.args)
return graph
}

View file

@ -55,13 +55,12 @@ func (rule RecordingRule) Eval(timestamp time.Time) (vector ast.Vector, err erro
return
}
// RuleToDotGraph returns a Graphviz dot graph of the recording rule.
func (rule RecordingRule) RuleToDotGraph() string {
graph := "digraph \"Rules\" {\n"
graph += fmt.Sprintf("%#p[shape=\"box\",label=\"%v = \"];\n", rule, rule.name)
graph += fmt.Sprintf("%#p -> %#p;\n", &rule, rule.vector)
graph += rule.vector.NodeTreeToDotGraph()
graph += "}\n"
func (rule RecordingRule) ToDotGraph() string {
graph := fmt.Sprintf(`digraph "Rules" {
%#p[shape="box",label="%s = "];
%#p -> %#p;
%s
}`, &rule, rule.name, &rule, rule.vector, rule.vector.NodeTreeToDotGraph())
return graph
}

View file

@ -28,4 +28,6 @@ type Rule interface {
EvalRaw(timestamp time.Time) (vector ast.Vector, err error)
// Eval evaluates the rule, including any associated recording or alerting actions.
Eval(timestamp time.Time) (vector ast.Vector, err error)
// ToDotGraph returns a Graphviz dot graph of the rule.
ToDotGraph() string
}