Package for writing Nagios/Icinga/et cetera plugins in Go (golang)

Build status

nagiosplugin

Package for writing Nagios/Icinga/et cetera plugins in Go (golang).

Documentation

See http://godoc.org/github.com/olorin/nagiosplugin.

Usage example

The general usage pattern looks like this:

func main() {
	// Initialize the check - this will return an UNKNOWN result
	// until more results are added.
	check := nagiosplugin.NewCheck()
	// If we exit early or panic() we'll still output a result.
	defer check.Finish()

	// obtain data here

	// Add an 'OK' result - if no 'worse' check results have been
	// added, this is the one that will be output.
	check.AddResult(nagiosplugin.OK, "everything looks shiny, cap'n")
	// Add some perfdata too (label, unit, value, min, max,
	// warn, crit). The math.Inf(1) will be parsed as 'no
	// maximum'.
	check.AddPerfDatum("badness", "kb", 3.14159, 0.0, math.Inf(1), 8000.0, 9000.0)

	// Parse a range from the command line and warn on a match.
	warnRange, err := nagiosplugin.ParseRange( "1:2" )
	if err != nil {
		check.AddResult(nagiosplugin.UNKNOWN, "error parsing warning range")
	}
	if warnRange.Check( 3.14159 ) {
		check.AddResult(nagiosplugin.WARNING, "Are we crashing again?")
	}
}

In the example above, multiple results were added to the check with AddResult(). The final state of the check will be determined by its most severe result. By default, result severity is ordered to match the plugin return codes documented in the Nagios plugin developer guidelines. A WARNING result is considered more severe than OK, CRITICAL more severe than WARNING, and UNKNOWN most severe of all. A status policy may be used to modify this default behaviour:

func main() {
	check := nagiosplugin.NewCheckWithOptions(nagiosplugin.CheckOptions{
		// OK -> UNKNOWN -> WARNING -> CRITICAL
		StatusPolicy: nagiosplugin.NewOUWCStatusPolicy(),
	})
	defer check.Finish()

	// Now, any WARNING or CRITICAL results added to the check will be
	// considered more severe than any UNKNOWN result.
}

Language version

Requires go >= 1.0; tested with versions up to 1.7.

