Skip to content

Commit

Permalink
Refactor watch command to take a subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
prymitive committed Mar 11, 2024
1 parent 43092d6 commit 0255f16
Show file tree
Hide file tree
Showing 18 changed files with 103 additions and 42 deletions.
10 changes: 5 additions & 5 deletions cmd/pint/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,32 @@ var (

var ciCmd = &cli.Command{
Name: "ci",
Usage: "Lint CI changes",
Usage: "Run checks on all git changes.",
Action: actionCI,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: requireOwnerFlag,
Aliases: []string{"r"},
Value: false,
Usage: "Require all rules to have an owner set via comment",
Usage: "Require all rules to have an owner set via comment.",
},
&cli.StringFlag{
Name: baseBranchFlag,
Aliases: []string{"b"},
Value: "",
Usage: "Set base branch to use for PR checks (main, master, ...)",
Usage: "Set base branch to use for PR checks (main, master, ...).",
},
&cli.StringFlag{
Name: failOnFlag,
Aliases: []string{"w"},
Value: "bug",
Usage: "Exit with non-zero code if there are problems with given severity (or higher) detected",
Usage: "Exit with non-zero code if there are problems with given severity (or higher) detected.",
},
&cli.BoolFlag{
Name: teamCityFlag,
Aliases: []string{"t"},
Value: false,
Usage: "Report problems using TeamCity Service Messages",
Usage: "Print found problems using TeamCity Service Messages format.",
},
},
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

var configCmd = &cli.Command{
Name: "config",
Usage: "Parse and print used config",
Usage: "Parse and print used config.",
Action: actionConfig,
}

Expand Down
10 changes: 5 additions & 5 deletions cmd/pint/lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,32 @@ var requireOwnerFlag = "require-owner"

