check

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: GPL-2.0 Imports: 14 Imported by: 27

README

go-check

go-check is a Golang library to help with development of monitoring plugins for tools like Icinga.

See the documentation on pkg.go.dev for more details and examples.

Usage

Simple Example

With the NewConfig constructor you can quickly create a CLI monitoring plugin:

package main

import (
    "fmt"

    "github.com/NETWAYS/go-check"
)

func main() {
    // Global configuration of the plugin
    config := check.NewConfig()
    config.Name = "check_test"
    config.Readme = `Test Plugin`
    config.Version = "1.0.0"

    // Command line arguments
    _ = config.FlagSet.StringP("hostname", "H", "localhost", "Hostname to check")

    config.ParseArguments()

    // Handle exit with the desired exit code
    check.Exit(check.OK, fmt.Sprintf("Everything is fine - answer=%d", 42))
    // Output:
    // [OK] - Everything is fine - answer=42
}

However, the go-check library does not require you to use the Config type.

Return Codes

The library provides predefined return or exit codes:

check.OK
check.Warning
check.Critical
check.Unknown

// These exit codes implement the Stringer interface
fmt.Println(check.OK)

To convert an integer or string into an exit code

unknown, err := NewStatus(3)

warning, err := NewStatusFromString("Warning")

See also: https://www.monitoring-plugins.org/doc/guidelines.html#AEN74

Exit

The Exit function can be used to cause an exit with the given status code.

check.Exit(check.OK, fmt.Sprintf("Everything is fine - value=%d", 42)) // OK, 0

// With critical
check.Exit(check.Critical, "Everything is broken", "Do something!") // CRITICAL, 2

The ExitWithPerfdata function can be used to include performance data in the output.

perfdata := check.PerfdataList{}
perfdata.Add(&check.Perfdata{Label: "packages_lost", Value: 42})

check.ExitWithPerfdata(check.OK, perfdata, "Everything is fine", "Package loss nominal")

The ExitError function can be used to cause an exit with the given error.

err := fmt.Errorf("connection to %s has been timed out", "localhost:12345")

check.ExitError(err)
// UNKNOWN, 3

You can use defer check.CatchPanic() to ensure a check plugin will always exit with a proper code, even if the code panics.

Timeout Handling

HandleTimeout is a helper for a goroutine, to wait for signals and timeout, and exit with a proper code.

checkPluginTimeoutInSeconds := 10

go check.HandleTimeout(checkPluginTimeoutInSeconds)

Thresholds

Threshold objects represent monitoring plugin thresholds that have methods to evaluate if a given input is within the range.

They can be created with the ParseThreshold parser.

warnThreshold, err := check.ParseThreshold("~:3")

if err != nil {
    // Handle the error
}

if warnThreshold.DoesViolate(3.6) {
    fmt.Println("Not great, not terrible.")
}

See also: https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT

Performance data

The Perfdata object represents monitoring plugin performance data that relates to the actual execution of a host or service check.

var pl check.PerfdataList

pl.Add(&check.Perfdata{
    Label: "process.cpu.percent",
    Value: 25,
    Uom:   "%",
    Warn:  &check.Threshold{Lower: check.NegInf, Upper: 50},
    Crit:  &check.Threshold{Lower: check.NegInf, Upper: 90},
    Min:   0,
    Max:   100})

fmt.Println(pl.String())

See also: https://www.monitoring-plugins.org/doc/guidelines.html#AEN197

WorstState

The WorstState helper can be used to determine the worst exit status from a set of exit states.

allStates = []check.Status{check.OK, check.Critical, check.Warning, check.Unknown}

rc := result.WorstState(allStates...)

Overall and Partial Results

The Overall and PartialResult objects can be used to represent a simple parent-child relationship.

An Overall can contain multiple subchecks. The final exit of the Overall will be automatically determined by the worst state of a PartialResult.

o := Overall{}
o.Add(0, "Something is OK")

pr := NewPartialResult()

pr.SetOutput("Something happened")
pr.SetState(check.OK)

o.AddSubcheck(pr)

fmt.Println(o.GetOutput())

// states: ok=1
// [OK] Something is OK
// \_ [OK] Something happened

Overall is concurrency-safe.

Human-readable bytes

ParseBytes is a helper that can be used to parse string containing IEC or SI bytes into the number of bytes.

b, err := ParseBytes("2MiB")
// uint64 2 * 1024 * 1024

b, err := ParseBytes("1MB")
// uint64 1000 * 1000

BytesIEC and BytesSI can be used to format a byte value with human-readable string output.

b := convert.BytesIEC(999)

fmt.Println(b)
// "999B"

b := convert.BytesIEC(999 * 1024)

fmt.Println(b)
// "999KiB"

b := convert.BytesIEC(999 * 1024 * 1024 * 1024 * 1024)

fmt.Println(b)
// "999TiB"

b := convert.BytesSI(999)

fmt.Println(b)
// "999B"

b := convert.BytesSI(999 * 1000)

fmt.Println(b)
// "999KB"

b := convert.BytesSI(999 * 1000 * 1000 * 1000 * 1000)