Owner
Sharif Olorin
I turn numbers into other, more useful numbers.
Sharif Olorin
Comments
  • Make WARNING/CRITICAL supersede UNKNOWN status

    Make WARNING/CRITICAL supersede UNKNOWN status

    Hello!

    This PR will change the way nagiosplugin interprets multiple check results as added by AddResult().

    Before: [WARNING, UNKNOWN] -> UNKNOWN

    After: [WARNING, UNKNOWN] -> WARNING

    To explain why I think this change is needed, let's go back to what these 'plugin return codes' (as Nagios calls them) mean in practice:

    • WARNING and CRITICAL: The plugin has positively identified something that is almost certainly broken.
    • UNKNOWN: The plugin cannot be sure whether something is broken because it could not acquire sufficient data to reach a decision.

    Non-trivial plugins will typically check multiple data points before returning a final result. Suppose I am trying to monitor my old washing machine. I sample from two sensors, a vibration sensor, and a sensor that tells me whether the floor is wet from a leak. I know from experience that should either sensor report a value outside its thresholds then there is a definite problem. This is true regardless of what the other sensor says -- or whether the other sensor is even attached and working. In pseudocode:

    func checkVibrations() {
        vibrations, err = queryVibrationSensor()
        if err {
            check.AddResult(UNKNOWN, "Unable to query vibration sensor")
            return
        }
        if vibrations > vibrationThreshold {
            check.AddResult(OK, "...")
        } else {
            check.AddResult(CRITICAL, "...")
        }
    }
    
    func checkLeaks() {
        leakiness, err = queryWaterSensor()
        if err {
            check.AddResult(UNKNOWN, "Unable to query water sensor")
            return
        }
        // and so on
    }
    
    checkVibrations()
    checkLeaks()
    

    With current behaviour, if I unplug the vibration sensor, any real fault detected by the water leakage sensor will be hidden behind an UNKNOWN. The check is able to positively identify a fault using partial data. I think this is the common case. We should optimise for it.

  • Build with Go 1.7

    Build with Go 1.7

    % go version
    go version go1.7.3 darwin/amd64
    % go test
    PASS
    ok      github.com/olorin/nagiosplugin  0.006s
    

    I'm not sure whether Travis supports 1.7. Only way to find out is with a PR. :)

  • Decouple severity from Nagios plugin return codes

    Decouple severity from Nagios plugin return codes

    An alternative solution the problem identified in #8.

    Compared with #8, this approach should be fully backwards-compatible -- but comes at the cost of additional complexity.

  • Add Ranges

    Add Ranges

    This commit implements nagios style ranges for warning and critical thresholds.

    It follows the threshold format outlined in the nagios plugin development guidelines at https://www.monitoring-plugins.org/doc/guidelines.html#THRESHOLDFORMAT

  • Add NewOUWCStatusPolicy() and document its use

    Add NewOUWCStatusPolicy() and document its use

    @cosmopetrich offered me some feedback on #9 that I was regrettably unable to include prior to the merge. I have incorporated it here. His feedback was twofold:

    1. Document the use of the new 'status policy' feature in the README so that users are at least aware of it.
    2. Of all 4! potential permutations of result ordering, we figure the majority of users will opt for either the default or the OK -> UNKNOWN -> WARNING -> CRITICAL ordering. In this PR I have elevated the latter to an easy-to-use preset. Pithy naming suggestions welcome.

    No rush on this PR. Just closing a loop. :)

  • Add test for omitted thresholds

    Add test for omitted thresholds

    No bugs here. Just an additional unit test. It helped me vet perfdata output and I think it improves coverage. After initially writing the test as a throwaway, I thought you might want to keep it.

    Thanks for this package!

    o/

  • Return parse errors from ParseRange

    Return parse errors from ParseRange

    The README includes this snippet in its example usage:

        // Parse a range from the command line and warn on a match.
        warnRange, err := nagiosplugin.ParseRange( "1:2" )
        if err != nil {
            check.AddResult(nagiosplugin.UNKNOWN, "error parsing warning range")
        }
    

    Since the input to ParseRange() is (at least partially) user-supplied in practice, I tried changing the string "1:2" to something silly expecting an UNKNOWN ultimate check result. Instead, I received output on stdout that violated the prescribed output format for Nagios plugins.

    This pull request should make actual behaviour align with the expectations set by the README.

  • Testable example breaks unit tests (false pass)

    Testable example breaks unit tests (false pass)

    One of the supplied testable examples breaks unit tests:

    func Example() {
        check := nagiosplugin.NewCheck()
        // Make sure the check always (as much as possible) exits with
        // the correct output and return code if we terminate unexpectedly.
        defer check.Finish()
        // [...]
        // Output:
        // OK: Everything looks shiny from here, cap'n | badness=3.141592653589793;4000;9000;0;
    }
    

    check.Finish() invokes os.Exit(). The test runner is killed before it is able to report on the final test result.

    To see this in action, let's add an intentionally broken unit test and run go test.

    diff --git a/range_test.go b/range_test.go
    index 32c10ec..1e7dda0 100644
    --- a/range_test.go
    +++ b/range_test.go
    @@ -162,3 +162,7 @@ func TestNegInfRange(t *testing.T) {
                    }
            }
     }
    +
    +func TestBrokenThing(t *testing.T) {
    +       t.Errorf("THE SKY IS FALLING")
    +}
    
    saj@sundown % go test
    --- FAIL: TestBrokenThing (0.00s)
            range_test.go:167: THE SKY IS FALLING
    ok      github.com/olorin/nagiosplugin     0.010s
    saj@sundown % echo $?
    0
    

    Removing the testable examples results in expected behaviour:

    saj@sundown % git status -s
     D example_test.go
     M range_test.go
    saj@sundown % go test
    --- FAIL: TestBrokenThing (0.00s)
            range_test.go:167: THE SKY IS FALLING
    FAIL
    exit status 1
    FAIL    github.com/olorin/nagiosplugin     0.007s
    saj@sundown % echo $?
    1
    

    I'm not sure how best to approach this problem in a testable example.

  • Large floating-point numbers result in incorrect perfdata

    Large floating-point numbers result in incorrect perfdata

    Perfdata values/thresholds must be in [-0-9.]; the Show instance for Double uses exponent notation for large/small values. Fix the Show instance for PerfValue to display real numbers in ordinary decimal notation.

  • Don't run the check example test

    Don't run the check example test

    It exits the test runner, and thus invalidates the rest of the testsuite. Removing the "// Output:" comment ensures that the example compiles, but does not run it.

    Fixes #4.

  • Status should be initialized as UNKNOWN instead of OK

    Status should be initialized as UNKNOWN instead of OK

    The initial state of check.String() (which uses check.status) is OK while the initial check result is UNKNOWN. These should match.

    // Initialize the check - this will return an UNKNOWN result
    // until more results are added.
    check := nagiosplugin.NewCheck()
    
    fmt.Printf("%s", check.String())   // returns: 'OK'
    
    check.Finish()  // returns 'UNKNOWN: no check result specified'
    
  • Function AddPerfDatum - MIN:MAX defined as float64, range format not possible

    Function AddPerfDatum - MIN:MAX defined as float64, range format not possible

    Hi,

    I am totally new to Go, just got my environment setup. I am trying to fix a problem in a nagios plugins written in Go that relies on nagiosplugin.go (@egnite). Now it seems to me this nagiosplugin.go does not support performance data output as it should. Let me explain:

    The tutorial is refering to Nagios Plugin Developers Guideline that says format for perf data is

    'label'=value[UOM];[warn];[crit];[min];[max]

    but the function AddPerfDatum is changing position of MIN-MAX with CRIT-WARN

    // Add some perfdata too (label, unit, value, min, max, warn, crit)

    Anyway. But furthermore, I wonder why warn, crit, min and max are defined as float64 since 'warn' and 'crit' can of course be in the range format so it should be able to use "20:40" as a value : https://docs.icinga.com/latest/en/perfdata.html

    This means neither can't I set the MIN to "20:28" nor can't I set the MAX to "18:30" which is quite important for monitoring ranges like temperature or process counters.

    So logically, any plugin based on this repo cannot use the range format as standard plugins do. Any nagios plugin should be able to output the min:max range with a colon between them:

    /usr/lib/nagios/plugins/check_procs -w 300:400 -c 500:600
    PROCS KRITISCH: 192 Prozesse | procs=192;300:400;500:600;0
    

    Is there a chance this code will be improved in time?

  • How to use thresholds in Check.AddPerfDatum()

    How to use thresholds in Check.AddPerfDatum()

    Hello,

    according to Nagios Plugin Dev Guidelines:

    warn and crit are in the range format (see the Section called Threshold and ranges). Must be the same UOM

    However, Check.AddPerfDatum() expects float64. What's the correct way to add warn and crit threshold to perf data then? I've tried something like:

    check.AddPerfDatum(label, unit, value, 0, 0,
        warnRange.Start, warnRange.End, critRange.Start, critRange.End)
    

    but the output doesn't seem to be correct, resp. it's something like:

    CRITICAL: It's broken. | label=value;0;warn.End;0;0
    

    where input values for warn and critical are -w 400000 -c 500000. I've also tried to pass different combinations to Check.AddPerfDatum(), but without success. However, it's possible I'm expecting something that cannot be :)

    Thank you for clarification.

