Add update-rules command to promtool

Signed-off-by: Goutham Veeramachaneni <cs14btech11014@iith.ac.in>
This commit is contained in:
Goutham Veeramachaneni 2017-06-14 11:13:00 +05:30
parent e8f55669ea
commit cea1e99f78
No known key found for this signature in database
GPG key ID: F1C217E8E9023CAD
3 changed files with 96 additions and 7 deletions

View file

@ -20,8 +20,12 @@ import (
"path/filepath" "path/filepath"
"strings" "strings"
yaml "github.com/ghodss/yaml"
"github.com/prometheus/common/model"
"github.com/prometheus/common/version" "github.com/prometheus/common/version"
"github.com/prometheus/prometheus/config" "github.com/prometheus/prometheus/config"
"github.com/prometheus/prometheus/pkg/rulefmt"
"github.com/prometheus/prometheus/promql" "github.com/prometheus/prometheus/promql"
"github.com/prometheus/prometheus/util/cli" "github.com/prometheus/prometheus/util/cli"
"github.com/prometheus/prometheus/util/promlint" "github.com/prometheus/prometheus/util/promlint"
@ -183,6 +187,85 @@ func checkRules(t cli.Term, filename string) (int, error) {
return len(rules), nil return len(rules), nil
} }
// UpdateRulesCmd updates the rule files.
func UpdateRulesCmd(t cli.Term, args ...string) int {
if len(args) == 0 {
t.Infof("usage: promtool update-rules <files>")
return 2
}
failed := false
for _, arg := range args {
if err := updateRules(t, arg); err != nil {
t.Errorf(" FAILED: %s", err)
failed = true
}
}
if failed {
return 1
}
return 0
}
func updateRules(t cli.Term, filename string) error {
t.Infof("Updating %s", filename)
if stat, err := os.Stat(filename); err != nil {
return fmt.Errorf("cannot get file info")
} else if stat.IsDir() {
return fmt.Errorf("is a directory")
}
content, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
rules, err := promql.ParseStmts(string(content))
if err != nil {
return err
}
yamlRG := &rulefmt.RuleGroups{
Version: 1,
Groups: []rulefmt.RuleGroup{{
Name: filename,
}},
}
yamlRules := make([]rulefmt.Rule, 0, len(rules))
for _, rule := range rules {
switch r := rule.(type) {
case *promql.AlertStmt:
yamlRules = append(yamlRules, rulefmt.Rule{
Alert: r.Name,
Expr: r.Expr.String(),
For: model.Duration(r.Duration).String(),
Labels: r.Labels.Map(),
Annotations: r.Annotations.Map(),
})
case *promql.RecordStmt:
yamlRules = append(yamlRules, rulefmt.Rule{
Record: r.Name,
Expr: r.Expr.String(),
Labels: r.Labels.Map(),
})
default:
panic("unknown statement type")
}
}
yamlRG.Groups[0].Rules = yamlRules
y, err := yaml.Marshal(yamlRG)
if err != nil {
return err
}
return ioutil.WriteFile(filename+".yaml", y, 0777)
}
var checkMetricsUsage = strings.TrimSpace(` var checkMetricsUsage = strings.TrimSpace(`
usage: promtool check-metrics usage: promtool check-metrics
@ -243,6 +326,11 @@ func main() {
Run: CheckMetricsCmd, Run: CheckMetricsCmd,
}) })
app.Register("update-rules", &cli.Command{
Desc: "update the rules to the new YAML format",
Run: UpdateRulesCmd,
})
app.Register("version", &cli.Command{ app.Register("version", &cli.Command{
Desc: "print the version of this binary", Desc: "print the version of this binary",
Run: VersionCmd, Run: VersionCmd,

View file

@ -47,18 +47,18 @@ func (g *RuleGroups) Validate() (errs []error) {
// RuleGroup is a list of sequentially evaluated recording and alerting rules. // RuleGroup is a list of sequentially evaluated recording and alerting rules.
type RuleGroup struct { type RuleGroup struct {
Name string `json:"name"` Name string `json:"name"`
Interval string `json:"interval"` Interval string `json:"interval,omitempty"`
Rules []Rule `json:"rules"` Rules []Rule `json:"rules"`
} }
// Rule describes an alerting or recording rule. // Rule describes an alerting or recording rule.
type Rule struct { type Rule struct {
Record string `json:"record"` Record string `json:"record,omitempty"`
Alert string `json:"alert"` Alert string `json:"alert,omitempty"`
Expr string `json:"expr"` Expr string `json:"expr"`
For string `json:"for"` For string `json:"for,omitempty"`
Labels map[string]string `json:"labels"` Labels map[string]string `json:"labels,omitempty"`
Annotations map[string]string `json:"annotations"` Annotations map[string]string `json:"annotations,omitempty"`
} }
// Validate the rule and return a list of encountered errors. // Validate the rule and return a list of encountered errors.

View file

@ -390,6 +390,7 @@ type Manager struct {
block chan struct{} block chan struct{}
} }
// Appendable returns an Appender.
type Appendable interface { type Appendable interface {
Appender() (storage.Appender, error) Appender() (storage.Appender, error)
} }
@ -517,7 +518,7 @@ func (m *Manager) loadGroups(interval time.Duration, filenames ...string) (map[s
itv = time.Duration(dur) itv = time.Duration(dur)
} }
rules := make([]Rule, len(rg.Rules), 0) rules := make([]Rule, 0, len(rg.Rules))
for _, r := range rg.Rules { for _, r := range rg.Rules {
expr, err := promql.ParseExpr(r.Expr) expr, err := promql.ParseExpr(r.Expr)
if err != nil { if err != nil {