2 # Check_MK Agent for AIX
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
27 # force load of environment
28 if [ -e $HOME/.profile ]
30 . $HOME/.profile >/dev/null 2>&1
33 # Remove locale settings to eliminate localized outputs where possible
37 export MK_LIBDIR=${MK_LIBDIR:-/usr/check_mk/lib}
38 export MK_CONFDIR=${MK_CONFDIR:-/usr/check_mk/conf}
39 export MK_VARDIR=${MK_VARDIR:-/tmp/check_mk}
41 # Optionally set a tempdir for all subsequent calls
44 # All executables in PLUGINSDIR will simply be executed and their
45 # ouput appended to the output of the agent. Plugins define their own
46 # sections and must output headers with '<<<' and '>>>'
47 PLUGINSDIR=$MK_LIBDIR/plugins
49 # All executables in LOCALDIR will by executabled and their
50 # output inserted into the section <<<local>>>. Please refer
51 # to online documentation for details.
52 LOCALDIR=$MK_LIBDIR/local
54 # All files in SPOOLDIR will simply appended to the agent
55 # output if they are not outdated (see below)
56 SPOOLDIR=$MK_VARDIR/spool
58 #Avoid problems with wrong decimal separators in other language verions of aix
59 export LC_NUMERIC="en_US"
61 # close standard input (for security reasons) and stderr
69 # Shell version of the waitmax utility, that limits the runtime of
70 # commands. This version does not conserve the original exit code
71 # of the command. It is successfull if the command terminated
79 # Run command in background
83 # Wait for termination within TIMOUT seconds
84 while [ $TIMEOUT -gt 0 ]
86 TIMEOUT=$((TIMEOUT - 1))
87 if [ ! -e /proc/$PID ] ; then
90 perl -e "select(undef, undef, undef, 0.1);"
93 # Process did not terminate in time. Kill and
94 # return with an error
101 # Be aware: Maxage was expected to be given in minutes but this was
102 # confusing because all other agents use seconds here. So this has
103 # been changed to be compatible.
108 if [ ! -e $MK_VARDIR/cache ] ; then mkdir -p $MK_VARDIR/cache ; fi
109 CACHE_FILE=$MK_VARDIR/cache/$NAME.cache
112 # Check if file exists and is recent enough
113 if [ -s $CACHE_FILE ]
115 MTIME=$(/usr/bin/perl -e 'if (! -f $ARGV[0]){die "0000000"};$mtime=(stat($ARGV[0]))[9];print ($^T-$mtime);' $CACHE_FILE )
116 if (( $MTIME < $MAXAGE )) ; then
120 if [ -s "$CACHE_FILE" ]
124 if [ -z "$USE_CACHE_FILE" -a ! -e "$CACHE_FILE.new" ]
126 nohup sh -c $CMDLINE > $CACHE_FILE.new 2> /dev/null && mv $CACHE_FILE.new $CACHE_FILE &
130 echo "<<<check_mk>>>"
131 echo "Version: 1.6.0i1"
133 echo "Hostname: $(hostname)"
134 echo "AgentDirectory: $MK_CONFDIR"
135 echo "DataDirectory: $MK_VARDIR"
136 echo "SpoolDirectory: $SPOOLDIR"
137 echo "PluginsDirectory: $PLUGINSDIR"
138 echo "LocalDirectory: $LOCALDIR"
141 if [ -x /usr/opt/freeware/bin/df ] ; then
142 excludefs="-x smbfs -x cifs -x iso9660 -x udf -x nfsv4 -x nfs -x mvfs -x zfs -x cdrfs"
143 # shellcheck disable=SC2086
144 /usr/opt/freeware/bin/df -PTlk $excludefs | sed 1d
146 # df inodes information
148 echo '[df_inodes_start]'
149 # shellcheck disable=SC2086
150 /usr/opt/freeware/bin/df -PTli $excludefs | sed 1d
151 echo '[df_inodes_end]'
153 df -kP | sed 's/ / - /' | grep -v ^/proc | grep -v ^Filesystem | grep -v :
156 # Check for hanging NFS mounts. This needs a GNU stat installed in the PATH
157 if type stat >/dev/null 2>&1 ; then
158 echo '<<<nfsmounts>>>'
159 mount | grep ' nfs' | awk '{print $3;}' | \
162 waitmax 5 stat -f -c '"'$MP' ok - - - -"' "$MP" || \
163 echo "$MP hanging 0 0 0 0"
165 echo '<<<cifsmounts>>>'
166 mount | grep ' cifs' | awk '{print $3;}' | \
169 if [ ! -r $MP ]; then
170 echo "$MP Permission denied"
172 waitmax 2 stat -f -c '"'$MP' ok - - - -"' "$MP" || \
173 echo "$MP hanging 0 0 0 0"
179 ps -ef -F user,vszsize,rssize,pcpu,args | sed -e 1d -e 's/ *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) */(\1,\2,\3,\4) /'
181 if type lparstat >/dev/null 2>&1
183 echo '<<<lparstat_aix>>>'
187 echo '<<<vmstat_aix>>>'
190 echo '<<<aix_diskiod>>>'
191 iostat -d | tr -s ' ' | grep hdisk
193 echo '<<<aix_memory>>>'
194 vmstat -v | tr -s ' '
197 echo '<<<mpstat_aix>>>'
200 # CPU output of Linux agent simulated
201 # (thanks to Cameron Pierce)
203 load=`uptime|sed -e 's;.*average: \([[:digit:]]\{1,\}\.[[:digit:]]\{1,\}\), \([[:digit:]]\{1,\}\.[[:digit:]]\{1,\}\), \([[:digit:]]\{1,\}\.[[:digit:]]\{1,\}\);\1 \2 \3;'`
204 ps=`ps -eo thcount | awk '{SUM+=$1} END {print SUM}'`
205 procs=`vmstat|grep lcpu|sed -e 's;.*lcpu=\([[:digit:]]\{1,4\}\).*;\1;'`
206 echo $load 1/$ps $$ $procs
210 for ent in $(ifconfig -a | grep '^en' | cut -d ":" -f 1)
213 entstat "$ent" | grep -E "(^Hardware|^Bytes:|^Packets:|^Transmit|^Broadcast:|^Multicast:)"
214 entstat "$ent" | grep -p "Driver Flags:"
218 if which ntpq > /dev/null 2>&1 ; then
219 if [ $(lssrc -s xntpd|grep -c active) -gt 0 ] ; then
221 ntpq -np | sed -e 1,2d -e 's/^\(.\)/\1 /' -e 's/^ /%/'
226 echo '<<<aix_multipath>>>'
227 lspath -F"name parent status"
231 # -L disables LVM lock for the query. Avoids blocking while LVM is
232 # doing changes. For rootvg that is fine.
236 echo '<<<tcp_conn_stats>>>'
237 netstat -ntfinet | awk ' /^tcp/ { c[$6]++; } END { for (x in c) { print x, c[x]; } }'
239 # Libelle Business Shadow
240 if type trd >/dev/null 2>&1
242 echo '<<<libelle_business_shadow:sep(58)>>>'
246 if [ -x /usr/sbin/sendmail ] ; then
247 echo '<<<postfix_mailq>>>';
248 mailq 2>&1 | tail -n 6
252 # 12:55pm up 105 days, 21 hrs, 2 users, load average: 0.26, 0.26, 0.26 --> 9147600
253 # 1:41pm up 105 days, 21:46, 2 users, load average: 0.28, 0.28, 0.27 --> 9150360
254 # 05:26PM up 1:16, 1 user, load average: 0.33, 0.21, 0.20 --> 4560
255 # 06:13PM up 2:03, 1 user, load average: 1.16, 1.07, 0.91 --> 7380
256 # 08:43AM up 29 mins, 1 user, load average: 0.09, 0.18, 0.21 --> 1740
257 # 08:47AM up 66 days, 18:34, 1 user, load average: 2.25, 2.43, 2.61 --> 5769240
258 # 08:45AM up 76 days, 34 mins, 1 user, load average: 2.25, 2.43, 2.61 --> 5769240
260 UPTIME=$(uptime | sed -e 's/^.*up//g' -e 's/[0-9]* user.*//g')
262 *day* ) DAYS=$(echo $UPTIME | sed -e 's/days\{0,1\},.*//g') ;;
268 HOURS=$(echo $UPTIME | sed -e 's/.*days\{0,1\},//g' -e 's/:.*//g')
269 MINS=$(echo $UPTIME | sed -e 's/.*days\{0,1\},//g' -e 's/.*://g' -e 's/,.*//g') ;;
271 HOURS=$(echo $UPTIME | sed -e 's/hrs\{0,1\},.*//g' -e 's/.*,//g')
275 MINS=$(echo $UPTIME | sed -e 's/mins\{0,1\},.*//g' -e 's/.*hrs\{0,1\},//g' -e 's/.*days\{0,1\},//g') ;;
281 echo $(((DAYS*86400)+(HOURS*3600)+(MINS*60)))
284 if cd $PLUGINSDIR 2>/dev/null
288 if [ -x "$skript" ] ; then
293 # Call some plugins only every X'th second
294 for skript in [1-9]*/* ; do
295 if [ -x "$skript" ] ; then
296 run_cached plugins_${skript//\//\#} ${skript%/*} "$skript"
302 # Fileinfo-Check: put patterns for files into /etc/check_mk/fileinfo.cfg
303 if [ -r "$MK_CONFDIR/fileinfo.cfg" ]; then
304 echo '<<<fileinfo:sep(124)>>>'
309 # let the shell do all the expansion, and pipe all files to perl
310 (cat "$MK_CONFDIR/fileinfo.cfg" "$MK_CONFDIR/fileinfo.d/*" 2>/dev/null) | while read -r pattern; do
312 /*) for f in $pattern; do echo $f; done
317 print "[[[header]]]\n";
318 print "name|status|size|time\n";
319 print "[[[content]]]\n";
324 print "$_|missing\n";
327 ($device, $inode, $mode, $nlink, $uid, $gid, $rdev, $size,
328 $atime, $mtime, $ctime, $blksize, $blocks) = stat($_);
330 print "$_|stat failed\n";
332 print "$_|ok|$size|$mtime\n";
335 set +vx; eval "$old_state"
340 if type lslpp >/dev/null 2>&1
342 cluster_cmd_output=$(lslpp -l cluster.es.server.rte)
343 if ! echo $cluster_cmd_output | grep -q "not installed"
345 # now the following commands should be available
346 nodes=$(cllsnode | grep "NODE" | sed -e s/NODE//g -e s/://g)
350 active_nodes=$(clgetactivenodes -n $node)
351 if echo $active_nodes | grep -q $node
353 list_active_nodes=$list_active_nodes"\n$node"
357 if [ "$list_active_nodes" ]
359 echo '<<<aix_hacmp_nodes>>>'
360 echo -e $list_active_nodes
364 echo '<<<aix_hacmp_services>>>'
365 if type clshowsrv ; then
366 waitmax 5 clshowsrv -v
367 else # fallback, hardcoded base installation path
368 waitmax 5 /usr/es/sbin/cluster/utilities/clshowsrv -v
371 echo '<<<aix_hacmp_resources:sep(58)>>>'
372 waitmax 5 clRGinfo -s
377 if cd $LOCALDIR 2>/dev/null
381 if [ -x "$skript" ] ; then
386 # Call some local checks only every X'th second
387 for skript in [1-9]*/* ; do
388 if [ -x "$skript" ] ; then
389 run_cached local_${skript//\//\#} ${skript%/*} "$skript"
394 # MK's Remote Plugin Executor
395 if [ -e "$MK_CONFDIR/mrpe.cfg" ]
398 grep -Ev '^[[:space:]]*($|#)' "$MK_CONFDIR/mrpe.cfg" | \
399 while read descr cmdline
401 PLUGIN=${cmdline%% *}
402 OUTPUT=$(eval "$cmdline")
403 echo "(${PLUGIN##*/}) $descr $? $OUTPUT" | tr \\n \\1
408 # Agent output snippets created by cronjobs, etc.
409 if [ -d "$SPOOLDIR" ]
411 cd "$SPOOLDIR" > /dev/null
416 # output every file in this directory. If the file is prefixed
417 # with a number, then that number is the maximum age of the
418 # file in seconds. If the file is older than that, it is ignored.
422 # Each away all digits from the front of the filename and
423 # collect them in the variable maxage.
424 while [ "${part/#[0-9]/}" != "$part" ]
426 maxage=$maxage${part:0:1}
430 # If there is at least one digit, than we honor that.
431 if [ "$maxage" ] ; then
432 mtime=$(stat -c %Y "$file")
433 if [ $((now - mtime)) -gt $maxage ] ; then