Related tags
🎉 An awesome version control tool for protoc and its related plugins.
🎉 An awesome version control tool for protoc and its related plugins.

❤️ PowerProto is actively maintained! Any questions in use can be directly raised issue, I will respond to you as fast as possible. If you think the p

Dec 29, 2022
This plugins watches and builds the source files continiusly in-memory

Caddy Esbuild plugin This plugins watches and builds the source files continiusly in-memory. It includes a etag to cache in the browser to save bandwi

Jun 17, 2022
Provides agent and server plugins for SPIRE to allow Tailscale node attestation.

SPIRE Tailscale Plugin ⚠️ this node attestation plugin relies on a Tailscale OIDC id-token feature, which is marked as Work-in-Progress and may not be

May 22, 2022
Package raw enables reading and writing data at the device driver level for a network interface. MIT Licensed.

raw Package raw enables reading and writing data at the device driver level for a network interface. MIT Licensed. For more information about using ra

Dec 28, 2022
A library to simplify writing applications using TCP sockets to stream protobuff messages

BuffStreams Streaming Protocol Buffers messages over TCP in Golang What is BuffStreams? BuffStreams is a set of abstraction over TCPConns for streamin

Dec 13, 2022
Go library for writing standalone Map/Reduce jobs or for use with Hadoop's streaming protocol

