diff --git a/cmd/promtool/main.go b/cmd/promtool/main.go index 84faf5d56..5be2734e6 100644 --- a/cmd/promtool/main.go +++ b/cmd/promtool/main.go @@ -163,8 +163,11 @@ func CheckConfig(files ...string) int { fmt.Println() for _, rf := range ruleFiles { - if n, err := checkRules(rf); err != nil { - fmt.Fprintln(os.Stderr, " FAILED:", err) + if n, errs := checkRules(rf); len(errs) > 0 { + fmt.Fprintln(os.Stderr, " FAILED:") + for _, err := range errs { + fmt.Fprintln(os.Stderr, " ", err) + } failed = true } else { fmt.Printf(" SUCCESS: %d rules found\n", n) diff --git a/pkg/rulefmt/rulefmt.go b/pkg/rulefmt/rulefmt.go index b89470d38..001d0476f 100644 --- a/pkg/rulefmt/rulefmt.go +++ b/pkg/rulefmt/rulefmt.go @@ -113,7 +113,7 @@ func (r *Rule) Validate() (errs []error) { if r.Expr == "" { errs = append(errs, errors.Errorf("field 'expr' must be set in rule")) } else if _, err := promql.ParseExpr(r.Expr); err != nil { - errs = append(errs, errors.Errorf("could not parse expression: %s", err)) + errs = append(errs, errors.Wrap(err, "could not parse expression")) } if r.Record != "" { if len(r.Annotations) > 0 { @@ -143,8 +143,7 @@ func (r *Rule) Validate() (errs []error) { } } - errs = append(errs, testTemplateParsing(r)...) - return errs + return append(errs, testTemplateParsing(r)...) } // testTemplateParsing checks if the templates used in labels and annotations @@ -176,18 +175,18 @@ func testTemplateParsing(rl *Rule) (errs []error) { } // Parsing Labels. - for _, val := range rl.Labels { + for k, val := range rl.Labels { err := parseTest(val) if err != nil { - errs = append(errs, errors.Errorf("msg=%s", err.Error())) + errs = append(errs, errors.Wrapf(err, "label %q", k)) } } // Parsing Annotations. - for _, val := range rl.Annotations { + for k, val := range rl.Annotations { err := parseTest(val) if err != nil { - errs = append(errs, errors.Errorf("msg=%s", err.Error())) + errs = append(errs, errors.Wrapf(err, "annotation %q", k)) } } @@ -207,7 +206,11 @@ func Parse(content []byte) (*RuleGroups, []error) { func ParseFile(file string) (*RuleGroups, []error) { b, err := ioutil.ReadFile(file) if err != nil { - return nil, []error{err} + return nil, []error{errors.Wrap(err, file)} + } + rgs, errs := Parse(b) + for i := range errs { + errs[i] = errors.Wrap(errs[i], file) } - return Parse(b) + return rgs, errs } diff --git a/rules/manager.go b/rules/manager.go index 563940d49..05ce3798e 100644 --- a/rules/manager.go +++ b/rules/manager.go @@ -15,18 +15,17 @@ package rules import ( "context" - "errors" + html_template "html/template" "math" "net/url" "sort" "sync" "time" - html_template "html/template" - "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" opentracing "github.com/opentracing/opentracing-go" + "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/common/model" @@ -898,7 +897,7 @@ func (m *Manager) LoadGroups( for _, r := range rg.Rules { expr, err := promql.ParseExpr(r.Expr) if err != nil { - return nil, []error{err} + return nil, []error{errors.Wrap(err, fn)} } if r.Alert != "" {