Emmanuel BENOîT
c46c9d76d9
This PR adds the `check_output_matches` plugin, which can be used to count regexp or substring matches from either text files or command outputs and determine the final status based on the amount of matches that were found. Reviewed-on: #5 Co-authored-by: Emmanuel BENOÎT <tseeker@nocternity.net> Co-committed-by: Emmanuel BENOÎT <tseeker@nocternity.net>
95 lines
3 KiB
Go
95 lines
3 KiB
Go
package matches // import nocternity.net/gomonop/cmd/matches
|
|
|
|
import (
|
|
"context"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/karrick/golf"
|
|
|
|
"nocternity.net/gomonop/pkg/perfdata"
|
|
)
|
|
|
|
// pluginFlags represent command line flags that have been parsed.
|
|
type pluginFlags struct {
|
|
isFile bool // Are we reading from a file?
|
|
dataSource string // The file or command to read from
|
|
timeout time.Duration // A timeout for the command, or 0 to disable
|
|
matches []matchConfig // Configuration for the matches to check
|
|
strict bool // Reject lines that don't match anything
|
|
}
|
|
|
|
// matchConfig is the configuration for a single match to check.
|
|
type matchConfig struct {
|
|
isRegexp bool // Are we checking against a regular expression?
|
|
matchString string // The string or regexp to match
|
|
compiledRe *regexp.Regexp // The compiled regexp
|
|
warn *perfdata.Range // Warning range
|
|
crit *perfdata.Range // Critical range
|
|
}
|
|
|
|
// parseArguments parses command line arguments for the plugin.
|
|
func (p *pluginFlags) parseArguments() {
|
|
golf.BoolVarP(&p.isFile, 'f', "is-file", false, "Are we reading from a file?")
|
|
golf.StringVarP(&p.dataSource, 's', "source", "", "The file or command to read from")
|
|
golf.DurationVarP(&p.timeout, 'T', "timeout", 0, "A timeout for the command, or 0 to disable")
|
|
golf.BoolVarP(&p.strict, 'S', "strict", false, "Reject lines that do not match anything")
|
|
|
|
isRegexp := golf.BoolP('R', "no-regexp", true, "Following match argument will be a basic string")
|
|
golf.BoolVarP(isRegexp, 'r', "regexp", false, "Following match argument will be a regexp")
|
|
|
|
var wRange *perfdata.Range
|
|
golf.StringFuncP('w', "warn", "", "Warning range, in Nagios-compatible format", func(s string) error {
|
|
locRange, err := perfdata.ParseRange(s)
|
|
if err == nil {
|
|
wRange = locRange
|
|
}
|
|
return err
|
|
})
|
|
golf.BoolFuncP('W', "no-warn", false, "Clear warning range", func(bool) error {
|
|
wRange = nil
|
|
return nil
|
|
})
|
|
|
|
var cRange *perfdata.Range
|
|
golf.StringFuncP('c', "critical", "", "Critical range, in Nagios-compatible format", func(s string) error {
|
|
locRange, err := perfdata.ParseRange(s)
|
|
if err == nil {
|
|
cRange = locRange
|
|
}
|
|
return err
|
|
})
|
|
golf.BoolFuncP('C', "no-critical", false, "Clear warning range", func(bool) error {
|
|
cRange = nil
|
|
return nil
|
|
})
|
|
|
|
golf.StringFuncP('m', "match", "", "Match string", func(s string) error {
|
|
p.matches = append(p.matches, matchConfig{
|
|
isRegexp: *isRegexp,
|
|
matchString: s,
|
|
warn: wRange,
|
|
crit: cRange,
|
|
})
|
|
return nil
|
|
})
|
|
|
|
golf.Parse()
|
|
}
|
|
|
|
// makeContext generates a context based on the timeout, if one is set.
|
|
func (p *pluginFlags) makeContext() (context.Context, context.CancelFunc) {
|
|
if p.timeout == 0 {
|
|
return context.Background(), func() {}
|
|
}
|
|
return context.WithTimeout(context.Background(), p.timeout)
|
|
}
|
|
|
|
// matches check if the specified string matches a configuration.
|
|
func (p *matchConfig) matches(s string) bool {
|
|
if p.isRegexp {
|
|
return p.compiledRe.MatchString(s)
|
|
}
|
|
return strings.Contains(s, p.matchString)
|
|
}
|