dmrgo is a Go library for writing map/reduce jobs. It can be used with Hadoop's streaming protocol, but also includes a standalone map/reduce impleme

Nov 27, 2022
webrpc is a schema-driven approach to writing backend services for modern Web apps and networks
webrpc is a schema-driven approach to writing backend services for modern Web apps and networks

webrpc is a schema-driven approach to writing backend servers for the Web. Write your server's api interface in a schema format of RIDL or JSON, and t

Jan 7, 2023
The plugin serves as a starting point for writing a Mattermost plugin

Plugin Starter Template This plugin serves as a starting point for writing a Mattermost plugin. Feel free to base your own plugin off this repository.

Dec 10, 2021
Forms814 - A website builder, useful for writing data collection webapps quickly.
Forms814 - A website builder, useful for writing data collection webapps quickly.

forms814 A website builder, useful for writing data collection webapps quickly. Project Design The method in use here is to mix it with complicated fo

Oct 25, 2022
Fetch-npm-package - A small utility that can be used to fetch a given version of a NPM package

Use fetch-npm-package <package> <version> <output-dir> E.g. fetch-npm-package is

May 21, 2022
ipx provides general purpose extensions to golang's IP functions in net package

ipx ipx is a library which provides a set of extensions on go's standart IP functions in net package. compability with net package ipx is fully compat

May 24, 2021
EasyTCP is a light-weight and less painful TCP server framework written in Go (Golang) based on the standard net package.

EasyTCP is a light-weight TCP framework written in Go (Golang), built with message router. EasyTCP helps you build a TCP server easily fast and less painful.

Jan 7, 2023
Package proxychannel is a customizable HTTP proxy framework in Golang.
Package proxychannel is a customizable HTTP proxy framework in Golang.

proxychannel Package proxychannel is a customizable HTTP proxy framework in Golang. It accepts regular HTTP and CONNECT(for HTTPS) requests, and hijac

Aug 6, 2022
Memberlist - Golang package for gossip based membership and failure detection

memberlist memberlist 是一个 Go 库,它使用基于 gossip 的协议来管理集群成员和成员故障检测。 这种库的用例影响深远:所有分布式系

Jan 26, 2022
Ratelimit - This package provides a Golang implementation of the leaky-bucket rate limit algorithm

Go rate limiter This package provides a Golang implementation of the leaky-bucke

Jul 26, 2022
Package arp implements the ARP protocol, as described in RFC 826. MIT Licensed.

arp Package arp implements the ARP protocol, as described in RFC 826. MIT Licensed. Portions of this code are taken from the Go standard library. The

Dec 20, 2022
Package dhcp6 implements a DHCPv6 server, as described in RFC 3315. MIT Licensed.

dhcp6 Package dhcp6 implements a DHCPv6 server, as described in IETF RFC 3315. MIT Licensed. At this time, the API is not stable, and may change over

Sep 27, 2022
A Go package for sending and receiving ethernet frames. Currently supporting Linux, Freebsd, and OS X.

ether ether is a go package for sending and receiving ethernet frames. Currently supported platform: BPF based OS X FreeBSD AF_PACKET based Linux Docu

Sep 27, 2022
Package ethernet implements marshaling and unmarshaling of IEEE 802.3 Ethernet II frames and IEEE 802.1Q VLAN tags. MIT Licensed.

ethernet Package ethernet implements marshaling and unmarshaling of IEEE 802.3 Ethernet II frames and IEEE 802.1Q VLAN tags. MIT Licensed. For more in

Dec 29, 2022