fmt.Println(b)
// "999TB"

Examples

A few plugins using go-check:

License

Copyright (c) 2020 NETWAYS GmbH

This library is distributed under the GPL-2.0 or newer license found in the COPYING file.

Documentation

Index

Examples

Constants

View Source
const (
	// OKString means everything is fine
	OKString = "OK"
	// WarningString means there is a problem the admin should review
	WarningString = "WARNING"
	// CriticalString means there is a problem that requires immediate action
	CriticalString = "CRITICAL"
	// UnknownString means the status can not be determined, probably due to an error or something missing
	UnknownString = "UNKNOWN"
)
View Source
const (
	NegativeInfinitySymbol = "~"
	RangeSeparatorSymbol   = ":"
	RangeStartSymbol       = "@"
)
View Source
const PerfdataSeparatorSymbol = "|"

Variables

View Source
var (
	PosInf = math.Inf(1)
	NegInf = math.Inf(-1)
)
View Source
var AllowExit = true

AllowExit lets you disable the call to os.Exit() in the BaseExit function of this package. This should be used carefully and most likely only for testing.

View Source
var PrintStack = true

PrintStack prints the error stack when recovering from a panic with CatchPanic()

Functions

func BaseExit

func BaseExit(rc Status)

BaseExit exits the process with a given return code.

Can be controlled with the global AllowExit. This should be used carefully and most likely only for testing.

func BoundaryToString

func BoundaryToString(value float64) string

BoundaryToString returns the string representation of a Threshold boundary.

func CatchPanic

func CatchPanic()

CatchPanic is a general function for defer, to capture any panic that occurred during runtime of a check

The function will recover from the condition and exit with a proper UNKNOWN status, while showing error and the call stack.

Example
defer CatchPanic()

panic("something bad happened")
Output:
[UNKNOWN] - Golang encountered a panic: something bad happened
would exit with code 3

func Compare added in v1.0.0

func Compare(a Status, b Status) int

Compare compares two Status types. If the left one (a) is worse than the right one (b), the result is < 0

If they are equal, the result is 0

If the right one (b) is worse than the left one (a), the result is > 0

func Exit

func Exit(rc Status, output ...string)

Exit exits the process with a given return code determined from the given Status and the provided text output to stdout. To include performance that is recommended to use ExitWithPerfdata instead Note that, the text output is not sanitized and will be printed as is.

Example: OK - everything is fine exit 0 Example: [UNKNOWN] - not sure what happened exit 3

Example
Exit(OK, fmt.Sprintf("Everything is fine - value=%d", 42))
Output:
[OK] - Everything is fine - value=42
would exit with code 0

func ExitError

func ExitError(err error)

ExitError exits with an Unknown state while reporting the error The Unknown state is used, since the plugin likely could not determine the actual status of whatever was meant to be checked.

Example
err := fmt.Errorf("connection to %s has been timed out", "localhost:12345")
ExitError(err)
Output:
[UNKNOWN] - connection to localhost:12345 has been timed out (*errors.errorString)
would exit with code 3

func ExitWithPerfdata added in v1.0.0

func ExitWithPerfdata(rc Status, perfdata PerfdataList, output ...string)

ExitWithPerfdata exits the process with a given return code determined from the Status, the performance data and the text output to stdout.

The provided text output will be sanitized to avoid multiple performance data separators (|).

Example: OK - everything is fine | mylabel=1 exit 0

Example
perfdata := PerfdataList{}
perfdata.Add(&Perfdata{Label: "time_duration", Value: 23})
perfdata.Add(&Perfdata{Label: "packages_lost", Value: 42})

ExitWithPerfdata(Critical, perfdata, "Everything is broken", "Do something")
Output:
[CRITICAL] - Everything is broken Do something|time_duration=23 packages_lost=42
would exit with code 2

func FormatFloat added in v0.3.0

func FormatFloat(value float64) string

FormatFloat returns a string representation of floats, avoiding scientific notation and removes trailing zeros.

func HandleTimeout

func HandleTimeout(timeout int)

HandleTimeout is a helper for a goroutine, to wait for signals and timeout, and exit with a proper code

func LoadFromEnv added in v0.6.0

func LoadFromEnv(config any)

LoadFromEnv can be used to load struct values from 'env' tags. Mainly used to avoid passing secrets via the CLI

type Config struct {
	Token    string `env:"BEARER_TOKEN"`
}

Types

type Config

type Config struct {
	// Name of the monitoring plugin
	Name string
	// README represents the help text for the CLI usage
	Readme string
	// Output for the --version flag
	Version string
	// Default for the --timeout flag
	Timeout int
	// Default for the --verbose flag
	Verbose bool
	// Default for the --debug flag
	Debug bool
	// Enable predefined --version output
	PrintVersion bool
	// Enable predefined default flags for the monitoring plugin
	DefaultFlags bool
	// Enable predefined default functions (e.g. Timeout handler) for the monitoring plugin
	DefaultHelper bool
	// Additional CLI flags for the monitoring plugin
	FlagSet *flag.FlagSet
}

Config represents a configuration for a monitoring plugin's CLI

