github.com/thanos-io/thanos@v0.32.5/cmd/thanos/tools.go (about)

     1  // Copyright (c) The Thanos Authors.
     2  // Licensed under the Apache License 2.0.
     3  
     4  package main
     5  
     6  import (
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/go-kit/log"
    11  	"github.com/go-kit/log/level"
    12  	"github.com/oklog/run"
    13  	"github.com/opentracing/opentracing-go"
    14  	"github.com/pkg/errors"
    15  	"github.com/prometheus/client_golang/prometheus"
    16  
    17  	"github.com/thanos-io/thanos/pkg/errutil"
    18  	"github.com/thanos-io/thanos/pkg/extkingpin"
    19  	"github.com/thanos-io/thanos/pkg/rules"
    20  )
    21  
    22  type checkRulesConfig struct {
    23  	rulesFiles []string
    24  }
    25  
    26  func registerTools(app *extkingpin.App) {
    27  	cmd := app.Command("tools", "Tools utility commands")
    28  
    29  	registerBucket(cmd)
    30  	registerCheckRules(cmd)
    31  }
    32  
    33  func (tc *checkRulesConfig) registerFlag(cmd extkingpin.FlagClause) *checkRulesConfig {
    34  	cmd.Flag("rules", "The rule files glob to check (repeated).").Required().StringsVar(&tc.rulesFiles)
    35  	return tc
    36  }
    37  
    38  func registerCheckRules(app extkingpin.AppClause) {
    39  	cmd := app.Command("rules-check", "Check if the rule files are valid or not.")
    40  	crc := &checkRulesConfig{}
    41  	crc.registerFlag(cmd)
    42  	cmd.Setup(func(g *run.Group, logger log.Logger, reg *prometheus.Registry, _ opentracing.Tracer, _ <-chan struct{}, _ bool) error {
    43  		// Dummy actor to immediately kill the group after the run function returns.
    44  		g.Add(func() error { return nil }, func(error) {})
    45  		return checkRulesFiles(logger, &crc.rulesFiles)
    46  	})
    47  }
    48  
    49  func checkRulesFiles(logger log.Logger, patterns *[]string) error {
    50  	var failed errutil.MultiError
    51  
    52  	for _, p := range *patterns {
    53  		level.Info(logger).Log("msg", "checking", "pattern", p)
    54  		matches, err := filepath.Glob(p)
    55  		if err != nil || matches == nil {
    56  			err = errors.New("matching file not found")
    57  			level.Error(logger).Log("result", "FAILED", "error", err)
    58  			level.Info(logger).Log()
    59  			failed.Add(err)
    60  			continue
    61  		}
    62  		for _, fn := range matches {
    63  			level.Info(logger).Log("msg", "checking", "filename", filepath.Clean(fn))
    64  			f, er := os.Open(fn)
    65  			if er != nil {
    66  				level.Error(logger).Log("result", "FAILED", "error", er)
    67  				level.Info(logger).Log()
    68  				failed.Add(err)
    69  				continue
    70  			}
    71  			defer func() { _ = f.Close() }()
    72  
    73  			n, errs := rules.ValidateAndCount(f)
    74  			if errs.Err() != nil {
    75  				level.Error(logger).Log("result", "FAILED")
    76  				for _, e := range errs {
    77  					level.Error(logger).Log("error", e.Error())
    78  					failed.Add(e)
    79  				}
    80  				level.Info(logger).Log()
    81  				continue
    82  			}
    83  			level.Info(logger).Log("result", "SUCCESS", "rules found", n)
    84  		}
    85  	}
    86  	return failed.Err()
    87  }