EVOLUTION-MANAGER
Edit File: check_updates
#!/usr/bin/perl eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' if 0; # not running under some shell # nagios: -epn package main; # check_updates is a Nagios plugin to check if RedHat or Fedora system # is up-to-date # # See the INSTALL file for installation instructions # # Copyright (c) 2007-2018, Matteo Corti # # This module is free software; you can redistribute it and/or modify it # under the terms of GNU general public license (gpl) version 3, # or (at your option) any later version. # See the COPYING file for details. use 5.00800; use strict; use warnings; no warnings 'once'; ## no critic (TestingAndDebugging::ProhibitNoWarnings) our $VERSION = '1.6.23'; use Carp; use English qw(-no_match_vars); use POSIX qw(uname); use Readonly; my $plugin_module = load_module( 'Monitoring::Plugin', 'Nagios::Plugin' ); my $plugin_threshold_module = load_module( 'Monitoring::Plugin::Threshold', 'Nagios::Plugin::Threshold' ); my $plugin_getopt_module = load_module( 'Monitoring::Plugin::Getopt', 'Nagios::Plugin::Getopt' ); # Check which version of the monitoring plugins is available sub load_module { my @names = @_; my $loaded_module; for my $name (@names) { my $file = $name; # requires need either a bare word or a file name $file =~ s{::}{/}gsxm; $file .= '.pm'; eval { ## no critic (ErrorHandling::RequireCheckingReturnValueOfEval) require $file; $name->import(); }; if ( !$EVAL_ERROR ) { $loaded_module = $name; last; } } if ( !$loaded_module ) { #<<< print 'CHECK_UPDATES: plugin not found: ' . join( ', ', @names ) . "\n"; ## no critic (RequireCheckedSyscall) #>>> exit 2; } return $loaded_module; } Readonly our $EXIT_UNKNOWN => 3; Readonly our $YUM_RETURN_ERROR => 1; Readonly our $YUM_RETURN_UPDATES_AVAILABLE => 100; Readonly our $BITS_PER_BYTE => 8; # IMPORTANT: Nagios plugins could be executed using embedded perl in this case # the main routine would be executed as a subroutine and all the # declared subroutines would therefore be inner subroutines # This will cause all the global lexical variables not to stay shared # in the subroutines! # # All variables are therefore declared as package variables... # ## no critic (ProhibitPackageVars) use vars qw( $bootcheck $exit_message $help $options $plugin $security_plugin $status $threshold $wrong_kernel $yum_executable @status_lines ); ## use critic ############################################################################## # Usage : verbose("some message string", $optional_verbosity_level); # Purpose : write a message if the verbosity level is high enough # Returns : n/a # Arguments : message : message string # level : options verbosity level # Throws : n/a # Comments : n/a # See also : n/a sub verbose { # arguments my $message = shift; my $level = shift; if ( !defined $message ) { exit_with_error( $plugin_module->UNKNOWN, q{Internal error: not enough parameters for 'verbose'} ); } if ( !defined $level ) { $level = 0; } # we check if options is defined as the it could be undefined if # running from a unit test if ( defined $options && $level < $options->verbose ) { #<<< print $message; ## no critic (RequireCheckedSyscalls) #>>> } return; } ############################################################################## # Usage : debug("some message string"); # Purpose : write a debugging message # Returns : n/a # Arguments : message : message string # Throws : n/a # Comments : n/a # See also : n/a sub debug { # arguments my $message = shift; if ( !defined $message ) { exit_with_error( $plugin_module->UNKNOWN, q{Internal error: not enough parameters for 'debug'} ); } if ( defined $options && $options->get('debug') ) { print "[DBG] $message"; ## no critic (RequireCheckedSyscalls) } return; } ############################################################################## # Usage : exit_with_error( $status, $message) # Purpose : if a plugin object is available exits via ->nagios_exit # otherwise prints to the shell and exit normally # Returns : n/a # Arguments : n/a # Throws : n/a # Comments : n/a # See also : n/a sub exit_with_error { my $status = shift; my $message = shift; if ($plugin) { $plugin->nagios_exit( $status, $message ); } else { #<<< print "Error: $message"; ## no critic (RequireCheckedSyscalls) #>>> exit $status; } return; } ############################################################################## # Usage : get_path('program_name'); # Purpose : retrieves the path of an executable file using the # 'which' utility # Returns : the path of the program (if found) # Arguments : the program name # Throws : n/a # Comments : n/a # See also : n/a sub get_path { my $prog = shift; my $path; my $which_command = "which $prog"; my $which_output; verbose "Executing 'which $prog'\n", 2; #<<< open $which_output, q{-|}, "$which_command 2>&1" or $plugin->nagios_exit( $plugin->UNKNOWN, "Cannot execute $which_command: $OS_ERROR" ); while (<$which_output>) { verbose $_, 2; chomp; if ( !/^which:/mxs ) { $path = $_; } } if ( !( close $which_output ) && ( $OS_ERROR != 0 ) ) { # close to a piped open return false if the command with non-zero # status. In this case $! is set to 0 $plugin->nagios_exit( $plugin->UNKNOWN, "Error while closing pipe to $which_command: $OS_ERROR" ); } #>>> return $path; } # the script is declared as a package so that it can be unit tested # but it should not be used as a module if ( !caller ) { run(); } ############################################################################## # Usage : whoami() # Purpose : retrieve the user runnging the process # Returns : username # Arguments : n/a # Throws : n/a # Comments : n/a # See also : n/a sub whoami { my $output; my $pid = open $output, q{-|}, 'whoami' or exit_with_error( $plugin_module->UNKNOWN, "Cannot determine the user: $OS_ERROR" ); while (<$output>) { chomp; return $_; } if ( !( close $output ) && ( $OS_ERROR != 0 ) ) { # close to a piped open return false if the command with non-zero # status. In this case $! is set to 0 exit_with_error( $plugin_module->UNKNOWN, "Error while closing pipe to whoami: $OS_ERROR\n" ); } exit_with_error( $plugin_module->UNKNOWN, 'Cannot determine the user' ); return; } ############################################################################## # Usage : versioncmp # Purpose : Sort revision-like numbers # Returns : -1, 0, or 1 depending on whether the left argument is less than, # equal to, or greater than the right argument. # Arguments : Globally defined $a and $b as the versions to compare # Throws : n/a # Comments : Included (and adapted) from Sort::Version to remove the # dependency on Sort::Version which is not available per default # on RH systems # See also : Sort::Version on CPAN sub versioncmp { my @A = ( $a =~ /([-.]|\d+|[^-.\d]+)/gxms ); my @B = ( $b =~ /([-.]|\d+|[^-.\d]+)/gxms ); my ( $A, $B ); while ( @A and @B ) { $A = shift @A; $B = shift @B; ## no critic (ProhibitCascadingIfElse) if ( $A eq q{-} and $B eq q{-} ) { next; } elsif ( $A eq q{-} ) { return -1; ## no critic (ProhibitMagicNumbers) } elsif ( $B eq q{-} ) { return 1; } elsif ( $A eq q{.} and $B eq q{.} ) { next; } elsif ( $A eq q{.} ) { return -1; ## no critic (ProhibitMagicNumbers) } elsif ( $B eq q{.} ) { return 1; } elsif ( $A =~ /^\d+$/xms and $B =~ /^\d+$/xms ) { if ( $A =~ /^0/xms || $B =~ /^0/xms ) { return $A cmp $B if $A cmp $B; } else { return $A <=> $B if $A <=> $B; } } else { $A = uc $A; $B = uc $B; return $A cmp $B if $A cmp $B; } ## use critic (ProhibitCascadingIfElse) } return @A <=> @B; } ############################################################################## # Usage : $kernel_version = clean_kernel_version( $kernel_version ) # Purpose : removes everything but the version number from the kernel # version (e.g., PAE, xen, ...) # Returns : kernel version # Arguments : kernel_version : output of uname # Throws : n/a # Comments : n/a # See also : n/a sub clean_kernel_version { my $kernel = shift; # remove PAE $kernel =~ s/[.][\w]*PAE//imxs; $kernel =~ s/PAE-//imxs; # remove core $kernel =~ s/core-//imxs; # remove Xen $kernel =~ s/xen-//imxs; # remove openvz $kernel =~ s/o?vzkernel-//imxs; # remove architecture $kernel =~ s/[.](i[3-6]86|ppc|x86_64)$//mxs; # remove smp $kernel =~ s/smp$//mxs; $kernel =~ s/smp-//imxs; # remove RHEL, CentOS, Scientific Linux and Fedora flavours $kernel =~ s/[.]el\d+.*//imxs; $kernel =~ s/[.]fc\d+.*//imxs; # remove UEK $kernel =~ s/uek-//imxs; # remove ml-aufs, lt-aufs $kernel =~ s/ml-aufs-//imxs; $kernel =~ s/lt-aufs-//imxs; return $kernel; } ############################################################################## # Usage : check_running_kernel( ); # Purpose : checks if the loaded kernel is the latest available # Returns : n/a # Arguments : n/a # Throws : n/a # Comments : n/a # See also : n/a sub check_running_kernel { # return if running in openvz client: /proc/vz is always present but # /proc/bc only exists on node, but not inside container. if ( -d '/proc/vz' && !( -d '/proc/bc' ) ) { return; } if ( !$bootcheck ) { return; } my $package = 'kernel'; ################################################################################ # Running my ( $sysname, $nodename, $release, $version, $machine ) = POSIX::uname(); $release = clean_kernel_version($release); verbose "running a Linux kernel: $release\n"; ################################################################################ # Installed my @versions; for my $rpm ( ( "$package", "$package-smp", "$package-PAE", "$package-xen", "$package-uek", 'ovzkernel', 'vzkernel', "$package-PAE-core", "$package-ml-aufs", "$package-lt-aufs", "$package-core", ) ) { my $output; #<<< my $pid = open $output, q{-|}, "rpm -q $rpm" ## no critic (RequireBriefOpen) or exit_with_error( $plugin_module->UNKNOWN, "Cannot list installed kernels: $OS_ERROR" ); #>>> # there could be multiple versions of the same package installed my @rpm_versions; while (<$output>) { chomp; push @rpm_versions, $_; } if ( !( close $output ) && ( $OS_ERROR != 0 ) ) { # close to a piped open return false if the command with non-zero # status. In this case $! is set to 0 exit_with_error( $plugin_module->UNKNOWN, "Error while closing pipe to rpm: $OS_ERROR\n" ); } if ( $CHILD_ERROR == 0 ) { # rpm exits with 0 only it the RPM exists push @versions, @rpm_versions; } } for (@versions) { # strip package name s/^$package-//mxs; $_ = clean_kernel_version($_); } @versions = sort versioncmp @versions; my $installed = $versions[-1]; if ( !$installed ) { $plugin->nagios_exit( $plugin->UNKNOWN, 'Unable to detect installed kernel' ); } verbose "kernel: running = $release, installed = $installed\n"; if ( $installed ne $release ) { my $error = "your machine is running kernel $release but a newer version ($installed) is installed: you should reboot"; if ($exit_message) { $exit_message .= $error; } else { $exit_message = $error; } $wrong_kernel = 1; } return; } ############################################################################## # Usage : run_yum(); # Purpose : runs yum check-update with the supplied command line argumens # Returns : the list of updates # Arguments : string with the command line arguments # : (optional) yum command # Throws : n/a # Comments : n/a # See also : n/a sub run_yum { my $arguments = shift; my $yum_command = shift; # per default check updates if ( !defined $yum_command ) { $yum_command = 'check-update'; } my $blank_line; my $OUTPUT_HANDLER; my @updates; my $command = "$yum_executable $yum_command $arguments"; debug qq{Running "$command"\n}, 1; #<<< my $pid = open $OUTPUT_HANDLER, q{-|}, $command ## no critic (RequireBriefOpen) or exit_with_error( $plugin_module->UNKNOWN, "Cannot list updates: $OS_ERROR" ); #>>> while (<$OUTPUT_HANDLER>) { my $line = $_; debug $line; chomp $line; if ( !$line ) { $blank_line = 1; next; } if ($blank_line) { # some lines are wrapped and result and the second part # is erroneously interpreted as a new update if ( $line =~ m/^[ ]/mxs ) { next; } # The obsoleted packages are already listed if ( $line =~ /^Obsoleting/imxs ) { last; } # After and including "Uploading Enabled Repositories Report" the output can be ignored if ( $line =~ /^Uploading\ Enabled\ Repositories\ Report/imxs ) { last; } $line =~ s{[ ].*}{}mxs; push @updates, $line; } } if ( !( close $OUTPUT_HANDLER ) && ( $OS_ERROR != 0 ) ) { # close to a piped open return false if the command with non-zero # status. In this case $! is set to 0 exit_with_error( $plugin_module->UNKNOWN, "Error while closing pipe to rpm: $OS_ERROR\n" ); } if ( ( $CHILD_ERROR >> $BITS_PER_BYTE ) == $YUM_RETURN_UPDATES_AVAILABLE ) { if ($security_plugin) { verbose "Security updates available\n"; } else { verbose "Updates available\n"; } } elsif ( ( $CHILD_ERROR >> $BITS_PER_BYTE ) == $YUM_RETURN_ERROR ) { exit_with_error( $plugin_module->UNKNOWN, "Error while executing '$command'\n" ); } return @updates; } ############################################################################## # Usage : check_security_option # Purpose : checks if you supports --security (in older versions required # a plugin) # Returns : 1 if --security is supported, undef otherwise # Arguments : n/a # Throws : n/a # Comments : n/a # See also : n/a sub check_security_option { my $OUTPUT_HANDLER; verbose "Checking if YUM/DNF supports the --security option\n", 2; if ( $yum_executable =~ /dnf$/mxs ) { verbose "Using DNF: no security plugin necessary\n", 2; $security_plugin = 1; } else { my $pid = open $OUTPUT_HANDLER, q{-|}, "$yum_executable --help | grep -q -- --security" or exit_with_error( $plugin_module->UNKNOWN, "Cannot check for security option: $OS_ERROR" ); if ( !( close $OUTPUT_HANDLER ) && ( $OS_ERROR != 0 ) ) { # close to a piped open return false if the command with non-zero # status. In this case $! is set to 0 exit_with_error( $plugin_module->UNKNOWN, "Error while closing pipe to rpm: $OS_ERROR\n" ); } if ( $CHILD_ERROR == 0 ) { verbose "Using YUM: security plugin installed\n", 1; $security_plugin = 1; } else { verbose "Using YUM and security plugin not installed: all updates will be considered security updates\n" ,; } } return; } ############################################################################## # Usage : check_yum(); # Purpose : checks a yum based system for updates # Returns : n/a # Arguments : string with the command line arguments # Throws : n/a # Comments : n/a # See also : n/a ## no critic (ProhibitExcessComplexity) sub check_yum { my $arguments = shift; my $message; check_security_option(); if ( $options->get('clean') ) { verbose 'Cleaning YUM/DNF caches'; run_yum( '-q', 'clean all' ); } my @outdated = run_yum($arguments); my @security_updates; $plugin->add_perfdata( label => 'total_updates', value => scalar @outdated, uom => q{}, threshold => $threshold, ); if ( @outdated > 0 ) { if ( !$security_plugin ) { if ( $options->get('security-only') ) { verbose "up2date does not distinguish security updates ignoring --security-only option\n"; } # every update is critical since it could be a security problem verbose "no security plugin: every update could be a security problem\n"; $status = $plugin_module->CRITICAL; verbose "DNF/YUM reports a non-up-to-date system\n"; $message = ( scalar @outdated ) . ' update'; if ( @outdated > 1 ) { $message = $message . q{s}; } $message = $message . ' available'; @status_lines = @outdated; } else { if ( @outdated >= $options->get('warning') ) { $status = $plugin_module->WARNING; } if ( @outdated >= $options->get('critical') ) { $status = $plugin_module->CRITICAL; } if ( $options->get('security-only') ) { # ignore any other update $status = $plugin_module->OK; } # --security generates a message on STDERR if no security update is present @security_updates = run_yum( $arguments . ' --security 2> /dev/null' ); if ( @security_updates > 0 ) { $status = $plugin_module->CRITICAL; $message = ( scalar @security_updates ) . ' security update'; if ( @security_updates > 1 ) { $message = $message . q{s}; } # compute the array difference my %count; for my $element (@security_updates) { push @status_lines, "$element (security)"; $count{$element}++; } for my $element (@outdated) { $count{$element}++; } my @difference; for my $element (@outdated) { if ( $count{$element} == 1 ) { push @difference, $element; } } @outdated = @difference; } if ( @outdated > 0 ) { if ($message) { $message .= ' and '; } $message .= ( scalar @outdated ) . ' non-security update'; if ( @outdated > 1 ) { $message = $message . q{s}; } push @status_lines, @outdated; } if ($message) { $message .= ' available'; } } } else { $status = $plugin_module->OK; $message = 'no updates available'; } if ($security_plugin) { $plugin->add_perfdata( label => 'security_updates', value => scalar @security_updates, uom => q{}, threshold => $threshold, ); } if ($exit_message) { $exit_message .= q{, } . $message; } else { $exit_message = $message; } return; } ## use critic (ProhibitExcessComplexity) ############################################################################## # Usage : check_up2date(); # Purpose : checks an up2date based system for updates # Returns : n/a # Arguments : n/a # Throws : n/a # Comments : n/a # See also : n/a sub check_up2date { if ( $options->get('clean') ) { verbose 'clean not supported with up2date'; } # parsing the output of up2date -l if ( whoami() ne 'root' ) { exit_with_error( $plugin_module->CRITICAL, q{must be root to execute 'up2date -l': use sudo} ); } my $output; my $command = q{/usr/sbin/up2date -lf | /bin/grep -A 64 -- '----------------------------------------------------------' | /bin/grep '[[:alpha:]]'}; my $pid = open $output, q{-|}, $command ## no critic (RequireBriefOpen) or exit_with_error( $plugin_module->UNKNOWN, "Cannot list updates: $OS_ERROR" ); while (<$output>) { chomp; my $line = $_; $line =~ s/[ ].*//mxs; push @status_lines, $line; } if ( !( close $output ) && ( $OS_ERROR != 0 ) ) { # close to a piped open return false if the command with non-zero # status. In this case $! is set to 0 exit_with_error( $plugin_module->UNKNOWN, "Error while closing pipe to dnf/yum (listing updates): $OS_ERROR\n" ); } my $message; if ( @status_lines > 0 ) { $message = ( scalar @status_lines ) . ' update'; if ( @status_lines >= $options->get('warning') ) { $status = $plugin_module->WARNING; } if ( @status_lines >= $options->get('critical') ) { $status = $plugin_module->CRITICAL; } if ( @status_lines > 1 ) { $message = $message . q{s}; } $message = $message . ' available'; $plugin->add_perfdata( label => 'updates', value => scalar @status_lines, uom => q{}, threshold => $threshold, ); } else { $message = 'no updates available'; $plugin->add_perfdata( label => 'updates', value => 0, uom => q{}, threshold => $threshold, ); } if ($exit_message) { $exit_message .= " $message"; } else { $exit_message = $message; } return; } ############################################################################## # Usage : my $system = get_os_name_and_version(); # Purpose : returns the name of the system by parsing $VERSION_FILE # Returns : name of the system # Arguments : n/a # Throws : CRITICAL if not able to read $VERSION_FILE # Comments : n/a # See also : n/a sub get_os_name_and_version { my $filename = shift; if ( !$filename ) { if ( -r '/etc/system-release' ) { $filename = '/etc/system-release'; } elsif ( -r '/etc/redhat-release' ) { $filename = '/etc/redhat-release'; } else { exit_with_error( $plugin_module->UNKNOWN, 'Cannot detect Linux distribution' ); } } my $header; if ( -r $filename ) { my $TMP; open $TMP, q{<}, $filename or exit_with_error( $plugin_module->CRITICAL, "Error opening $filename: $OS_ERROR" ); while (<$TMP>) { chomp; $header = $_; last; } close $TMP or exit_with_error( $plugin_module->CRITICAL, "Error closing $filename: $OS_ERROR" ); } else { exit_with_error( $plugin_module->UNKNOWN, "Cannot detect Linux distribution (no $filename file)" ); } return $header; } ############################################################################## # Usage : my $updater = get_updated() # Purpose : returns the name of updating system (yum or up2date) # Returns : name of updating system or undef if not found # Arguments : n/a # Throws : n/a # Comments : n/a # See also : n/a sub get_updater { my $name = shift; if ( $name =~ /Fedora/mxs || $name =~ /CentOS/mxs || $name =~ /PUIAS/mxs || $name =~ /CloudLinux/mxs || $name =~ /Scientific[ ]Linux/mxs || $name =~ /Red[ ]Hat.*[ ][567]/mxs || $name =~ /Oracle/mxs || $name =~ /Amazon/mxs ) { return 'yum'; } elsif ( $name =~ /Red[ ]Hat.*[ ]4/mxs ) { return 'up2date'; } return; } ############################################################################## # Usage : run(); # Purpose : main method # Returns : n/a # Arguments : n/a # Throws : n/a # Comments : n/a # See also : n/a sub run { $status = $plugin_module->OK; ############################################################################## # main # ################ # initialization $help = q{}; $bootcheck = 1; $wrong_kernel = 0; $plugin = $plugin_module->new( shortname => 'CHECK_UPDATES' ); ######################## # Command line arguments $options = $plugin_getopt_module->new( usage => 'Usage: %s [OPTIONS]', version => $VERSION, url => 'https://github.com/matteocorti/check_updates', blurb => 'Checks if RedHat or Fedora system is up-to-date', ); $options->arg( spec => 'boot-check', help => 'Check if the machine was booted with the newest kernel (default)', ); $options->arg( spec => 'boot-check-warning', help => 'Like --boot-check but state is warning instead of critical', ); $options->arg( spec => 'debug|d', help => 'Enables debugging messages', ); $options->arg( spec => 'no-boot-check', help => 'Do not complain if the machine was booted with an old kernel', ); $options->arg( spec => 'clean', help => 'Cleans YUM/DNF caches', ); $options->arg( spec => 'warning|w=i', help => 'Exit with WARNING status if more than INTEGER non-security updates are available', default => 0 ); $options->arg( spec => 'critical|c=i', help => 'Exit with CRITICAL status if more than INTEGER non-security updates are available', default => 0 ); $options->arg( spec => 'security-only', help => 'Ignores non-security updates', ); $options->arg( spec => 'yum-arguments|a=s', help => 'specific Yum arguments as STRING', ); $options->getopts(); ############### # Sanity checks if ( $options->get('warning') > $options->get('critical') ) { exit_with_error( $plugin_module->UNKNOWN, q{'critical' (} . $options->get('critical') . q{) must not be lower than 'warning' (} . $options->get('warning') . q{)} ); } $threshold = $plugin_threshold_module->set_thresholds( warning => $options->get('warning'), critical => $options->get('critical'), ); # check bootcheck consistency if ( $options->get('boot-check') && $options->get('no-boot-check') ) { exit_with_error( $plugin_module->CRITICAL, 'Error --boot-check and --no-boot-check specified at the same time' ); } if ( $options->get('boot-check-warning') && $options->get('no-boot-check') ) { exit_with_error( $plugin_module->CRITICAL, 'Error --boot-check-warning and --no-boot-check specified at the same time' ); } if ( $options->get('no-boot-check') ) { $bootcheck = 0; } if ( $options->get('boot-check-warning') ) { $bootcheck = 2; } ############ # YUM or DNF if ( !defined $yum_executable ) { verbose 'Searching for DNF or YUM in ' . $ENV{'PATH'} . "\n", 1; # the yum executable is not mandated by the tests $yum_executable = get_path('dnf'); if ( !defined $yum_executable ) { $yum_executable = get_path('yum'); } } if ( !defined $yum_executable ) { exit_with_error( $plugin_module->UNKNOWN, "Cannot find DNF or YUM\n" ); } ######### # Arguments my $arguments = q{}; if ( $options->get('yum-arguments') ) { $arguments = $options->get('yum-arguments'); } ######### # Timeout alarm $options->timeout; verbose "Checking a $OSNAME system\n"; if ( $OSNAME eq 'linux' ) { my $name = get_os_name_and_version(); verbose "Running on $name\n"; my $updater = get_updater($name); if ( $updater eq 'yum' ) { verbose "Using Yum\n"; check_running_kernel(); check_yum($arguments); } elsif ( $updater eq 'up2date' ) { verbose "Using up2date\n"; if ( $options->get('security-only') ) { verbose "up2date does not distinguish security updates ignoring --security-only option\n"; } check_running_kernel(); check_up2date(); } else { exit_with_error( $plugin_module->UNKNOWN, 'unknown Linux distribution' ); } if ( $bootcheck == 2 && $wrong_kernel ) { $status = $plugin_module->WARNING; } elsif ( $bootcheck && $wrong_kernel ) { $status = $plugin_module->CRITICAL; } # Monitoring::Plugin does not support the addition Nagios 3 status lines # -> we do it manually eval { ## no critic (ErrorHandling::RequireCheckingReturnValueOfEval) ## no critic (Modules::RequireBarewordIncludes) require 'Monitoring/Plugin.pm'; ## use critic (Modules::RequireBarewordIncludes) Monitoring::Plugin->import(); }; if ( !$EVAL_ERROR ) { #<<< print 'CHECK_UPDATES ' ## no critic (RequireCheckedSyscalls) . $Monitoring::Plugin::STATUS_TEXT{$status} . " - $exit_message |"; #>>> } else { #<<< print 'CHECK_UPDATES ' ## no critic (RequireCheckedSyscalls) . $Nagios::Plugin::STATUS_TEXT{$status} . " - $exit_message |"; #>>> } for my $pdata ( @{ $plugin->perfdata } ) { #<<< print q{ } . $pdata->perfoutput; ## no critic (RequireCheckedSyscalls) #>>> } #<<< print "\n"; ## no critic (RequireCheckedSyscalls) #>>> for my $package (@status_lines) { #<<< print "$package\n"; ## no critic (RequireCheckedSyscalls) #>>> } exit $status; } else { exit_with_error( $plugin_module->UNKNOWN, 'Cannot detect Linux system' ); } return; } 1;