Example
config := NewConfig()
config.Name = "check_test"
config.Readme = `Test Plugin`
config.Version = "1.0.0"

_ = config.FlagSet.StringP("hostname", "H", "localhost", "Hostname to check")

config.ParseArguments()

// Some checking should be done here

Exit(OK, fmt.Sprintf("Everything is fine - answer=%d", 42))
Output:
[OK] - Everything is fine - answer=42
would exit with code 0

func NewConfig

func NewConfig() *Config

NewConfig returns a Config struct with some defaults

func (*Config) EnableTimeoutHandler

func (c *Config) EnableTimeoutHandler()

EnableTimeoutHandler starts the timeout and signal handler in a goroutine

func (*Config) ParseArguments

func (c *Config) ParseArguments()

ParseArguments parses the command line arguments given by os.Args

func (*Config) ParseArray

func (c *Config) ParseArray(arguments []string)

ParseArray parses a list of command line arguments

type Perfdata added in v1.0.0

type Perfdata struct {
	Label string
	Value any
	// Uom is the unit-of-measurement, see links above for details.
	Uom  string
	Warn *Threshold
	Crit *Threshold
	Min  any
	Max  any
}

Perfdata represents all properties of performance data for Icinga

Implements fmt.Stringer to return the plaintext format for a plugin output. See also: https://www.monitoring-plugins.org/doc/guidelines.html#AEN201

For examples of Uom see: - https://github.com/Icinga/icinga2/blob/master/lib/base/perfdatavalue.cpp - https://icinga.com/docs/icinga-2/latest/doc/05-service-monitoring/#unit-of-measurement-uom

func (Perfdata) String added in v1.0.0

func (p Perfdata) String() string

String returns the proper format for the plugin output on errors (occurs with invalid data, the empty string is returned

func (Perfdata) ValidatedString added in v1.0.0

func (p Perfdata) ValidatedString() (string, error)

ValidatedString returns the proper format for the plugin output Returns an error in some known cases where the value of a data type does not represent a valid measurement, see the explanation for "formatNumeric" for perfdata values.

type PerfdataList added in v1.0.0

type PerfdataList []*Perfdata

PerfdataList can store multiple perfdata and implements the fmt.Stringer interface to provide formatted output for the performance data

Example
list := PerfdataList{}
list.Add(&Perfdata{Label: "test1", Value: 23})
list.Add(&Perfdata{Label: "test2", Value: 42})

fmt.Println(list)
Output:
[test1=23 test2=42]

func (*PerfdataList) Add added in v1.0.0

func (l *PerfdataList) Add(p *Perfdata)

Add adds a Perfdata pointer to the list. Note that, it's not concurrency safe.

func (*PerfdataList) String added in v1.0.0

func (l *PerfdataList) String() string

String returns string representations of all Perfdata added to the list

type Status added in v1.0.0

type Status int
const (
	OK Status = iota
	Warning
	Critical
	Unknown
)

func NewStatus added in v1.0.0

func NewStatus(status int) (Status, error)

NewStatus returns a state corresponding to its common string representation. When an invalid parameter is passed an error and an Unknown status will be returned

func NewStatusFromString added in v1.0.0

func NewStatusFromString(status string) (Status, error)

NewStatusFromString returns a state corresponding to its common string representation. When an invalid parameter is passed an error and an Unknown status will be returned

func WorstState added in v1.0.0

func WorstState(states ...Status) Status

WorstState determines the worst state from a list of states

This can be used to combine multiple states into a one state. Order of preference: Critical, Unknown, Warning, Ok

Note that, this precedence was decided for this package since there is no specification for the preference. See also: https://www.monitoring-plugins.org/doc/guidelines.html#AEN74

func (Status) String added in v1.0.0

func (s Status) String() string

String returns the string corresponding to a state

type Threshold

type Threshold struct {
	Inside bool
	Lower  float64
	Upper  float64
}

Threshold defines threshold for any numeric value

Format: [@]start:end

Threshold Generate an alert if x... 10 < 0 or > 10, (outside the range of {0 .. 10}) 10: < 10, (outside {10 .. ∞}) ~:10 > 10, (outside the range of {-∞ .. 10}) 10:20 < 10 or > 20, (outside the range of {10 .. 20}) @10:20 ≥ 10 and ≤ 20, (inside the range of {10 .. 20})

See also: https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT

func ParseThreshold

func ParseThreshold(spec string) (*Threshold, error)

ParseThreshold parses a Threshold from a string.

See the Threshold type for details.

func (Threshold) DoesViolate

func (t Threshold) DoesViolate(value float64) bool

DoesViolate compares a value against the threshold, and returns true if the value violates the threshold.

func (Threshold) String

func (t Threshold) String() string

String returns the plain representation of the Threshold

Directories

Path Synopsis
Package convert provides function to convert and humanize units
Package convert provides function to convert and humanize units
examples
check_example command
check_example2 command
Package result provides types and functions to organize results in a check plugin
Package result provides types and functions to organize results in a check plugin
Package testhelper is used in testing.
Package testhelper is used in testing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL