Page 1 of 2

Trying to Use Arguments in Script

Posted: Fri Jan 31, 2014 12:28 pm
by omar
I’m still trying to get the hand of Nagios. Thankfully, this forum has been really helpful in research. Unfortunately my issue is probably so basic, that I cannot find many information on my particular issue.

When it comes, to arguments, I understand that they must be declared in define command, and can be defined in define service.
Like the following:

Code: Select all

define command{
   command_name      WeatherGooseII.pl
   command_line      $USER1$/WeatherGooseII.pl –H $HOSTADDRESS$ c- $ARG1$ w- $ARG2$ s- $ARG3$
}

define service{
        use                         generic-service
        host_name              localhost
        description              Check Calculus Temperature 
        check_command      WeatherGooseII.pl!90!75!TempC
        }
(Hopefully the –s applies to $ARG3$) My question is how would I implement those arguments into my script. Would I just use $ARG1$ in my script to get the defined values for I can use to compare in order to return a Status. I have successfully been able to get my script to work, hardcoding values, but I know things can be easier if I can understand how to implement the arguments into my script.

I provided a sample of my script, commenting where I hardcoded by values, to show what I am trying to do.

Code: Select all

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use XML::Simple;


sub read_xml {
    my $file = shift;
    my $xml       = XML::Simple->new();
    my $data  = XMLin( $file );
    return $data;
}


my $xml = read_xml( '/var/www/html/data.xml' );

my $fieldTempC = "TempC";  //hardcoded TempC

my $tempCValue = $xml->{'devices'}->{'device'}->{'field'}->{'TempC'}->{'value'};  //hardcoded TempC

if($tempCValue >= 90)  //hardcoded critical value
{
      print "CRITICAL: ", $fieldTempC, " is at or above 90";
      print "Current Value: ", $tempCValue;
   
      exit 2;
}
   
elsif($tempCValue >= 75)  //hardcoded warning value
{      
print "WARNING: ", $fieldTempC, " is nearing the max temperature of 75";
      print "Current Value: ", $tempCValue;
   }   
exit 1;
}

elsif ($tempCValue < 75)     //hardcoded TempC and warning value
{
   print $fieldTempC, " is OK";
   exit 0;
}

else
{
   print "Unknown arguments\n";
   print $tempCValue;
   exit 3;
}

Re: Trying to Use Arguments in Script

Posted: Fri Jan 31, 2014 12:40 pm
by tmcdonald

Code: Select all

define command{
   command_name      WeatherGooseII.pl
   command_line      $USER1$/WeatherGooseII.pl –H $HOSTADDRESS$ c- $ARG1$ w- $ARG2$ s- $ARG3$
}
First I want to make sure that you meant "-c" "-w" and "-s" and that you typoed in your post.

And second, welcome to the world of Perl! It's ugly but it gets the job done.

You will want to look into getopts, which is how most plugins will handle flags:

http://alvinalexander.com/perl/perl-get ... gs-in-perl

You could just skip the flags altogether and stick to a "use the first argument for this variable, the second argument for this variable" etc etc, and then you just have to put the values in the right order, but getopts is much cleaner and more extendable.

Re: Trying to Use Arguments in Script

Posted: Fri Jan 31, 2014 12:51 pm
by omar
tmcdonald wrote: First I want to make sure that you meant "-c" "-w" and "-s" and that you typoed in your post.
yes, Im sorry, I meant - w, -c, and -s... My mistake on that

From the numerous code and articles I have read -c means critical levels. I believe, since I established $ARG1$ with - c in define command, and set it to 90 in define service, I'm hoping it means that when I compare whatever value my device is getting me to $ARG1$, that based on my coding, it will see that as a critical and to send a status exit(2) to display a critical warning in the Nagios Web Interface. I'm hoping the same for the -w with $ARG2$ but instead of a sending a critical status, it will send a warning status (exit(1)) if my device value is at or above 75 (The value I set for it in define service)

Im not quite sure about -s though... Based on many syntax I have read, I beleive it means that I am hoping to send the string "TempC" through as an argument.

