mirror of
https://github.com/prometheus/prometheus.git
synced 2025-08-05 21:57:09 +02:00
Add parse alerting for rules files (#16601)
Builds over https://github.com/prometheus/prometheus/pull/16462 Addresses comments, adds invalid rules file Signed-off-by: subhramit <subhramit.bb@live.in> Co-authored-by: marcodebba <marcodebonis74@gmail.com>
This commit is contained in:
parent
2834a665ed
commit
44e27a876e
@ -648,6 +648,17 @@ func main() {
|
||||
logger.Error(fmt.Sprintf("Error loading dynamic scrape config files from config (--config.file=%q)", cfg.configFile), "file", absPath, "err", err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
// Parse rule files to verify they exist and contain valid rules.
|
||||
if err := rules.ParseFiles(cfgFile.RuleFiles); err != nil {
|
||||
absPath, pathErr := filepath.Abs(cfg.configFile)
|
||||
if pathErr != nil {
|
||||
absPath = cfg.configFile
|
||||
}
|
||||
logger.Error(fmt.Sprintf("Error loading rule file patterns from config (--config.file=%q)", cfg.configFile), "file", absPath, "err", err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
if cfg.tsdb.EnableExemplarStorage {
|
||||
if cfgFile.StorageConfig.ExemplarsConfig == nil {
|
||||
cfgFile.StorageConfig.ExemplarsConfig = &config.DefaultExemplarsConfig
|
||||
|
6
rules/fixtures/invalid_rules.yaml
Normal file
6
rules/fixtures/invalid_rules.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
groups:
|
||||
- name: invalid
|
||||
rules:
|
||||
- record: job:http_requests:rate5m
|
||||
expr: sum by (job)(rate(http_requests_total[5m]))
|
||||
unexpected_field: this_field_should_not_be_here
|
@ -19,6 +19,7 @@ import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -579,3 +580,32 @@ func FromMaps(maps ...map[string]string) labels.Labels {
|
||||
|
||||
return labels.FromMap(mLables)
|
||||
}
|
||||
|
||||
// ParseFiles parses the rule files corresponding to glob patterns.
|
||||
func ParseFiles(patterns []string) error {
|
||||
files := map[string]string{}
|
||||
for _, pat := range patterns {
|
||||
fns, err := filepath.Glob(pat)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed retrieving rule files for %q: %w", pat, err)
|
||||
}
|
||||
for _, fn := range fns {
|
||||
absPath, err := filepath.Abs(fn)
|
||||
if err != nil {
|
||||
absPath = fn
|
||||
}
|
||||
cleanPath, err := filepath.EvalSymlinks(absPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed evaluating rule file path %q (pattern: %q): %w", absPath, pat, err)
|
||||
}
|
||||
files[cleanPath] = pat
|
||||
}
|
||||
}
|
||||
for fn, pat := range files {
|
||||
_, errs := rulefmt.ParseFile(fn, false)
|
||||
if len(errs) > 0 {
|
||||
return fmt.Errorf("parse rules from file %q (pattern: %q): %w", fn, pat, errors.Join(errs...))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"math"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
@ -2549,6 +2550,17 @@ func TestLabels_FromMaps(t *testing.T) {
|
||||
require.Equal(t, expected, mLabels, "unexpected labelset")
|
||||
}
|
||||
|
||||
func TestParseFiles(t *testing.T) {
|
||||
t.Run("good files", func(t *testing.T) {
|
||||
err := ParseFiles([]string{filepath.Join("fixtures", "rules.y*ml")})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("bad files", func(t *testing.T) {
|
||||
err := ParseFiles([]string{filepath.Join("fixtures", "invalid_rules.y*ml")})
|
||||
require.ErrorContains(t, err, "field unexpected_field not found in type rulefmt.Rule")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRuleDependencyController_AnalyseRules(t *testing.T) {
|
||||
type expectedDependencies struct {
|
||||
noDependentRules bool
|
||||
|
Loading…
Reference in New Issue
Block a user