From 3a58d586f935a35390196bbbb65b36d5c651fe93 Mon Sep 17 00:00:00 2001 From: Gavin Carr Date: Tue, 26 Sep 2006 04:10:37 +0000 Subject: Update Nagios::Plugin with NP::Function wrapper methods, and extras. git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/Nagios-Plugin/trunk@1483 f882894a-f735-0410-b71e-b25c423dba1c diff --git a/MANIFEST b/MANIFEST index 9fc9611..a0764e5 100644 --- a/MANIFEST +++ b/MANIFEST @@ -4,7 +4,8 @@ MANIFEST README t/check_stuff.pl t/check_stuff.t -t/Nagios-Plugin.t +t/Nagios-Plugin-01.t +t/Nagios-Plugin-02.t t/Nagios-Plugin-Functions-01.t t/Nagios-Plugin-Functions-02.t t/Nagios-Plugin-Getopt-01.t diff --git a/Makefile.PL b/Makefile.PL index c25369f..2d45e43 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -5,7 +5,10 @@ use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Nagios::Plugin', VERSION_FROM => 'lib/Nagios/Plugin/Functions.pm', # finds $VERSION - PREREQ_PM => {Params::Validate => 0.24}, # e.g., Module::Name => 1.1 + PREREQ_PM => { + Class::Struct => 0, + Params::Validate => 0.24, + }, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/Nagios/Plugin.pm', # retrieve abstract from module AUTHOR => 'Nagios Plugin Development Team ') : ()), diff --git a/lib/Nagios/Plugin.pm b/lib/Nagios/Plugin.pm index 5ff6709..025880d 100644 --- a/lib/Nagios/Plugin.pm +++ b/lib/Nagios/Plugin.pm @@ -1,17 +1,17 @@ # This is only because Class::Struct doesn't allow subclasses # Trick stolen from Class::DBI -package Nagios::__::Plugin; +###package Nagios::__::Plugin; -use 5.008004; use Class::Struct; struct "Nagios::__::Plugin" => { - perfdata => '@', - shortname => '$', - }; + perfdata => '@', + shortname => '$', + messages => '%', + }; package Nagios::Plugin; -use Nagios::Plugin::Functions; +use Nagios::Plugin::Functions qw(:codes %ERRORS %STATUS_TEXT @STATUS_CODES); use Nagios::Plugin::Performance; use Nagios::Plugin::Threshold; @@ -22,149 +22,385 @@ use Carp; use Exporter; our @ISA = qw(Exporter Nagios::__::Plugin); +our @EXPORT = (@STATUS_CODES); our @EXPORT_OK = qw(%ERRORS); our $VERSION = $Nagios::Plugin::Functions::VERSION; sub add_perfdata { - my ($self, %args) = @_; - my $perf = Nagios::Plugin::Performance->new(%args); - push @{$self->perfdata}, $perf; + my ($self, %args) = @_; + my $perf = Nagios::Plugin::Performance->new(%args); + push @{$self->perfdata}, $perf; } - sub all_perfoutput { - my $self = shift; - return join(" ", map {$_->perfoutput} (@{$self->perfdata})); + my $self = shift; + return join(" ", map {$_->perfoutput} (@{$self->perfdata})); } sub set_thresholds { shift; Nagios::Plugin::Threshold->set_thresholds(@_); } +# NP::Functions wrappers +sub nagios_exit { + my $self = shift; + Nagios::Plugin::Functions::nagios_exit(@_, { plugin => $self }); +} +sub nagios_die { + my $self = shift; + Nagios::Plugin::Functions::nagios_die(@_, { plugin => $self }); +} sub die { - my $self = shift; - Nagios::Plugin::Functions::die(@_, { plugin => $self }); + my $self = shift; + Nagios::Plugin::Functions::nagios_die(@_, { plugin => $self }); +} + +# ------------------------------------------------------------------------- +# NP::Functions::check_messages helpers and wrappers + +sub add_message { + my $self = shift; + my ($code, @messages) = @_; + + croak "Invalid error code '$code'" + unless defined($ERRORS{uc $code}) || defined($STATUS_TEXT{$code}); + + # Store messages using strings rather than numeric codes + $code = $STATUS_TEXT{$code} if $STATUS_TEXT{$code}; + $code = lc $code; + croak "Error code '$code' not supported by add_message" + if $code eq 'unknown' || $code eq 'dependent'; + + $self->messages($code, []) unless $self->messages($code); + push @{$self->messages($code)}, @messages; } +sub check_messages { + my $self = shift; + my %args = @_; + + # Add object messages to any passed in as args + for my $code (qw(critical warning ok)) { + my $messages = $self->messages($code) || []; + if ($args{$code}) { + unless (ref $args{$code} eq 'ARRAY') { + if ($code eq 'ok') { + $args{$code} = [ $args{$code} ]; + } else { + croak "Invalid argument '$code'" + } + } + push @{$args{$code}}, @$messages; + } + else { + $args{$code} = $messages; + } + + + Nagios::Plugin::Functions::check_messages(%args); +} + +# ------------------------------------------------------------------------- + 1; -__END__ -=head1 NAME +#vim:et:sw=4 + +__END__ -Nagios::Plugin - Object oriented helper routines for your Nagios plugin -=head1 SYNOPSIS +=head1 NAME - use Nagios::Plugin qw(%ERRORS); - $p = Nagios::Plugin->new( shortname => "PAGESIZE" ); +Nagios::Plugin - a family of perl modules to streamline writing Nagios plugins - $threshold = $p->set_thresholds( warning => "10:25", critical => "~:25" ); - # Critical if outside -INF to 25, ie > 25. Warn if outside 10-25, ie < 10 - # ... collect current metric into $value - if ($trouble_getting_metric) { - $p->die( return_code => $ERRORS{UNKNOWN}, message => "Could not retrieve page"); - # Output: PAGESIZE UNKNOWN Could not retrieve page - # Return code: 3 - } +=head1 SYNOPSIS - $p->add_perfdata( label => "size", - value => $value, - uom => "kB", - threshold => $threshold, + # Constants OK, WARNING, CRITICAL, and UNKNOWN are exported by default + # See also Nagios::Plugin::Functions for a functional interface + use Nagios::Plugin; + + # Constructor + $np = Nagios::Plugin->new; # OR + $np = Nagios::Plugin->new( shortname => "PAGESIZE" ); + + # Exit methods - nagios_exit( CODE, MESSAGE ), nagios_die( MESSAGE, [CODE]) + $page = retrieve_page($page1) + or $np->nagios_exit( UNKNOWN, "Could not retrieve page" ); + # Return code: 3; output: PAGESIZE UNKNOWN - Could not retrieve page + test_page($page) + or $np->nagios_exit( CRITICAL, "Bad page found" ); + + # nagios_die() is just like nagios_exit(), but return code defaults to UNKNOWN + $page = retrieve_page($page2) + or $np->nagios_die( "Could not retrieve page" ); + # Return code: 3; output: PAGESIZE UNKNOWN - Could not retrieve page + + # Threshold methods (NOT YET IMPLEMENTED - use Nagios::Plugin::Threshold for now) + $code = $np->check_threshold( + check => $value, + warning => $warning_threshold, + critical => $critical_threshold, + ); + $np->nagios_exit( $code, "Threshold check failed" ) if $code != OK; + + # Message methods (EXPERIMENTAL AND SUBJECT TO CHANGE) - + # add_message( CODE, $message ); check_messages() + for (@collection) { + if (m/Error/) { + $np->add_message( CRITICAL, $_ ); + } else { + $np->add_message( OK, $_ ); + } + } + ($code, $message) = $np->check_message(); + nagios_exit( $code, $message ); + # If any items in collection matched m/Error/, returns CRITICAL and the joined + # set of Error messages; otherwise returns OK and the joined set of ok messages + + # Perfdata methods + $np->add_perfdata( + label => "size", + value => $value, + uom => "kB", + threshold => $threshold, ); - $p->add_perfdata( label => "time", ... ); + $np->add_perfdata( label => "time", ... ); + $np->nagios_exit( OK, "page size at http://... was ${value}kB" ); + # Return code: 0; output: + # PAGESIZE OK - page size at http://... was 36kB | size=36kB;10:25;25: time=... + + # Option handling methods (NOT YET IMPLEMENTED - use Nagios::Plugin::Getopt for now) + - $p->die( return_code => $threshold->get_status($value), message => "page size at http://... was ${value}kB" ); - # Output: PAGESIZE OK: page size at http://... was 36kB | size=36kB;10:25;25: time=... - # Return code: 0 =head1 DESCRIPTION -This is the place for common routines when writing Nagios plugins. The idea is to make it as -easy as possible for developers to conform to the plugin guidelines +Nagios::Plugin and its associated Nagios::Plugin::* modules are a family of perl modules +to streamline writing Nagios plugins. The main end user modules are Nagios::Plugin, +providing an object-oriented interface to the entire Nagios::Plugin::* collection, and +Nagios::Plugin::Functions, providing a simpler functional interface to a useful subset of +the available functionality. + +The purpose of the collection is to make it as simple as possible for developers to +create plugins that conform the Nagios Plugin guidelines (http://nagiosplug.sourceforge.net/developer-guidelines.html). -=head1 EXAMPLE SCRIPT -"Enough talk! Show me where to start!" +=head2 EXPORTS -See the file 'check_stuff.pl' in the 't' directory for a complete working example of a plugin script. +Nagios status code constants are exported by default: -=head1 DESIGN + OK + WARNING + CRITICAL + UNKNOWN + DEPENDENT -To facilitate object oriented classes, there are multiple perl modules, each reflecting a type of data -(ie, thresholds, ranges, performance). However, a plugin developer does not need to know about the -different types - a "use Nagios::Plugin" should be sufficient. +The following variables are also exported on request: -There is a Nagios::Plugin::Export. This holds all internals variables. You can specify these variables -when use'ing Nagios::Plugin +=over 4 - use Nagios::Plugin qw(%ERRORS) - print $ERRORS{WARNING} # prints 1 +=item %ERRORS -=head1 VERSIONING +A hash mapping error strings ("CRITICAL", "UNKNOWN", etc.) to the corresponding +status code. -Only methods listed in the documentation for each module is public. +=item %STATUS_TEXT -These modules are experimental and so the interfaces may change up until Nagios::Plugin -hits version 1.0, but every attempt will be made to make backwards compatible. +A hash mapping status code constants (OK, WARNING, CRITICAL, etc.) to the +corresponding error string ("OK", "WARNING, "CRITICAL", etc.) i.e. the reverse +of %ERRORS. -=head1 STARTING +=back + + +=head2 CONSTRUCTOR + + Nagios::Plugin->new; + + Nagios::Plugin->new( shortname => 'PAGESIZE' ); + +Instantiates a new Nagios::Plugin object. Accepts the following named arguments: =over 4 -=item use Nagios::Plugin qw(%ERRORS) +=item shortname -Imports the %ERRORS hash. This is currently the only symbol that can be imported. +The 'shortname' for this plugin, used as the first token in the plugin output +by the various exit methods. Default: uc basename $0. =back -=head1 CLASS METHODS + +=head2 EXIT METHODS =over 4 -=item Nagios::Plugin->new( shortname => $$ ) +=item nagios_exit( , $message ) + +Exit with return code CODE, and a standard nagios message of the +form "SHORTNAME CODE - $message". + +=item nagios_die( $message, [] ) + +Same as nagios_exit(), except that CODE is optional, defaulting +to UNKNOWN. + +=item die( $message, [] ) + +Alias for nagios_die(). Deprecated. -Initializes a new Nagios::Plugin object. Can specify the shortname here. +=back + + +=head2 THRESHOLD METHODS + +NOT YET IMPLEMENTED - use Nagios::Plugin::Threshold directly for now. + +=over 4 + +=item check_threshold( check => $value, warning => $warn, critical => $crit ) =back -=head1 OBJECT METHODS + +=head2 MESSAGE METHODS + +EXPERIMENTAL AND SUBJECT TO CHANGE + +add_messages and check_messages are higher-level convenience methods to add +and then check a set of messages, returning an appropriate return code and/or +result message. =over 4 -=item set_thresholds( warning => "10:25", critical => "~:25" ) +=item add_message( , $message ) -Sets the thresholds, based on the range specification at -http://nagiosplug.sourceforge.net/developer-guidelines.html#THRESHOLDFORMAT. -Returns a Nagios::Plugin::Threshold object, which can be used to input a value to see which threshold -is crossed. +Add a message with CODE status to the object. May be called multiple times. The messages +added are checked by check_messages, following. + +Only CRITICAL, WARNING, and OK are accepted as valid codes. -=item add_perfdata( label => "size", value => $value, uom => "kB", threshold => $threshold ) -Adds to an array a Nagios::Plugin::Performance object with the specified values. +=item check_messages() -This needs to be done separately to allow multiple perfdata output. +Check the current set of messages and return an appropriate nagios return code and/or a +result message. In scalar context, returns only a return code; in list context returns +both a return code and an output message, suitable for passing directly to nagios_exit() +e.g. -=item die( return_code => $ERRORS{CRITICAL}, message => "Output" ) + $code = $np->check_messages; + ($code, $message) = $np->check_messages; -Exits the plugin and prints to STDOUT a Nagios plugin compatible output. Exits with the specified -return code. Also prints performance data if any have been added in. +check_messages returns CRITICAL if any critical messages are found, WARNING if any +warning messages are found, and OK otherwise. The message returned in list context defaults +to the joined set of error messages; this may be customised using the arguments below. + +check_messages accepts the following named arguments (none are required): + +=over 4 + +=item join => SCALAR + +A string used to join the relevant array to generate the message +string returned in list context i.e. if the 'critical' array @crit +is non-empty, check_messages would return: + + join( $join, @crit ) + +as the result message. Default: ' ' (space). + +=item join_all => SCALAR + +By default, only one set of messages are joined and returned in the +result message i.e. if the result is CRITICAL, only the 'critical' +messages are included in the result; if WARNING, only the 'warning' +messages are included; if OK, the 'ok' messages are included (if +supplied) i.e. the default is to return an 'errors-only' type +message. + +If join_all is supplied, however, it will be used as a string to +join the resultant critical, warning, and ok messages together i.e. +all messages are joined and returned. + +=item critical => ARRAYREF + +Additional critical messages to supplement any passed in via add_message(). + +=item warning => ARRAYREF + +Additional warning messages to supplement any passed in via add_message(). + +=item ok => ARRAYREF | SCALAR + +Additional ok messages to supplement any passed in via add_message(). + +=back =back + +=head2 PERFORMANCE DATA METHODS + +=over 4 + +=item add_perfdata( label => "size", value => $value, uom => "kB", threshold => $threshold ) + +Add a set of performance data to the object. May be called multiple times. The performance +data is included in the standard plugin output messages by the various exit methods. + +See the Nagios::Plugin::Performance documentation for more information on performance data +and the various field definitions, as well as the relevant section of the Nagios Plugin +guidelines (http://nagiosplug.sourceforge.net/developer-guidelines.html#AEN202). + +=back + + +=head2 OPTION HANDLING METHODS + +NOT YET IMPLEMENTED - use Nagios::Plugin::Getopt directly for now. + + +=head1 EXAMPLES + +"Enough talk! Show me some examples!" + +See the file 'check_stuff.pl' in the 't' directory for a complete working example of a +plugin script. + + +=head1 VERSIONING + +The Nagios::Plugin::* modules are currently experimental and so the interfaces may +change up until Nagios::Plugin hits version 1.0, although every attempt will be made to +keep them as backwards compatible as possible. + + =head1 SEE ALSO -http://nagiosplug.sourceforge.net +See Nagios::Plugin::Functions for a simple functional interface to a subset +of the available Nagios::Plugin functionality. + +See also Nagios::Plugin::Getopt, Nagios::Plugin::Range, Nagios::Plugin::Performance, +Nagios::Plugin::Range, and Nagios::Plugin::Threshold. + +The Nagios Plugin project page is at http://nagiosplug.sourceforge.net. + + +=head1 BUGS + +Please report bugs in these modules to the Nagios Plugin development team: +nagiosplug-devel@lists.sourceforge.net. + =head1 AUTHOR -Maintained by the Nagios Plugin development team - http://nagiosplug.sourceforge.net +Maintained by the Nagios Plugin development team - http://nagiosplug.sourceforge.net. -Originally by Ton Voon, Eton.voon@altinity.comE +Originally by Ton Voon, Eton.voon@altinity.comE. Nathan Vonnahme added extra tests and subsequent fixes. -Gavin Carr contributed the Nagios::Plugin::GetOpt module. + =head1 COPYRIGHT AND LICENSE diff --git a/lib/Nagios/Plugin/Functions.pm b/lib/Nagios/Plugin/Functions.pm index 9c20288..e77bc4f 100644 --- a/lib/Nagios/Plugin/Functions.pm +++ b/lib/Nagios/Plugin/Functions.pm @@ -14,7 +14,7 @@ our @STATUS_CODES = qw(OK WARNING CRITICAL UNKNOWN DEPENDENT); require Exporter; our @ISA = qw(Exporter); our @EXPORT = (@STATUS_CODES, qw(nagios_exit nagios_die check_messages)); -our @EXPORT_OK = qw(%ERRORS %STATUS_TEXT); +our @EXPORT_OK = qw(%ERRORS %STATUS_TEXT @STATUS_CODES); our %EXPORT_TAGS = ( all => [ @EXPORT, @EXPORT_OK ], codes => [ @STATUS_CODES ], @@ -28,7 +28,7 @@ use constant UNKNOWN => 3; use constant DEPENDENT => 4; our %ERRORS = ( - 'OK' => OK, + 'OK' => OK, 'WARNING' => WARNING, 'CRITICAL' => CRITICAL, 'UNKNOWN' => UNKNOWN, @@ -84,7 +84,8 @@ sub nagios_exit { $output = "$shortname $output" if $shortname; if ($arg->{plugin}) { my $plugin = $arg->{plugin}; - $output .= " | ". $plugin->all_perfoutput if $plugin->perfdata; + $output .= " | ". $plugin->all_perfoutput + if $plugin->perfdata && $plugin->all_perfoutput; } $output .= "\n"; @@ -193,7 +194,7 @@ Nagios plugins. # Constants OK, WARNING, CRITICAL, and UNKNOWN exported by default use Nagios::Plugin::Functions; - # nagios_exit( ODE, $message ) - exit with error code CODE, + # nagios_exit( CODE, $message ) - exit with error code CODE, # and message "PLUGIN CODE - $message" nagios_exit( CRITICAL, $critical_error ) if $critical_error; nagios_exit( WARNING, $warning_error ) if $warning_error; @@ -223,7 +224,7 @@ Nagios::Plugin. It is intended for those who prefer a simpler functional interface, and who do not need the additional functionality of Nagios::Plugin. -=head2 Exports +=head2 EXPORTS Nagios status code constants are exported by default: @@ -245,13 +246,13 @@ The following variables are exported only on request: %STATUS_TEXT -=head2 Functions +=head2 FUNCTIONS The following functions are supported: =over 4 -=item nagios_exit( CODE, $message ) +=item nagios_exit( , $message ) Exit with return code CODE, and a standard nagios message of the form "PLUGIN CODE - $message". diff --git a/t/Nagios-Plugin-Functions-02.t b/t/Nagios-Plugin-Functions-02.t index 981e2eb..1a9351b 100644 --- a/t/Nagios-Plugin-Functions-02.t +++ b/t/Nagios-Plugin-Functions-02.t @@ -1,7 +1,7 @@ # check_messages tests use strict; -use Test::More tests => 33; +use Test::More tests => 37; BEGIN { use_ok("Nagios::Plugin::Functions", ":all") } @@ -160,3 +160,19 @@ is($message, $msg_all_wo, "join_all '$join_all' (critical, warning, \$ok) messag is($code, WARNING, "(warning) code is $STATUS_TEXT{$code}"); is($message, 'D E F', "join_all '$join_all' (critical, warning) message is $message"); +# ------------------------------------------------------------------------- +# Error cases + +# Test failures without required fields +ok(! defined eval { ($code, $message) = check_messages() }, + "check_messages dies without message args"); + +ok(! defined eval { ($code, $message) = check_messages(warning => $arrays{warning}) }, + "check_messages dies without 'critical' message"); + +ok(! defined eval { ($code, $message) = check_messages(critical => $arrays{critical}) }, + "check_messages dies without 'warning' message"); + +ok(defined eval { ($code, $message) = check_messages(critical => $arrays{critical}, warning => $arrays{warning}) }, + "check_messages ok with 'critical' and 'warning' messages"); + -- cgit v0.10-9-g596f