Re: Trying to Use Arguments in Script

Posted: Fri Jan 31, 2014 12:57 pm
by tmcdonald
Well the beautiful thing about writing your own plugin is that you can have it do whatever you want!

The standard by and large for -w and -c is correct: warn and crit. -s has been used for many things, but yes it is usually for a user-defined string or service (in the case of WMI or the like).

Re: Trying to Use Arguments in Script

Posted: Fri Jan 31, 2014 2:11 pm
by omar
I'm starting to think, passing arguments from define service to the script doesn't require any special macros or Nagio-specific coding, but just basic perl coding

Re: Trying to Use Arguments in Script

Posted: Fri Jan 31, 2014 2:13 pm
by tmcdonald
omar wrote:I'm starting to think, passing arguments from define service to the script doesn't require any special macros or Nagio-specific coding, but just basic perl coding
Correct. Nagios macros will have no meaning within a plugin. You need to pull them in using something like getopts or $ARGV[1] etc.

Re: Trying to Use Arguments in Script

Posted: Fri Jan 31, 2014 2:33 pm
by omar
I get you now (hopefully)... So $ARG1$, $ARG2$, etc can be called in script using $ARGV[x].

So using the coding above...

I would use

Code: Select all

my $field = $ARGV[2];  //since I'm trying to get TempC, and Temp C was $ARG3$ in define service
So would the script already know to put the values from define service (in this case 90, 75, and TempC) as $ARGV[0], $ARGV[1], and $ARGV[2] or would I have to declare it as such in the script:

Code: Select all

my @ARGV[] = ( $ARG1, $ARG2$, $ARG3 );

Re: Trying to Use Arguments in Script

Posted: Fri Jan 31, 2014 2:42 pm
by tmcdonald
omar wrote: So would the script already know to put the values from define service (in this case 90, 75, and TempC) as $ARGV[0], $ARGV[1], and $ARGV[2] or would I have to declare it as such in the script:

Code: Select all

my @ARGV[] = ( $ARG1, $ARG2$, $ARG3 );
perl has no idea what those Nagios macros $ARG1$, $ARG2$, and $ARG3$ are. perl has no idea what Nagios is. As far as perl knows, it is alone in the system and only knows what you tell it. When you run

./perlscript.pl hello world

$ARGV[0] is 'hello' and $ARGV[1] is 'world'. When Nagios runs the check it will do the substitution of its own macros and run something like:

./perlscript.pl -w 20 -c 10 -s someString

and then the perl script will understand that $ARGV[0] is '-w', $ARGV[1] is '20' etc etc

Remember that we start counting from 0 when programming.

Re: Trying to Use Arguments in Script

Posted: Fri Jan 31, 2014 2:52 pm
by omar
yeah I know that when it comes to arrays, the first element is 0, hence why I put $ARG3$ (TempC) as $ARGV[2]. Since $ARG1$ would be $ARGV[0] and $ARG2$ would be $ARGV[1].

Well since Nagios can definitely see and the script due to the define command in the .cfg files in Nagios libexec folder, I am assuming now I have to figure out a way to get the script to recognize those values defined in define service ?

(by the way, I decided to take your advice and do away with -c, -w, etc and used straight up $ARG1$)

Re: Trying to Use Arguments in Script

Posted: Fri Jan 31, 2014 3:04 pm
by tmcdonald
If you have a command definition like this:

Code: Select all

define command {
    command_name    check_goose
    command_line    $USER1$/check_weathergoose.pl $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$
}
and you have a service definition like this (truncated to just interesting parts):

Code: Select all

define service {
    check_command    check_goose!20!10!TempC
}
then within the perl script, you will have the following values:

Code: Select all

$ARGV[0] == IP address you want to check
$ARGV[1] == 20
$ARGV[2] == 10
$ARGV[3] == TempC
In your check_command line, whatever comes after the first "!" is $ARG1$ (a Nagios macro). So the effective call then becomes

Code: Select all

./check_weathergoose.pl 192.168.1.100 20 10 TempC
obviously with the IP you choose.