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

Cleanup and idiomaticize rule/expression dot graph output.
pull/198/merge
juliusv 12 years ago
commit aaf15fe625

@ -14,6 +14,7 @@
package rules package rules
import ( import (
"fmt"
"github.com/prometheus/prometheus/model" "github.com/prometheus/prometheus/model"
"github.com/prometheus/prometheus/rules/ast" "github.com/prometheus/prometheus/rules/ast"
"github.com/prometheus/prometheus/utility" "github.com/prometheus/prometheus/utility"
@ -131,6 +132,15 @@ func (rule AlertingRule) Eval(timestamp time.Time) (vector ast.Vector, err error
return 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. // 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{

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

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

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

Loading…
Cancel
Save