commit 417003304aa9635608b89d27fdc3bbb68ad42fa5733a720ab511a479684dac30 Author: Lars Vogdt Date: Thu Aug 15 09:46:23 2024 +0000 - check_iostat: report as critical and as "stuck" if read and write are at 0 and util is at 100 percent OBS-URL: https://build.opensuse.org/package/show/server:monitoring/monitoring-plugins-sar-perf?expand=0&rev=40 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9b03811 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,23 @@ +## Default LFS +*.7z filter=lfs diff=lfs merge=lfs -text +*.bsp filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.gem filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.jar filter=lfs diff=lfs merge=lfs -text +*.lz filter=lfs diff=lfs merge=lfs -text +*.lzma filter=lfs diff=lfs merge=lfs -text +*.obscpio filter=lfs diff=lfs merge=lfs -text +*.oxt filter=lfs diff=lfs merge=lfs -text +*.pdf filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text +*.rpm filter=lfs diff=lfs merge=lfs -text +*.tbz filter=lfs diff=lfs merge=lfs -text +*.tbz2 filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.ttf filter=lfs diff=lfs merge=lfs -text +*.txz filter=lfs diff=lfs merge=lfs -text +*.whl filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57affb6 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.osc diff --git a/check_iostat b/check_iostat new file mode 100644 index 0000000..df08bc9 --- /dev/null +++ b/check_iostat @@ -0,0 +1,260 @@ +#!/usr/bin/perl + +# +# Version 0.0.2 - Jan/2009 +# Changes: added device verification +# +# by Thiago Varela - thiago@iplenix.com + +# Version 0.1 - Nov/2011 +# by Ruediger Oertel ro@suse.de +# Changes: +# - rewrite in perl, no need for external grep, awk, bc +# - add output for iowait +# - implement using device mapper names, e.g. $vg-$lv + +use strict; +use Getopt::Std; + +$Getopt::Std::STANDARD_HELP_VERSION = "true"; + +my $iostat = `which iostat 2>/dev/null`; +chomp($iostat); + +my $progname = $0; + + +# call it VERSION_MESSAGE so that getopts uses it automatically +sub VERSION_MESSAGE { + print "$progname: version 0.1, Nov/2011\n"; +} + +# call it HELP_MESSAGE so that getopts uses it automatically +sub HELP_MESSAGE { + print "\n\tThis plugin shows the I/O usage of the specified disk, using the iostat external program.\n"; + print "\tIt prints three statistics: Transactions per second (tps), Kilobytes per second\n"; + print "read from the disk (KB_read/s) and and written to the disk (KB_written/s)\n\n"; + print "$progname:\n\t-d \t\tDevice to be checked (without the full path, eg. sda)\n"; + print "\t\t\t\t(also accepted are device mapper names)\n"; + print "\t-c ,,\tSets the CRITICAL level for tps, KB_read/s and KB_written/s, respectively\n"; + print "\t-w ,,\tSets the WARNING level for tps, KB_read/s and KB_written/s, respectively\n"; + print "\t-C \t Sets the CRITICAL level for iowait\n"; + print "\t-W \t Sets the WARNING level for iowait\n"; + print "\t-X \t Sets the CRITICAL level for utilization\n"; + print "\t-Y \t Sets the WARNING level for utilization\n"; + print "\t\t\t(if no level is set for iowait, no warning is set for this value)\n"; + exit 1; +} + +unless ($iostat && -f $iostat) { + warn "ERROR: You must have iostat installed in order to run this plugin\n"; + exit 1; +} + +# Getting parameters: +my %opts; +getopts('d:w:c:W:C:X:Y:hv', \%opts); + +my $disk = $opts{'d'}; +my $warning = $opts{'w'}; +my $critical = $opts{'c'}; +my $warn_iowait = $opts{'W'}; +my $crit_iowait = $opts{'C'}; +my $warn_util = $opts{'X'}; +my $crit_util = $opts{'Y'}; + +VERSION_MESSAGE() if $opts{'v'}; +HELP_MESSAGE() if $opts{'h'}; + +# Adjusting the three warn and crit levels: +my ($crit_tps,$crit_read,$crit_written) = split(',',$critical); +my ($warn_tps,$warn_read,$warn_written) = split(',',$warning); + +# Checking parameters: +if (-d "$disk") { + # directory specified ... + my $mp = `stat --format '\%m' $disk`; + chomp($mp); + my $fstype = `stat --file-system --format '\%T' $mp`; + chomp($fstype); + if ($fstype eq "tmpfs") { + print "OK - $disk (mountpoint $mp is tmpfs)\n"; + exit 0; + } + open(MOUNTS,"/proc/mounts"); + while() { + chomp($_); + my @line = split('\s+',$_); + $disk = $line[0] if $mp eq $line[1]; + } + close(MOUNTS); +} + +$disk =~ s/^\/dev\/mapper\///; +$disk =~ s/^\/dev\///; + +if (! -b "/dev/$disk") { + if (-b "/dev/mapper/$disk") { + my @f = stat("/dev/mapper/$disk"); + $f[6] %= 256; + $disk = "dm-$f[6]"; + } else { + warn "ERROR: Device incorrectly specified\n"; + HELP_MESSAGE(); + } +} + +unless ($warn_tps && $warn_read && $warn_written && $crit_tps && $crit_read && $crit_written) { + warn "ERROR: You must specify all warning and critical levels\n"; + HELP_MESSAGE(); +} + +if ($warn_tps > $crit_tps || $warn_read > $crit_read || $warn_written > $crit_written) { + warn "ERROR: critical levels must be highter than warning levels\n"; + HELP_MESSAGE(); +} + +if ($warn_iowait && $crit_iowait && $warn_iowait > $crit_iowait) { + warn "ERROR: critical iowait level must be higher than warning level\n"; + HELP_MESSAGE(); +} + +if ($warn_util && $crit_util && $warn_util > $crit_util) { + warn "ERROR: critical utilization level must be higher than warning level\n"; + HELP_MESSAGE(); +} + +my ($tps,$rps,$wps,$kbread,$kbwritten,$iowait,$util); +my $seen_usage = 0; +my $seen_disk = 0; +my $field_rps = 3; +my $field_wps = 4; +my $field_rmbps = 5; +my $field_wmbps = 6; +my $field_util = 13; + +# Doing the actual check: +open (IOSTAT,"-|","$iostat -kx $disk 5 2"); +while () { + chomp(); + if (/^[0-9\.\ \t]+$/) { + $seen_usage++; + next if $seen_usage < 2; + my (@stats) = split ('\s+', $_); + $iowait = $stats[4]; + next; + } + if (/^Device/) { + my @hdrs = split('\s+', $_); + my ($search_rps) = grep { $hdrs[$_] eq "r/s" } 0..$#hdrs; + $field_rps = $search_rps if $search_rps; + my ($search_wps) = grep { $hdrs[$_] eq "w/s" } 0..$#hdrs; + $field_wps = $search_wps if $search_wps; + my ($search_rmbps) = grep { $hdrs[$_] eq "rkB/s" } 0..$#hdrs; + $field_rmbps = $search_rmbps if $search_rmbps; + my ($search_wmbps) = grep { $hdrs[$_] eq "wkB/s" } 0..$#hdrs; + $field_wmbps = $search_wmbps if $search_wmbps; + my ($search_util) = grep { $hdrs[$_] eq "%util" } 0..$#hdrs; + $field_util = $search_util if $search_util; + next; + } + if (/^$disk /) { + $seen_disk++; + next if $seen_disk < 2; + my (@stats) = split ('\s+', $_); + ($rps,$wps,$kbread,$kbwritten,$util) = @stats[$field_rps,$field_wps,$field_rmbps,$field_wmbps,$field_util]; + $tps = $rps + $wps; + last; + } +} +close (IOSTAT); + +my $msg = "OK"; +my $status = 0; +my %reasons; + +# Comparing the result and setting the correct level: +if ($tps >= $warn_tps || $kbread >= $warn_read || $kbwritten >= $warn_written) { + $msg = "WARNING"; + $reasons{'throughput'} = 1; + $status = 1; +} + +if ($warn_iowait && $iowait >= $warn_iowait) { + $msg = "WARNING"; + $reasons{'iowait'} = 1; + $status = 1; +} + +if ($warn_util && $util >= $warn_util) { + $msg = "WARNING"; + $reasons{'util'} = 1; + $status = 1; +} + +if ($tps >= $crit_tps || $kbread >= $crit_read || $kbwritten >= $crit_written) { + $msg = "CRITICAL"; + $reasons{'throughput'} = 2; + $status = 2; +} + +if ($crit_iowait && $iowait >= $crit_iowait) { + $msg = "CRITICAL"; + $reasons{'iowait'} = 2; + $status = 2; +} + +if ($crit_util && $util >= $crit_util) { + $msg = "CRITICAL"; + $reasons{'util'} = 2; + $status = 2; +} + +if ($util == 100 && $kbread == 0 && $kbwritten == 0) { + $msg = "CRITICAL"; + $reasons{'stuck'} = 2; + $status = 2; +} + +$msg .= " (".join(",",keys(%reasons)).")" if $status != 0; + +my $p_tps = $tps; +if ($warn_tps) { + $p_tps .= ";$warn_tps"; + if ($crit_tps) { + $p_tps .= ";$crit_tps"; + } +} +my $p_kbread = $kbread; +if ($warn_read) { + $p_kbread .= ";$warn_read"; + if ($crit_read) { + $p_kbread .= ";$crit_read"; + } +} +my $p_kbwritten = $kbwritten; +if($warn_written) { + $p_kbwritten .= ";$warn_written"; + if ($crit_written) { + $p_kbwritten .= ";$crit_written"; + } +} +my $p_iowait = $iowait; +if ($warn_iowait) { + $p_iowait .= ";$warn_iowait"; + if ($crit_iowait) { + $p_iowait .= ";$crit_iowait"; + } +} +my $p_util = $util; +if ($warn_util) { + $p_util .= ";$warn_util"; + if ($crit_util) { + $p_util .= ";$crit_util"; + } +} +# Printing the results: +print "$msg - I/O stats tps=$tps KB_read/s=$kbread KB_written/s=$kbwritten iowait=$iowait util=$util | 'tps'=$p_tps; 'KB_read/s'=$p_kbread; 'KB_written/s'=$p_kbwritten; 'iowait'=$p_iowait; 'util'=$p_util\n"; + +# Bye! +exit $status; diff --git a/monitoring-plugins-sar-perf-output.patch b/monitoring-plugins-sar-perf-output.patch new file mode 100644 index 0000000..8b9adcd --- /dev/null +++ b/monitoring-plugins-sar-perf-output.patch @@ -0,0 +1,14 @@ +Index: check_sar_perf.py +=================================================================== +--- check_sar_perf.py.orig ++++ check_sar_perf.py +@@ -99,7 +99,8 @@ class SarNRPE: + # Create dictionary + for i in range(len(columns)): + # Remove first column if data contains only letters +- if i != 0 or not search.match(data[i]): ++ #if i != 0 or not search.match(data[i]): ++ if (i != 0 or not search.match(data[i])) and (columns[i] != "DEV"): + # Remove characters that cause issues (%/) + badchars=['%','/'] + columns[i] = ''.join(j for j in columns[i] if j not in badchars) diff --git a/monitoring-plugins-sar-perf-stdout.patch b/monitoring-plugins-sar-perf-stdout.patch new file mode 100644 index 0000000..c07023b --- /dev/null +++ b/monitoring-plugins-sar-perf-stdout.patch @@ -0,0 +1,19 @@ +Index: check_sar_perf.py +=================================================================== +--- check_sar_perf.py.orig ++++ check_sar_perf.py +@@ -153,11 +153,12 @@ def Main(args): + else: + sar = SarNRPE(myOpts[args[1]]) + else: +- print 'ERROR: option not defined' ++ print 'ERROR: option ',args[1],' not defined' + sys.exit(ERR_UNKN) + + # Output in NRPE format +- print 'sar OK|', ' '.join(sar.stats) ++ args[0]='' ++ print 'sar OK: ',' '.join(args),'|', ' '.join(sar.stats) + + if __name__ == '__main__': + Main(sys.argv) diff --git a/monitoring-plugins-sar-perf.changes b/monitoring-plugins-sar-perf.changes new file mode 100644 index 0000000..80c696d --- /dev/null +++ b/monitoring-plugins-sar-perf.changes @@ -0,0 +1,163 @@ +------------------------------------------------------------------- +Wed Jul 24 12:24:59 CEST 2024 - ro@suse.de + +- check_iostat: report as critical and as "stuck" if read and + write are at 0 and util is at 100 percent + +------------------------------------------------------------------- +Fri Feb 23 08:37:18 UTC 2024 - pgajdos@suse.com + +- Use %autosetup macro. Allows to eliminate the usage of deprecated + %patchN + +------------------------------------------------------------------- +Thu Apr 22 12:25:03 UTC 2021 - Lars Vogdt + +- include abstractions/bash in apparmor profile - otherwise + the 'which iostat' command fails +- reload the apparmor profile in postun to make the changes effective + +------------------------------------------------------------------- +Tue Jul 28 14:03:05 CEST 2020 - ro@suse.de + +- update apparmor profile again to allow reading + /sys/devices/**/stat + +------------------------------------------------------------------- +Tue Jul 07 15:29:46 UTC 2020 - lars@linux-schulserver.de + +- update AppArmor profiles to include a comment why the check + needs to read nsswitch.conf and passwd + +------------------------------------------------------------------- +Sun May 31 13:31:20 UTC 2020 - Christian Boltz + +- update AppArmor profile to allow reading /etc/nsswitch.conf and /etc/passwd + +------------------------------------------------------------------- +Fri Mar 13 00:42:48 CET 2020 - ro@suse.de + +- update apparmor profile usr.lib.nagios.plugins.check_iostat + to allow reading / and /proc/$pid/mountinfo + +------------------------------------------------------------------- +Fri Feb 28 15:41:17 CET 2020 - ro@suse.de + +- check_iostat: add reasons why state is warning or critical + to the output + +------------------------------------------------------------------- +Wed Dec 11 18:10:48 CET 2019 - ro@suse.de + +- check_iostat: sanitize dev name to properly match iostat output + +------------------------------------------------------------------- +Thu Dec 5 16:34:19 CET 2019 - ro@suse.de + +- check_iostat: exit with OK if running on tmpfs +- check_iostat: fix apparmor profile to allow stat call + +------------------------------------------------------------------- +Thu Dec 5 14:40:38 CET 2019 - ro@suse.de + +- check_iostat: allow to just specify a directory + +------------------------------------------------------------------- +Sun Apr 14 16:06:32 UTC 2019 - Christian Boltz + +- update AppArmor profile for usrMerge (bash) (boo#1132350) + +------------------------------------------------------------------- +Tue Apr 10 11:08:51 CEST 2018 - ro@suse.de + +- check_iostat: fix to work with iostat on sle15 + +------------------------------------------------------------------- +Wed Nov 15 12:52:11 CET 2017 - ro@suse.de + +- check_iostat: get field numbers from iostat dynamically + by parsing header line (r/s and w/s fields move between versions) + +------------------------------------------------------------------- +Tue Nov 14 17:27:19 CET 2017 - ro@suse.de + +- check_iostat: pass warning and critical level to perfdata +- use iostat fields r/s and w/s for tps calculation + +------------------------------------------------------------------- +Mon Apr 24 12:33:08 CEST 2017 - ro@suse.de + +- use -x for iostat and add utilization monitoring + +------------------------------------------------------------------- +Fri Oct 30 15:01:40 UTC 2015 - lars@linux-schulserver.de + +- switch to BSD-2-Clause as the script is more likely released + under this license + +------------------------------------------------------------------- +Sat Aug 1 19:14:27 UTC 2015 - lars@linux-schulserver.de + +- add apparmor profile for check_iostat +- recommend apparmor-profiles (needed for apparmor profile, but as + the check itself runs without apparmor, we use a week dependency) + +------------------------------------------------------------------- +Wed Jul 30 19:20:45 UTC 2014 - lars@linux-schulserver.de + +- Renamed package to monitoring-plugins-sar-perf + +------------------------------------------------------------------- +Fri Nov 9 16:57:05 CET 2012 - ro@suse.de + +- check_iostat: use 5 seconds instead of 2 to get more useful data + +------------------------------------------------------------------- +Mon Nov 28 14:26:57 CET 2011 - ro@suse.de + +- check_iostat: add warning and critical levels for iowait + +------------------------------------------------------------------- +Sat Nov 26 19:41:38 CET 2011 - ro@suse.de + +- check_iostat: actually check current io stats, not since boot + +------------------------------------------------------------------- +Sat Nov 26 00:59:35 CET 2011 - ro@suse.de + +- more additions to check_iostat: can use device-mapper name + +------------------------------------------------------------------- +Fri Nov 25 12:51:48 CET 2011 - ro@suse.de + +- rewrite check_iostat in perl, also output iowait value + +------------------------------------------------------------------- +Fri Nov 25 10:51:16 CET 2011 - ro@suse.de + +- add requires sysstat +- check_iostat: call iostat with "-k" to really display kb + instead of blocks as unit + +------------------------------------------------------------------- +Thu Nov 24 16:26:58 UTC 2011 - lars@linux-schulserver.de + +- added check_iostat + +------------------------------------------------------------------- +Tue Oct 4 15:27:09 UTC 2011 - lars@linux-schulserver.de + +- also print the used arguments as output to STDOUT, so the user + knows what is mesured (monitoring-plugins-sar-perf-stdout.patch) + +------------------------------------------------------------------- +Tue Oct 4 12:59:33 UTC 2011 - lars@linux-schulserver.de + +- added monitoring-plugins-sar-perf-output.patch : + do not print DEV name for disk in performance output + +------------------------------------------------------------------- +Sun Jul 24 10:05:07 UTC 2011 - lars@linux-schulserver.de + +- initial version (git commit 4878d0cc66e928bd1075) defined as 0.1 + diff --git a/monitoring-plugins-sar-perf.spec b/monitoring-plugins-sar-perf.spec new file mode 100644 index 0000000..55e21f6 --- /dev/null +++ b/monitoring-plugins-sar-perf.spec @@ -0,0 +1,90 @@ +# +# spec file for package monitoring-plugins-sar-perf +# +# Copyright (c) 2024 SUSE LLC +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via https://bugs.opensuse.org/ +# + + +Name: monitoring-plugins-sar-perf +Summary: Get performance data from sar +License: BSD-2-Clause +Group: System/Monitoring +Version: 0.1 +Release: 0 +URL: https://github.com/nickanderson/check-sar-perf +Source0: nickanderson-check-sar-perf-4878d0c.tar.gz +Source1: check_iostat +Source2: usr.lib.nagios.plugins.check_iostat +Patch0: monitoring-plugins-sar-perf-output.patch +Patch1: monitoring-plugins-sar-perf-stdout.patch +BuildRequires: nagios-rpm-macros +%if 0%{?suse_version} +Recommends: apparmor-profiles +%endif +Provides: nagios-plugins-sar-perf = %{version}-%{release} +Obsoletes: nagios-plugins-sar-perf < %{version}-%{release} +Requires: python +Requires: sysstat +BuildArch: noarch +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +%description +This plug-in was written to get performance data from sar. It was developed for +use with Zenoss but should work with other NRPE compatible NMS. + +Example output: + +check_sar_perf cpu +sar OK| CPU=all user=59.90 nice=0.00 system=4.46 iowait=0.00 steal=0.00 + idle=35.64 + +check_sar_perf disk sda +sar OK| DEV=sda tps=0.00 rd_sec/s=0.00 wr_sec/s=0.00 avgrq-sz=0.00 + avgqu-sz=0.00 await=0.00 svctm=0.00 util=0.00 + +%prep +%autosetup -p0 -n nickanderson-check-sar-perf-4878d0c + +%build + +%install +install -D -m755 check_sar_perf.py %{buildroot}/%{nagios_plugindir}/check_sar_perf +install -m755 %{SOURCE1} %{buildroot}/%{nagios_plugindir}/check_iostat +install -Dm0644 %{SOURCE2} %{buildroot}/%{_sysconfdir}/apparmor.d/usr.lib.nagios.plugins.check_iostat + +%postun +if [ "$YAST_IS_RUNNING" != "instsys" ]; then + if [ -x /sbin/apparmor_parser ]; then + if /usr/bin/systemctl is-active --quiet apparmor.service; then + /sbin/apparmor_parser -r -T -W %{_sysconfdir}/apparmor.d/usr.lib.nagios.plugins.check_iostat &> /dev/null || : + fi + else + echo "Could not reload the Apparmor profile: /sbin/apparmor_parser is missing or not executable." + fi +fi + +%clean +rm -rf %{buildroot} + +%files +%defattr(-,root,root) +# avoid build dependecy of nagios - own the dirs +%dir %{nagios_libdir} +%dir %{nagios_plugindir} +%dir %{_sysconfdir}/apparmor.d +%{nagios_plugindir}/check_sar_perf +%{nagios_plugindir}/check_iostat +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/apparmor.d/usr.lib.nagios.plugins.check_iostat + +%changelog diff --git a/nickanderson-check-sar-perf-4878d0c.tar.gz b/nickanderson-check-sar-perf-4878d0c.tar.gz new file mode 100644 index 0000000..b911c79 --- /dev/null +++ b/nickanderson-check-sar-perf-4878d0c.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4c76642e2dfc208fe0e699f6fdc55231d9839f2bfd55cb6371c63cf5ad8be5ed +size 3308 diff --git a/usr.lib.nagios.plugins.check_iostat b/usr.lib.nagios.plugins.check_iostat new file mode 100644 index 0000000..d603469 --- /dev/null +++ b/usr.lib.nagios.plugins.check_iostat @@ -0,0 +1,25 @@ +#include +/usr/lib/nagios/plugins/check_iostat { + #include + #include + #include + #include + /usr/bin/iostat rix, + /{usr/,}bin/bash rix, + /{usr/,}bin/stat rix, + /usr/bin/which rix, + /sys/devices/system/cpu/ r, + /sys/devices/**/stat r, + /proc/meminfo r, + @{PROC}/[0-9]*/mounts r, + @{PROC}/[0-9]*/mountinfo r, + /proc/diskstats r, + /proc/uptime r, + / r, + /etc/sysstat/sysstat.ioconf r, + # once the service tries to lookup which user is + # invoking the programm, it needs access to the + # following files + /etc/nsswitch.conf r, + /etc/passwd r, +}