var lintCmd = &cli.Command{
Name: "lint",
Usage: "Lint specified files",
Usage: "Check specified files or directories (can be a glob).",
Action: actionLint,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: requireOwnerFlag,
Aliases: []string{"r"},
Value: false,
Usage: "Require all rules to have an owner set via comment",
Usage: "Require all rules to have an owner set via comment.",
},
&cli.StringFlag{
Name: minSeverityFlag,
Aliases: []string{"n"},
Value: "warning",
Usage: "Set minimum severity for reported problems",
Usage: "Set minimum severity for reported problems.",
},
&cli.StringFlag{
Name: failOnFlag,
Aliases: []string{"w"},
Value: "bug",
Usage: "Exit with non-zero code if there are problems with given severity (or higher) detected",
Usage: "Exit with non-zero code if there are problems with given severity (or higher) detected.",
},
&cli.BoolFlag{
Name: teamCityFlag,
Aliases: []string{"t"},
Value: false,
Usage: "Report problems using TeamCity Service Messages",
Usage: "Report problems using TeamCity Service Messages.",
},
},
}
Expand Down
14 changes: 7 additions & 7 deletions cmd/pint/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,43 +27,43 @@ var (

func newApp() *cli.App {
return &cli.App{
Usage: "Prometheus rule linter",
Usage: "Prometheus rule linter/validator.",
Flags: []cli.Flag{
&cli.PathFlag{
Name: configFlag,
Aliases: []string{"c"},
Value: ".pint.hcl",
Usage: "Configuration file to use",
Usage: "Configuration file to use.",
},
&cli.IntFlag{
Name: workersFlag,
Aliases: []string{"w"},
Value: 10,
Usage: "Number of worker threads for running checks",
Usage: "Number of worker threads for running checks.",
},
&cli.StringFlag{
Name: logLevelFlag,
Aliases: []string{"l"},
Value: slog.LevelInfo.String(),
Usage: "Log level",
Usage: "Log level.",
},
&cli.BoolFlag{
Name: noColorFlag,
Aliases: []string{"n"},
Value: false,
Usage: "Disable output colouring",
Usage: "Disable output colouring.",
},
&cli.StringSliceFlag{
Name: disabledFlag,
Aliases: []string{"d"},
Value: cli.NewStringSlice(),
Usage: "List of checks to disable (example: promql/cost)",
Usage: "List of checks to disable (example: promql/cost).",
},
&cli.BoolFlag{
Name: offlineFlag,
Aliases: []string{"o"},
Value: false,
Usage: "Disable all check that send live queries to Prometheus servers",
Usage: "Disable all check that send live queries to Prometheus servers.",
},
},
Commands: []*cli.Command{
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const levelStep = 2

var parseCmd = &cli.Command{
Name: "parse",
Usage: "Parse a query and print AST, use for debugging or understanding query details",
Usage: "Parse a query and print AST, use it for debugging or understanding query details.",
Action: actionParse,
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/tests/0041_watch.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
exec bash -x ./test.sh &

pint.ok --no-color -l debug watch --interval=5s --listen=127.0.0.1:6041 --pidfile=pint.pid rules
pint.ok --no-color -l debug watch --interval=5s --listen=127.0.0.1:6041 --pidfile=pint.pid glob rules
! stdout .

stderr 'level=INFO msg="Pidfile created" path=pint.pid'
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/tests/0042_watch_metrics.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
exec bash -x ./test.sh &

pint.ok watch --listen=127.0.0.1:6042 --pidfile=pint.pid rules
pint.ok watch --listen=127.0.0.1:6042 --pidfile=pint.pid glob rules
cmp curl.txt metrics.txt

-- test.sh --
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/tests/0043_watch_cancel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ http start github 127.0.0.1:7043

exec bash -x ./test.sh &

pint.ok --no-color watch --interval=1h --listen=127.0.0.1:6043 --pidfile=pint.pid rules
pint.ok --no-color watch --interval=1h --listen=127.0.0.1:6043 --pidfile=pint.pid glob rules
! stdout .
stderr 'level=INFO msg="Shutting down"'
stderr 'level=INFO msg="Waiting for all background tasks to finish"'
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/tests/0048_watch_limit.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
exec bash -x ./test.sh &

pint.ok watch --listen=127.0.0.1:6048 --max-problems=2 --pidfile=pint.pid rules
pint.ok watch --listen=127.0.0.1:6048 --max-problems=2 --pidfile=pint.pid glob rules
cmp curl.txt metrics.txt

-- test.sh --
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/tests/0049_watch_severity_warning.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
exec bash -x ./test.sh &

pint.ok watch --listen=127.0.0.1:6049 --min-severity=warning --pidfile=pint.pid rules
pint.ok watch --listen=127.0.0.1:6049 --min-severity=warning --pidfile=pint.pid glob rules
cmp curl.txt metrics.txt

-- test.sh --
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/tests/0050_watch_severity_fatal.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
exec bash -x ./test.sh &

pint.ok watch --listen=127.0.0.1:6050 --min-severity=fatal --pidfile=pint.pid rules
pint.ok watch --listen=127.0.0.1:6050 --min-severity=fatal --pidfile=pint.pid glob rules
cmp curl.txt metrics.txt

-- test.sh --
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/tests/0051_watch_severity_invalid.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pint.error --no-color watch --min-severity=foo bar
pint.error --no-color watch --min-severity=foo glob bar
! stdout .
cmp stderr stderr.txt

Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/tests/0054_watch_metrics_prometheus.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ http start prometheus 127.0.0.1:7054

exec bash -x ./test.sh &

pint.ok watch --listen=127.0.0.1:6054 --pidfile=pint.pid rules
pint.ok watch --listen=127.0.0.1:6054 --pidfile=pint.pid glob rules
cmp curl.txt metrics.txt

-- test.sh --
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/tests/0057_watch_metrics_prometheus_ignore.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ http start prometheus 127.0.0.1:7057

exec bash -x ./test.sh &

pint.ok watch --listen=127.0.0.1:6057 --pidfile=pint.pid rules
pint.ok watch --listen=127.0.0.1:6057 --pidfile=pint.pid glob rules
cmp curl.txt metrics.txt

-- test.sh --
Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/tests/0064_watch_no_path.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pint.error --no-color watch --listen=127.0.0.1:6064
pint.error --no-color watch --listen=127.0.0.1:6064 glob
! stdout .
cmp stderr stderr.txt

Expand Down
2 changes: 1 addition & 1 deletion cmd/pint/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

var versionCmd = &cli.Command{
Name: "version",
Usage: "Print version and exit",
Usage: "Print version and exit.",
Action: actionVersion,
}

Expand Down
23 changes: 14 additions & 9 deletions cmd/pint/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,38 +38,44 @@ const (
)

var watchCmd = &cli.Command{
Name: "watch",
Usage: "Continuously lint specified files",
Action: actionWatch,
Name: "watch",
Usage: "Run in the foreground and continuesly check specified rules.",
Subcommands: []*cli.Command{
{
Name: "glob",
Usage: "Check a list of files or directories (can be a glob).",
Action: actionWatch,
},
},
Flags: []cli.Flag{
&cli.DurationFlag{
Name: intervalFlag,
Aliases: []string{"i"},
Value: time.Minute * 10,
Usage: "How often to run all checks",
Usage: "How often to run all checks.",
},
&cli.StringFlag{
Name: listenFlag,
Aliases: []string{"s"},
Value: ":8080",
Usage: "Listen address for HTTP web server exposing metrics",
Usage: "Listen address for HTTP web server exposing metrics.",
},
&cli.StringFlag{
Name: pidfileFlag,
Aliases: []string{"p"},
Usage: "Write pid file to this path",
Usage: "Write pid file to this path.",
},
&cli.IntFlag{
Name: maxProblemsFlag,
Aliases: []string{"m"},
Value: 0,
Usage: "Maximum number of problems to report on metrics, 0 - no limit",
Usage: "Maximum number of problems to report on metrics, 0 - no limit.",
},
&cli.StringFlag{
Name: minSeverityFlag,
Aliases: []string{"n"},
Value: strings.ToLower(checks.Bug.String()),
Usage: "Set minimum severity for problems reported via metrics",
Usage: "Set minimum severity for problems reported via metrics.",
},
},
}
Expand Down Expand Up @@ -257,7 +263,6 @@ func newProblemCollector(cfg config.Config, paths []string, minSeverity checks.S

func (c *problemCollector) scan(ctx context.Context, workers int, isOffline bool, gen *config.PrometheusGenerator) error {
slog.Info("Finding all rules to check", slog.Any("paths", c.paths))
// nolint: contextcheck
entries, err := discovery.NewGlobFinder(c.paths, git.NewPathFilter(nil, nil, c.cfg.Parser.CompileRelaxed())).Find()
if err != nil {
return err
Expand Down
62 changes: 59 additions & 3 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,9 @@ it will pass `workdir` option to `pint lint`, which means that all files inside

### Ad-hoc

Lint specified files and report any found issue.
Check specified files and report any found issue.
You can pass directory paths and use [glob](https://pkg.go.dev/path/filepath#Match)
patterns as arguments to select files for checking.

You can lint selected files:

Expand All @@ -140,14 +142,68 @@ or both:
pint lint path/to/dir file.yml path/file.yml path/dir
```

Using glob patterns:

```shell
pint lint path/*.yml path/*.yaml
```

### Watch mode

Run pint as a daemon in watch mode:
Run pint as a daemon in watch mode where it continuously checks
all rules found in selected files and exposes metrics about
found problems.

#### Manually selecting files and directories

You can tell it to continuously test specific files or directories:

```shell
pint watch glob $GLOB_1 $GLOB_2 ... $GLOB_N
```

Example:

```shell
pint watch glob /etc/prometheus/rules-*.yml /etc/prometheus/rules.d
```

If provide a config file for pint with some Prometheus server definitions
then pint will also run "online" checks for it to, for example, ensure all
time series used inside your alerting rules are still present.
Example config:

```json
prometheus "local" {
uri = "http://localhost:9090"
}
```

#### Getting list of files to check from Prometheus

You can also point pint directly at a Prometheus server from the config file.
This will make pint query Prometheus API to get the current value of `rule_files`
Prometheus config option and then run checks on all matching files.
This way if you test your rules against a running Prometheus instance then you don't
need to manually specify any paths or directories.

Usage:

```shell
pint watch rules.yml
pint watch rule_files $prometheus
```

Where `$prometheus` is the name of `prometheus` configuration block from pint
config file.

Example:

```shell
pint watch rule_files local
```

#### Accessing watch mode metrics

By default it will start a HTTP server on port `8080` and run all checks every
10 minutes. This can be customised by passing extra flags to the `watch` command.
Run `pint watch -h` to see all available flags.
Expand Down

0 comments on commit 0255f16

Please sign in to comment.