Compare commits

..

28 Commits

Author SHA1 Message Date
aea7a22b8b Update link 2024-08-03 20:20:33 +02:00
746a674ab2 Set exec 2022-10-26 20:52:01 +02:00
07727979d0 Add exec bit 2022-10-22 23:54:53 +02:00
7a02be87c9 add exec bit 2022-10-22 23:54:26 +02:00
93c66e1d40 add exec bit 2022-10-22 23:53:22 +02:00
570f7534ab Fix README 2022-10-12 20:14:37 +02:00
65f6b4ac06 Fix build script permissions 2022-10-12 20:11:11 +02:00
e77d740adb Add notify_slack plugin 2022-10-12 19:55:09 +02:00
45225e7799 added support for systemd-timesyncd, new force_systemd configuration parameter 2022-02-16 21:10:26 +01:00
f2e52dc4ff Added fix in notify_mail() for different switch to mailx command between Linux distro 2022-02-16 21:03:14 +01:00
Patrick Van der Veken
c8cc6bd89f * Add new plugin: check_hpux_defunct_processes
* Small fixes
2021-04-07 15:59:43 +02:00
Patrick Van der Veken
eec674c972 Fixed bug for check host routine: do not reset HC_TIME_OUT to 60 by default 2021-03-30 17:42:58 +02:00
Patrick Van der Veken
11a888638d make _WAIT_TIME & _CRON_LOG_FILE configurable 2021-03-29 17:50:18 +02:00
a00d68afde Added --comment option for --disable & --disable features. 2021-03-28 20:59:34 +02:00
a807703f61 check_linux_burp_backup(): updated code for changing 'burp -v' option as of burp v2.2 quote fixes 2021-03-28 19:09:50 +02:00
54aeef0c71 Add option to disable the count of log entries in archive logs during the archiving operation (global setting: HC_COUNT_ARCHIVES). Disabling this will speed up archiving. 2021-02-13 22:59:06 +01:00
Patrick Van der Veken
ae20069c8a Merge branch 'master' of https://github.com/patvdv/check_health 2021-02-03 11:43:44 +01:00
Patrick Van der Veken
47484d1e09 Fixes for slot detection & reporting in check_linux_hpacucli & check_linux_hpssacli 2021-02-03 11:43:10 +01:00
41ad3542ab Merge branch 'master' of https://github.com/patvdv/check_health 2021-02-01 21:03:50 +01:00
4e75b3ceb6 Update documentation link 2021-02-01 21:03:22 +01:00
Patrick Van der Veken
c108237765 Comment fix 2021-01-13 10:56:55 +01:00
Patrick Van der Veken
b8d03a150d Fix for wrong logic in check_*_file_change 2021-01-13 10:50:26 +01:00
Patrick Van der Veken
888965a5b2
Create FUNDING.yml 2020-12-27 20:11:47 +01:00
6bbbb8970c * Refactored --archive-all feature so that archiving runs more efficiently (starting with the HC that has most messages in the HC log first, then with the HC that has the second most messages etc)
* show_statistics(): show archived events in proper order
* quoting fixes
2020-12-27 17:11:00 +01:00
04b5e8f8e5 Fixes 2020-12-27 01:05:31 +01:00
835189facf Fix typo 2020-12-26 19:43:08 +01:00
1fd486b036 * Added plugins: check_*_uptim, check_linux_fetchmail_status, check_linux_dovecot_status
* Fixes for check_*_ntp_status plugins.
* Added log check for check_*_postfix plugins.
2020-12-26 17:51:03 +01:00
cc1d9e5c98 Fix issue #9 : do_cleanup() removing plugin stdout & stderr log files when running multiple HC plugins 2020-11-08 22:01:10 +01:00
53 changed files with 3722 additions and 436 deletions

3
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,3 @@
# These are supported funding model platforms
github: patvdv

View File

@ -90,6 +90,7 @@ Additionally, there may be bundles for display or notification plugins, e.g.:
* hc-display-terse
* hc-notify-eif
* hc-notify-sms
* hc-notify-slack
## Configure & deploy
@ -141,13 +142,14 @@ An Ansible role is available at: https://github.com/patvdv/kudos.check_health
* **Alerting** on failed health checks:
```
/opt/hc/bin/check_health.sh --hc=check_hpux_root_crontab --run --notify=mail --mail-to="alert@acme.com"
/opt/hc/bin/check_health.sh --hc=check_linux_fs_usage --run --notify=slack
```
## References
### Documentation
More documentation can be found at http://www.kudos.be/Projects/Health_checker.html
More documentation can be found at <https://www.kudos.be/check_health/>
### Logo

View File

@ -32,12 +32,14 @@ Fileset
/opt/hc/lib/platform/aix/check_aix_subsystems.sh
/opt/hc/lib/platform/aix/check_aix_sysbackup.sh
/opt/hc/lib/platform/aix/check_aix_topasrec.sh
/opt/hc/lib/platform/aix/check_aix_uptime.sh
/etc/opt/hc
/etc/opt/hc/check_aix_file_age.conf.dist
/etc/opt/hc/check_aix_file_change.conf.dist
/etc/opt/hc/check_aix_root_crontab.conf.dist
/etc/opt/hc/check_aix_subsystems.conf.dist
/etc/opt/hc/check_aix_sysbackup.conf.dist
/etc/opt/hc/check_aix_uptime.conf.dist
EOROOTFiles
Relocatable: N
EOFileset

View File

@ -0,0 +1 @@
*prereq hc_aix.rte

View File

@ -0,0 +1,31 @@
Package Name: hc_notify_slack
Package VRMF: %BUILD_DATE%
Update: N
Fileset
Fileset Name: hc_notify_slack.rte
Fileset VRMF: %BUILD_DATE%
Fileset Description: Health Checker - core Slack plugin
USRLIBLPPFiles
EOUSRLIBLPPFiles
ROOTLIBLPPFiles
Post-installation Script: /export/nim/build/hc_notify_slack/scripts/hc_notify_slack.postinstall
Unpost-installation Script: /export/nim/build/hc_notify_slack/scripts/hc_notify_slack.postuninstall
EOROOTLIBLPPFiles
Bosboot required: N
License agreement acceptance required: N
Include license files in this package: N
Requisites: /export/nim/build/hc_notify_slack/hc_notify_slack.reqs
USRFiles
EOUSRFiles
ROOT Part: Y
ROOTFiles
/opt/hc/lib
/opt/hc/lib/core
/opt/hc/lib/platform/aix/notify_slack.sh
/etc/opt/hc
/etc/opt/hc/core
/etc/opt/hc/core/providers
/etc/opt/hc/core/providers/notify_slack.conf.dist
EOROOTFiles
Relocatable: N
EOFileset

View File

@ -0,0 +1,51 @@
#!/usr/bin/env ksh
#******************************************************************************
# @(#) post-install script for hc_notify_slack LPP package
#******************************************************************************
# @(#) Copyright (C) 2022 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#******************************************************************************
# ------------------------- CONFIGURATION starts here -------------------------
# location of ETC dir
HC_ETC_DIR="/etc/opt/hc"
# location of check_health.sh
HC_BIN="/opt/hc/bin/check_health.sh"
PATH="$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
# ------------------------- CONFIGURATION ends here ---------------------------
print "INFO: starting post-install script ..."
# copy plugin config file from dist (if needed)
if [[ ! -f ${HC_ETC_DIR}/core/providers/notify_slack.conf ]]
then
cp -p ${HC_ETC_DIR}/core/providers/notify_slack.conf.dist ${HC_ETC_DIR}/core/providers/notify_slack.conf >/dev/null || \
{
print -u2 "ERROR: could not copy plugin config file in ${HC_ETC_DIR}/core/providers"
exit 1
}
fi
# refresh symbolic FPATH links
if [[ -x ${HC_BIN} ]]
then
${HC_BIN} --fix-symlinks || print -u2 "WARN: updating symlinks failed"
else
print -u2 "ERROR: could not locate or excute the HC main script (${HC_BIN})"
fi
print "INFO: finished post-install script"
exit 0
#******************************************************************************
# END of script
#******************************************************************************

View File

@ -0,0 +1,48 @@
#!/usr/bin/env ksh
#******************************************************************************
# @(#) post-uninstall script for hc_notify_slack LPP package
#******************************************************************************
# @(#) Copyright (C) 2022 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#******************************************************************************
# ------------------------- CONFIGURATION starts here -------------------------
# location of the HC configuration files
HC_ETC_DIR="/etc/opt/hc"
# location of check_health.sh
HC_BIN="/opt/hc/bin/check_health.sh"
PATH="$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
# ------------------------- CONFIGURATION ends here ---------------------------
print "INFO: starting post-uninstall script ..."
# remove plugin configuration file (.dist only)
if [[ -d ${HC_ETC_DIR}/core/providers ]]
then
rm -f ${HC_ETC_DIR}/core/providers/notify_slack.conf.dist >/dev/null
(( $? == 0 )) || echo "WARN: could not remove plugin config file in directory ${HC_ETC_DIR}/core/providers"
fi
# refresh symbolic FPATH links
if [[ -x ${HC_BIN} ]]
then
${HC_BIN} --fix-symlinks || print -u2 "WARN: updating symlinks failed"
else
print -u2 "ERROR: could not locate or excute the HC main script (${HC_BIN})"
fi
print "INFO: finished post-uninstall script"
exit 0
#******************************************************************************
# END of script
#******************************************************************************

View File

@ -63,6 +63,7 @@ This is the OS/platform plugin package"
file -m 755 check_hpux_autopath.sh
file -m 755 check_hpux_cdsf_cluster.sh
file -m 755 check_hpux_cron_status.sh
file -m 755 check_hpux_defunct_processes.sh
file -m 755 check_hpux_drd_status.sh
file -m 755 check_hpux_file_age.sh
file -m 755 check_hpux_file_change.sh
@ -72,7 +73,7 @@ This is the OS/platform plugin package"
file -m 755 check_hpux_ignite_backup.sh
file -m 755 check_hpux_ioscan.sh
file -m 755 check_hpux_guid_status.sh
file -m 644 check_hpux_hpvm_vpar_status.sh
file -m 755 check_hpux_hpvm_vpar_status.sh
file -m 755 check_hpux_httpd_status.sh
file -m 755 check_hpux_kernel_params.sh
file -m 755 check_hpux_kernel_usage.sh
@ -87,6 +88,7 @@ This is the OS/platform plugin package"
file -m 755 check_hpux_sshd_status.sh
file -m 755 check_hpux_syslog.sh
file -m 755 check_hpux_syslogd_status.sh
file -m 755 check_hpux_uptime.sh
file -m 755 check_hpux_vg_minor_number.sh
end
@ -104,6 +106,8 @@ This is the OS/platform plugin package"
directory ../../../etc/opt/hc/=/etc/opt/hc
file -m 644 check_hpux_autofs.conf.dist
file -m 644 check_hpux_cron_status.conf.dist
file -m 644 check_hpux_defunct_processes.conf.dist
file -m 644 check_hpux_drd_status.conf.dist
file -m 644 check_hpux_file_age.conf.dist
file -m 644 check_hpux_file_change.conf.dist
@ -115,11 +119,12 @@ This is the OS/platform plugin package"
file -m 644 check_hpux_kernel_params.conf.dist
file -m 644 check_hpux_kernel_usage.conf.dist
file -m 644 check_hpux_ntp_status.conf.dist
file -m 755 check_hpux_ovpa_status.conf.dist
file -m 755 check_hpux_patch_version.conf.dist
file -m 644 check_hpux_ovpa_status.conf.dist
file -m 644 check_hpux_patch_version.conf.dist
file -m 644 check_hpux_root_crontab.conf.dist
file -m 644 check_hpux_sfm_status.conf.dist
file -m 644 check_hpux_syslog.conf.dist
file -m 644 check_hpux_uptime.conf.dist
end
fileset

View File

@ -0,0 +1,80 @@
# Depot definition:
depot
layout_version 1.0
# Vendor definition:
vendor
tag KUDOS
title "KUDOS BVBA - http://www.kudos.be"
end
# Bundle definitions:
bundle
tag HC-NOTIFY-SLACK
title "The Health Checker (HC) for UNIX (core SLACK plugin)"
os_name HP-UX
revision %BUILD_DATE%
architecture HP-UX_B.11_32/64
machine_type ia64*
vendor_tag KUDOS
contents HC-NOTIFY-SLACK-MAIN,r=,a=,v=
end
# Product definitions:
product
tag HC-NOTIFY-SLACK-MAIN
revision %BUILD_DATE%
category tools
category_title Tools
title "The Health Checker (HC) for UNIX (OS plugins)"
description "The Health Checker is collection of scripts (plugins)
designed to perform regular - but not intensive - health checks on
UNIX/Linux systems. It provides plugins for AIX, HP-UX and Linux as
well customer specific checks. Checks may include topics such file
system mounts, process checks, file consistency etc.
This is the core SLACK plugin package"
architecture S700/S800_HP-UX_10/HP-UX_11/IA64_HP-UX_11
machine_type 9000/7*|9000/8*|ia64*
os_name HP-UX
os_release ?.1?.*
os_version [A-Z]
directory /opt/hc
is_locatable false
is_patch false
postinstall scripts/hc_notify_slack.postinstall
postremove scripts/hc_notify_slack.postremove
# Fileset definitions:
fileset
tag core_plugins
title UX Health Checker (core SLACK plugins)
is_kernel false
is_locatable false
is_reboot false
is_sparse false
is_patch false
prerequisite HC-HPUX-MAIN
file_permissions -u 0222 -o root -g sys
directory ../../../opt/hc/lib/core=/opt/hc/lib/core
file -m 755 notify_slack.sh
end
fileset
tag config
title UX Health Checker (core SLACK plugins: configuration)
is_kernel false
is_locatable false
is_reboot false
is_sparse false
is_patch false
prerequisite HC-NOTIFY-SLACK-MAIN.core_plugins
file_permissions -u 0222 -o root -g sys
directory ../../../etc/opt/hc/core/providers=/etc/opt/hc/core/providers
file -m 644 notify_slack.conf.dist
end
end

View File

@ -0,0 +1,51 @@
#!/usr/bin/env ksh
#******************************************************************************
# @(#) post-install script for HC-NOTIFY-SLACK SD package
#******************************************************************************
# @(#) Copyright (C) 2022 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#******************************************************************************
# ------------------------- CONFIGURATION starts here -------------------------
# location of ETC dir
HC_ETC_DIR="/etc/opt/hc"
# location of check_health.sh
HC_BIN="/opt/hc/bin/check_health.sh"
PATH="$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
# ------------------------- CONFIGURATION ends here ---------------------------
print "INFO: starting post-install script ..."
# copy plugin config file from dist (if needed)
if [[ ! -f ${HC_ETC_DIR}/core/providers/notify_slack.conf ]]
then
cp -p ${HC_ETC_DIR}/core/providers/notify_slack.conf.dist ${HC_ETC_DIR}/core/providers/notify_slack.conf >/dev/null || \
{
print -u2 "ERROR: could not copy plugin config file in ${HC_ETC_DIR}/core/providers"
exit 1
}
fi
# refresh symbolic FPATH links
if [[ -x ${HC_BIN} ]]
then
${HC_BIN} --fix-symlinks || print -u2 "WARN: updating symlinks failed"
else
print -u2 "ERROR: could not locate or excute the HC main script (${HC_BIN})"
fi
print "INFO: finished post-install script"
exit 0
#******************************************************************************
# END of script
#******************************************************************************

View File

@ -0,0 +1,48 @@
#!/usr/bin/env ksh
#******************************************************************************
# @(#) post-remove script for HC-NOTIFY-SLACK SD package
#******************************************************************************
# @(#) Copyright (C) 2022 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#******************************************************************************
# ------------------------- CONFIGURATION starts here -------------------------
# location of the HC configuration files
HC_ETC_DIR="/etc/opt/hc"
# location of check_health.sh
HC_BIN="/opt/hc/bin/check_health.sh"
PATH="$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
# ------------------------- CONFIGURATION ends here ---------------------------
print "INFO: starting post-remove script ..."
# remove plugin configuration file (.dist only)
if [[ -d ${HC_ETC_DIR}/core/providers ]]
then
rm -f ${HC_ETC_DIR}/core/providers/notify_slack.conf.dist >/dev/null
(( $? == 0 )) || echo "WARN: could not remove plugin config file in directory ${HC_ETC_DIR}/core/providers"
fi
# refresh symbolic FPATH links
if [[ -x ${HC_BIN} ]]
then
${HC_BIN} --fix-symlinks || print -u2 "WARN: updating symlinks failed"
else
print -u2 "ERROR: could not locate or excute the HC main script (${HC_BIN})"
fi
print "INFO: finished post-remove script"
exit 0
#******************************************************************************
# END of script
#******************************************************************************

View File

@ -22,8 +22,10 @@ package() {
install -D -m 755 opt/hc/lib/platform/linux/check_linux_autofs.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_autofs.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_burp_backup.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_burp_backup.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_burp_status.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_burp_status.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_dovecot_status.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_dovecot_status.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_es_status.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_es_status.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_fail2ban_status.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_fail2ban_status.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_fetchmail_status.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_fetchmail_status.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_file_age.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_file_age.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_file_change.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_file_change.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_fs_mounts.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_fs_mounts.sh
@ -43,6 +45,7 @@ package() {
install -D -m 755 opt/hc/lib/platform/linux/check_linux_hpssacli.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_hpssacli.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_process_limits.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_process_limits.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_root_crontab.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_root_crontab.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_uptime.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_uptime.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_vz_ct_counters.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_vz_ct_counters.sh
install -D -m 755 opt/hc/lib/platform/linux/check_linux_vz_ct_status.sh ${pkgdir}/opt/hc/lib/platform/linux/check_linux_vz_ct_status.sh
install -d -m 755 ${pkgdir}/etc/opt/hc
@ -50,6 +53,7 @@ package() {
install -D -m 644 etc/opt/hc/check_linux_burp_backup.conf.dist ${pkgdir}/etc/opt/hc/check_linux_burp_backup.conf.dist
install -D -m 644 etc/opt/hc/check_linux_es_status.conf.dist ${pkgdir}/etc/opt/hc/check_linux_es_status.conf.dist
install -D -m 644 etc/opt/hc/check_linux_fail2ban_status.conf.dist ${pkgdir}/etc/opt/hc/check_linux_fail2ban_status.conf.dist
install -D -m 644 etc/opt/hc/check_linux_fetchmail_status.conf.dist ${pkgdir}/etc/opt/hc/check_linux_fetchmail_status.conf.dist
install -D -m 644 etc/opt/hc/check_linux_file_age.conf.dist ${pkgdir}/etc/opt/hc/check_linux_file_age.conf.dist
install -D -m 644 etc/opt/hc/check_linux_file_change.conf.dist ${pkgdir}/etc/opt/hc/check_linux_file_change.conf.dist
install -D -m 644 etc/opt/hc/check_linux_fs_usage.conf.dist ${pkgdir}/etc/opt/hc/check_linux_fs_usage.conf.dist
@ -62,6 +66,7 @@ package() {
install -D -m 644 etc/opt/hc/check_linux_ntp_status.conf.dist ${pkgdir}/etc/opt/hc/check_linux_ntp_status.conf.dist
install -D -m 644 etc/opt/hc/check_linux_process_limits.conf.dist ${pkgdir}/etc/opt/hc/check_linux_process_limits.conf.dist
install -D -m 644 etc/opt/hc/check_linux_root_crontab.conf.dist ${pkgdir}/etc/opt/hc/check_linux_root_crontab.conf.dist
install -D -m 644 etc/opt/hc/check_linux_uptime.conf.dist ${pkgdir}/etc/opt/hc/check_linux_uptime.conf.dist
install -D -m 644 etc/opt/hc/check_linux_vz_ct_counters.conf.dist ${pkgdir}/etc/opt/hc/check_linux_vz_ct_counters.conf.dist
install -D -m 644 etc/opt/hc/check_linux_vz_ct_status.conf.dist ${pkgdir}/etc/opt/hc/check_linux_vz_ct_status.conf.dist
install -d -m 755 ${pkgdir}/etc/opt/hc/core

View File

@ -0,0 +1,33 @@
# -- post-install --
post_install() {
# ------------------------- CONFIGURATION starts here -------------------------
# location of check_health.sh
HC_BIN="/opt/hc/bin/check_health.sh"
PATH="$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
# ------------------------- CONFIGURATION ends here ---------------------------
echo "INFO: starting post-install script ..."
# refresh symbolic FPATH links
if [[ -x ${HC_BIN} ]]
then
${HC_BIN} --fix-symlinks
(( $? == 0 )) || echo "WARN: updating symlinks failed"
fi
echo "INFO: finished post-install script"
}
# -- post-remove --
post_remove() {
# ------------------------- CONFIGURATION starts here -------------------------
# location of check_health.sh
HC_BIN="/opt/hc/bin/check_health.sh"
PATH="$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
# ------------------------- CONFIGURATION ends here ---------------------------
echo "INFO: starting post-uninstall script ..."
# refresh symbolic FPATH links
if [[ -x ${HC_BIN} ]]
then
${HC_BIN} --fix-symlinks
(( $? == 0 )) || echo "WARN: updating symlinks failed"
fi
echo "INFO: finished post-uninstall script"
}

View File

@ -0,0 +1,26 @@
# Maintainer: Patrick Van der Veken <patrick@kudos.be>
_pkgname="check_health"
pkgname="hc-notify-slack"
pkgver="%BUILD_DATE%"
pkgrel=1
pkgdesc="The KUDOS Health Checker (HC) for UNIX (Slack notify core plugin)"
arch=("any")
url="https://github.com/patvdv/${_pkgname}"
license=('GPL3')
makedepends=('git')
depends=('hc-linux')
source=("${_pkgname}::git+${url}.git#branch=master")
install=".install"
sha256sums=('SKIP')
package() {
cd "${srcdir}/${_pkgname}"
install -d -m 755 ${pkgdir}/opt/hc/lib
install -d -m 755 ${pkgdir}/opt/hc/lib/core
install -D -m 755 opt/hc/lib/core/notify_slack.sh ${pkgdir}/opt/hc/lib/core/notify_slack.sh
install -d -m 755 ${pkgdir}/etc/opt/hc
install -d -m 755 ${pkgdir}/etc/opt/hc/core
install -d -m 755 ${pkgdir}/etc/opt/hc/core/providers
install -D -m 644 etc/opt/hc/core/providers/notify_slack.conf.dist ${pkgdir}/etc/opt/hc/core/providers/notify_slack.conf.dist
}

View File

@ -0,0 +1,10 @@
Package: hc-notify-slack
Version: %BUILD_DATE%
Architecture: all
Maintainer: Patrick Van der Veken <patrick@kudos.be>
Essential: no
Installed-Size: 50
Pre-Depends: hc-linux
Section: tools
Priority: extra
Description: The KUDOS Health Checker (HC) for UNIX (Slack notify core plugin).

View File

@ -0,0 +1,33 @@
#!/bin/bash
# ------------------------- CONFIGURATION starts here -------------------------
# location of the HC configuration files
HC_ETC_DIR="/etc/opt/hc"
# location of check_health.sh
HC_BIN="/opt/hc/bin/check_health.sh"
PATH="$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
# ------------------------- CONFIGURATION ends here ---------------------------
echo "INFO: starting post-install script ..."
# debian: reset ownerships
chown -R root:root /opt/hc /etc/opt/hc 2>/dev/null
# copy plugin configuration file
if [[ -f ${HC_ETC_DIR}/core/providers/notify_slack.conf.dist ]]
then
if [[ ! -f ${HC_ETC_DIR}/core/providers/notify_slack.conf ]]
then
cp -p ${HC_ETC_DIR}/core/providers/notify_slack.conf.dist ${HC_ETC_DIR}/core/providers/notify_slack.conf >/dev/null
(( $? == 0 )) || \
{
echo "ERROR: could not copy plugin config file in ${HC_ETC_DIR}/core/providers"
exit 1
}
fi
else
echo "WARN: could not find plugin config .dist file in ${HC_ETC_DIR}/core/providers"
fi
# refresh symbolic FPATH links
if [[ -x ${HC_BIN} ]]
then
${HC_BIN} --fix-symlinks
(( $? == 0 )) || echo "WARN: updating symlinks failed"
fi
echo "INFO: finished post-install script"

View File

@ -0,0 +1,32 @@
#!/bin/bash
# ------------------------- CONFIGURATION starts here -------------------------
# location of the HC configuration files
HC_ETC_DIR="/etc/opt/hc"
# location of check_health.sh
HC_BIN="/opt/hc/bin/check_health.sh"
PATH="$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
# ------------------------- CONFIGURATION ends here ---------------------------
# update or uninstall?
if (( $1 == 0 ))
then
echo "INFO: starting post-uninstall script ..."
# copy plugin configuration file (.dist only)
if [[ -d ${HC_ETC_DIR}/core/providers ]]
then
rm -f ${HC_ETC_DIR}/core/providers/notify_slack.conf.dist 2>/dev/null
(( $? == 0 )) || \
{
echo "ERROR: could not remove plugin config file in ${HC_ETC_DIR}/core/providers"
exit 1
}
fi
else
echo "INFO: starting post-uninstall script (RPM upgrade)"
fi
# refresh symbolic FPATH links
if [[ -x ${HC_BIN} ]]
then
${HC_BIN} --fix-symlinks
(( $? == 0 )) || echo "WARN: updating symlinks failed"
fi
echo "INFO: finished post-uninstall script"

View File

@ -30,8 +30,10 @@ install -d -m 755 $RPM_BUILD_ROOT/opt/hc/lib/platform/linux
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_autofs.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_autofs.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_burp_backup.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_burp_backup.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_burp_status.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_burp_status.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_dovecot_status.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_dovecot_status.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_es_status.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_es_status.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_fail2ban_status.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_fail2ban_status.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_fetchmail_status.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_fetchmail_status.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_file_age.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_file_age.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_file_change.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_file_change.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_fs_mounts.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_fs_mounts.sh
@ -51,6 +53,7 @@ cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_hplog.sh $RPM_BUILD_ROOT/opt
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_hpssacli.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_hpssacli.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_process_limits.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_process_limits.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_root_crontab.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_root_crontab.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_uptime.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_uptime.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_vz_ct_counters.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_vz_ct_counters.sh
cp ../SOURCES/opt/hc/lib/platform/linux/check_linux_vz_ct_status.sh $RPM_BUILD_ROOT/opt/hc/lib/platform/linux/check_linux_vz_ct_status.sh
install -d -m 755 $RPM_BUILD_ROOT/etc/opt/hc
@ -58,6 +61,7 @@ cp ../SOURCES/etc/opt/hc/check_linux_autofs.conf.dist $RPM_BUILD_ROOT/etc/opt/hc
cp ../SOURCES/etc/opt/hc/check_linux_burp_backup.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_burp_backup.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_es_status.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_es_status.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_fail2ban_status.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_fail2ban_status.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_fetchmail_status.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_fetchmail_status.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_file_age.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_file_age.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_file_change.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_file_change.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_fs_usage.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_fs_usage.conf.dist
@ -70,6 +74,7 @@ cp ../SOURCES/etc/opt/hc/check_linux_mysqld_status.conf.dist $RPM_BUILD_ROOT/etc
cp ../SOURCES/etc/opt/hc/check_linux_ntp_status.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_ntp_status.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_process_limits.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_process_limits.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_root_crontab.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_root_crontab.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_uptime.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_uptime.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_vz_ct_counters.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_vz_ct_counters.conf.dist
cp ../SOURCES/etc/opt/hc/check_linux_vz_ct_status.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/check_linux_vz_ct_status.conf.dist
install -d -m 755 $RPM_BUILD_ROOT/etc/opt/hc/core
@ -115,8 +120,10 @@ echo "INFO: finished post-uninstall script"
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_autofs.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_burp_backup.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_burp_status.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_dovecot_status.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_es_status.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_fail2ban_status.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_fetchmail_status.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_file_age.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_file_change.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_fs_mounts.sh
@ -136,6 +143,7 @@ echo "INFO: finished post-uninstall script"
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_hpssacli.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_process_limits.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_root_crontab.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_uptime.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_vz_ct_counters.sh
%attr(755, root, root) /opt/hc/lib/platform/linux/check_linux_vz_ct_status.sh
%dir /etc/opt/hc
@ -143,6 +151,7 @@ echo "INFO: finished post-uninstall script"
%attr(644, root, root) /etc/opt/hc/check_linux_burp_backup.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_es_status.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_fail2ban_status.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_fetchmail_status.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_file_age.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_file_change.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_fs_usage.conf.dist
@ -155,6 +164,7 @@ echo "INFO: finished post-uninstall script"
%attr(644, root, root) /etc/opt/hc/check_linux_ntp_status.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_process_limits.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_root_crontab.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_uptime.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_vz_ct_counters.conf.dist
%attr(644, root, root) /etc/opt/hc/check_linux_vz_ct_status.conf.dist
%dir /etc/opt/hc/core
@ -163,6 +173,11 @@ echo "INFO: finished post-uninstall script"
%attr(644, root, root) /etc/opt/hc/core/templates/mail_body.tpl-check_linux_root_crontab
%changelog
* Sat Dec 26 2020 <patrick@kudos.be> - 0.3.5
- Added check_linux_fetchmail_status plugin
- Added check_linux_dovecot_status plugin
* Mon Dec 21 2020 <patrick@kudos.be> - 0.3.4
- Added check_linux_uptime plugin
* Fri Oct 18 2020 <patrick@kudos.be> - 0.3.3
- Added check_linux_fail2ban_status plugin
* Fri Nov 1 2019 <patrick@kudos.be> - 0.3.2

View File

@ -0,0 +1,107 @@
%define build_timestamp %(date +"%Y%m%d")
Name: hc-notify-slack
Version: %{build_timestamp}
Release: 1
Summary: The KUDOS Health Checker (HC) for UNIX (Slack notify core plugin)
Group: Tools/Monitoring
License: GNU General Public License either version 2 of the License, or (at your option) any later version
URL: http://www.kudos.be
Requires: ksh,hc-linux
BuildArch: noarch
BuildRoot: %{_topdir}/%{name}-%{version}-root
%description
The Health Checker is collection of scripts (plugins) designed to perform regular - but not intensive - health checks on UNIX/Linux systems. It provides plugins for AIX, HP-UX and Linux as well customer specific checks. Checks may include topics such file system mounts, process checks, file consistency etc.
This package contains core plugins (notify).
%prep
%build
%install
rm -rf $RPM_BUILD_ROOT
install -d -m 755 $RPM_BUILD_ROOT/opt/hc/lib
install -d -m 755 $RPM_BUILD_ROOT/opt/hc/lib/core
cp ../SOURCES/opt/hc/lib/core/notify_slack.sh $RPM_BUILD_ROOT/opt/hc/lib/core/notify_slack.sh
install -d -m 755 $RPM_BUILD_ROOT/etc/opt/hc
install -d -m 755 $RPM_BUILD_ROOT/etc/opt/hc/core
install -d -m 755 $RPM_BUILD_ROOT/etc/opt/hc/core/providers
cp ../SOURCES/etc/opt/hc/core/providers/notify_slack.conf.dist $RPM_BUILD_ROOT/etc/opt/hc/core/providers/notify_slack.conf.dist
%post
# ------------------------- CONFIGURATION starts here -------------------------
# location of the HC configuration files
HC_ETC_DIR="/etc/opt/hc"
# location of check_health.sh
HC_BIN="/opt/hc/bin/check_health.sh"
PATH="$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
# ------------------------- CONFIGURATION ends here ---------------------------
echo "INFO: starting post-install script ..."
# copy plugin configuration file
if [[ ! -f ${HC_ETC_DIR}/core/providers/notify_slack.conf ]]
then
cp -p ${HC_ETC_DIR}/core/providers/notify_slack.conf.dist ${HC_ETC_DIR}/core/providers/notify_slack.conf >/dev/null
(( $? == 0 )) || \
{
echo "ERROR: could not copy plugin config file in ${HC_ETC_DIR}/core/providers"
exit 1
}
fi
# refresh symbolic FPATH links
if [[ -x ${HC_BIN} ]]
then
${HC_BIN} --fix-symlinks
(( $? == 0 )) || echo "WARN: updating symlinks failed"
fi
echo "INFO: finished post-install script"
%postun
# ------------------------- CONFIGURATION starts here -------------------------
# location of the HC configuration files
HC_ETC_DIR="/etc/opt/hc"
# location of check_health.sh
HC_BIN="/opt/hc/bin/check_health.sh"
PATH="$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/usr/bin/X11:/sbin"
# ------------------------- CONFIGURATION ends here ---------------------------
# update or uninstall?
if (( $1 == 0 ))
then
echo "INFO: starting post-uninstall script ..."
# copy plugin configuration file (.dist only)
if [[ -d ${HC_ETC_DIR}/core/providers ]]
then
rm -f ${HC_ETC_DIR}/core/providers/notify_slack.conf.dist 2>/dev/null
(( $? == 0 )) || \
{
echo "ERROR: could not remove plugin config file in ${HC_ETC_DIR}/core/providers"
exit 1
}
fi
else
echo "INFO: starting post-uninstall script (RPM upgrade)"
fi
# refresh symbolic FPATH links
if [[ -x ${HC_BIN} ]]
then
${HC_BIN} --fix-symlinks
(( $? == 0 )) || echo "WARN: updating symlinks failed"
fi
echo "INFO: finished post-uninstall script"
%files
%defattr(-,root,root,755)
%dir /opt/hc/lib
%dir /opt/hc/lib/core
%attr(755, root, root) /opt/hc/lib/core/notify_slack.sh
%dir /etc/opt/hc
%dir /etc/opt/hc/core
%dir /etc/opt/hc/core/providers
%attr(644, root, root) /etc/opt/hc/core/providers/notify_slack.conf.dist
%changelog
* Sun Oct 14 2022 <patrick@kudos.be> - 0.0.1
- Initial build

View File

@ -47,6 +47,7 @@ rpmbuild -bb ${BUILD_DIR}/SPECS/hc-linux-platform.spec
# build core plugins
rpmbuild -bb ${BUILD_DIR}/SPECS/hc-notify-eif.spec
rpmbuild -bb ${BUILD_DIR}/SPECS/hc-notify-sms.spec
rpmbuild -bb ${BUILD_DIR}/SPECS/hc-notify-slack.spec
rpmbuild -bb ${BUILD_DIR}/SPECS/hc-display-init.spec
rpmbuild -bb ${BUILD_DIR}/SPECS/hc-display-json.spec
rpmbuild -bb ${BUILD_DIR}/SPECS/hc-display-csv.spec

View File

@ -0,0 +1,41 @@
#******************************************************************************
# @(#) check_aix_uptime.conf
#******************************************************************************
# This is a configuration file for the check_aix_uptime HC plugin.
# All lines starting with a '#' are comment lines.
# [default: indicates hardcoded script values if no value is defined here]
#******************************************************************************
# specify whether to also log passed health checks
# (warning: this may rapidly grow the HC log)
# [default: no]
log_healthy="no"
# trigger event when current uptime is less than previously record uptime?
# [default: yes]
check_reboot="yes"
# time to wait before the current uptime is considered for the reboot check.
# Example: a value of 60m means the check for a previous reboot will be at earliest
# performed 1 hour after the last reboot of the host.
# Format: <value>m|h|d where m=minutes, h=hours, d=days (lowercase suffix).
# if no suffix is specified, then minutes are assumed.
# [default: 60m]
reboot_time="60m"
# trigger event when current uptime goes over the maximum threshold?
# [default: no]
check_old_age="no"
# time to expire before the current uptime is considered "old age".
# Example: a value of 365d means a must-reboot will be flagged at earliest after
# 1 year of uptime of the host
# Format: <value>m|h|d where m=minutes, h=hours, d=days (lowercase suffix).
# if no suffix is specified, then minutes are assumed.
# [default: 365d]
old_age_time="365d"
#******************************************************************************
# End of FILE
#******************************************************************************

View File

@ -0,0 +1,25 @@
#******************************************************************************
# @(#) check_hpux_cron_status.conf
#******************************************************************************
# This is a configuration file for the check_hpux_cron_status HC plugin.
# All lines starting with a '#' are comment lines.
# [default: indicates hardcoded script values if no value is defined here]
#******************************************************************************
# specify whether to also log passed health checks
# (warning: this may rapidly grow the HC log)
# [default: no]
log_healthy="no"
# specify the wait time (in seconds) between registering and checking a cron task
# [default: 10]
wait_time=10
# specify the path the cron log file
# [default: /var/adm/cron/log]
cron_log="/var/adm/cron/log"
#******************************************************************************
# End of FILE
#******************************************************************************

View File

@ -0,0 +1,27 @@
#******************************************************************************
# @(#) check_hpux_defunct_processes.conf
#******************************************************************************
# This is a configuration file for the check_hpux_defunct_processes HC plugin.
# All lines starting with a '#' are comment lines.
# [default: indicates hardcoded script values if no value is defined here]
#******************************************************************************
# specify whether to also log passed health checks
# (warning: this may rapidly grow the HC log)
# [default: no]
log_healthy="yes"
# specify above which threshold of defunct processes to generate a HC fail event
# If group_by_ppid is set to 'yes' then the value of 'process_threshold' will
# apply for each PPID, otherwise it will apply to all defunct processes together
# [default: 10]
process_threshold=10
# specify whether to group by parent ID or not.
# [default: yes]
group_by_ppid="yes"
#******************************************************************************
# End of FILE
#******************************************************************************

View File

@ -0,0 +1,41 @@
#******************************************************************************
# @(#) check_hpux_uptime.conf
#******************************************************************************
# This is a configuration file for the check_hpux_uptime HC plugin.
# All lines starting with a '#' are comment lines.
# [default: indicates hardcoded script values if no value is defined here]
#******************************************************************************
# specify whether to also log passed health checks
# (warning: this may rapidly grow the HC log)
# [default: no]
log_healthy="no"
# trigger event when current uptime is less than previously record uptime?
# [default: yes]
check_reboot="yes"
# time to wait before the current uptime is considered for the reboot check.
# Example: a value of 60m means the check for a previous reboot will be at earliest
# performed 1 hour after the last reboot of the host.
# Format: <value>m|h|d where m=minutes, h=hours, d=days (lowercase suffix).
# if no suffix is specified, then minutes are assumed.
# [default: 60m]
reboot_time="60m"
# trigger event when current uptime goes over the maximum threshold?
# [default: no]
check_old_age="no"
# time to expire before the current uptime is considered "old age".
# Example: a value of 365d means a must-reboot will be flagged at earliest after
# 1 year of uptime of the host
# Format: <value>m|h|d where m=minutes, h=hours, d=days (lowercase suffix).
# if no suffix is specified, then minutes are assumed.
# [default: 365d]
old_age_time="365d"
#******************************************************************************
# End of FILE
#******************************************************************************

View File

@ -0,0 +1,28 @@
#******************************************************************************
# @(#) check_linux_fetchmail_status.conf
#******************************************************************************
# This is a configuration file for the check_linux_fetchmail_status HC plugin.
# All lines starting with a '#' are comment lines.
# [default: indicates hardcoded script values if no value is defined here]
#******************************************************************************
# specify whether to also log passed health checks
# (warning: this may rapidly grow the HC log)
# [default: no]
log_healthy="no"
# specify the regex of error codes that will be used to search the log file_path
# [default: error|authfail|lockbusy|ioerr]
error_regex="error|authfail|lockbusy|ioerr"
# specify fetchmail details
# Format:
# fetchmail:<account>:<rc_file>:<check_log=Yes|No>
# Examples:
#fetchmail:vmail:/srv/vmail/janedoe/.fetchmailrc:Yes
#fetchmail:vmail:/srv/vmail/johndoe/.fetchmailrc:No
#******************************************************************************
# End of FILE
#******************************************************************************

View File

@ -19,6 +19,11 @@ force_chrony="no"
# [default: no]
force_ntp="no"
# whether to force the use of systemd-timesyncd?
# [default: no]
# [release >20220129]
force_systemd="no"
# maximum allowed offset (in milliseconds (positive integers only)
# [default: 500]
max_offset=500

View File

@ -0,0 +1,41 @@
#******************************************************************************
# @(#) check_linux_uptime.conf
#******************************************************************************
# This is a configuration file for the check_linux_uptime HC plugin.
# All lines starting with a '#' are comment lines.
# [default: indicates hardcoded script values if no value is defined here]
#******************************************************************************
# specify whether to also log passed health checks
# (warning: this may rapidly grow the HC log)
# [default: no]
log_healthy="no"
# trigger event when current uptime is less than previously record uptime?
# [default: yes]
check_reboot="yes"
# time to wait before the current uptime is considered for the reboot check.
# Example: a value of 60m means the check for a previous reboot will be at earliest
# performed 1 hour after the last reboot of the host.
# Format: <value>m|h|d where m=minutes, h=hours, d=days (lowercase suffix).
# if no suffix is specified, then minutes are assumed.
# [default: 60m]
reboot_time="60m"
# trigger event when current uptime goes over the maximum threshold?
# [default: no]
check_old_age="no"
# time to expire before the current uptime is considered "old age".
# Example: a value of 365d means a must-reboot will be flagged at earliest after
# 1 year of uptime of the host
# Format: <value>m|h|d where m=minutes, h=hours, d=days (lowercase suffix).
# if no suffix is specified, then minutes are assumed.
# [default: 365d]
old_age_time="365d"
#******************************************************************************
# End of FILE
#******************************************************************************

View File

@ -31,6 +31,10 @@ HC_REPORT_CACHE_LAST="No"
# [values: Yes|No]
HC_REPORT_CACHE_TODAY="No"
# Show log entry count(s) after archiving. Disabling this will speed up archiving.
# [values: Yes|No]
HC_COUNT_ARCHIVES="Yes"
#******************************************************************************
# End of FILE

View File

@ -0,0 +1,15 @@
#******************************************************************************
# @(#) notify_slack.conf
#******************************************************************************
# This is the the configuration file for the notify_slack.sh provider.
# All lines starting with a '#' are comment lines.
# [default: indicates hardcoded script values if no value is defined here]
#******************************************************************************
# URL of the webhook of the Slack app
SLACK_WEBHOOK=""
#******************************************************************************
# End of FILE
#******************************************************************************

View File

@ -23,8 +23,8 @@
# REQUIRES: ksh88/93 (mksh/pdksh will probably work too but YMMV)
# build_fpath(), check_config(), check_core(), check_lock_dir(),
# check_params(), check_platform(), check_user(), check_shell(),
# display_usage(), do_cleanup, fix_symlinks(), read_config()
# + include functions
# display_usage(), do_cleanup, fix_symlinks(), get_disable_comment(),
# read_config() + include functions
# For other pre-requisites see the documentation in display_usage()
# REQUIRES (OPTIONAL): display_*(), notify_*(), report_*()
# EXISTS: 0=no errors encountered, >0=some errors encountered
@ -38,7 +38,7 @@
# ------------------------- CONFIGURATION starts here -------------------------
# define the version (YYYY-MM-DD)
typeset -r SCRIPT_VERSION="2020-04-07"
typeset -r SCRIPT_VERSION="2021-03-31"
# location of parent directory containing KSH functions/HC plugins
typeset -r FPATH_PARENT="/opt/hc/lib"
# location of custom HC configuration files
@ -86,8 +86,8 @@ typeset EXIT_CODE=0
typeset FDIR=""
typeset FFILE=""
typeset FPATH=""
typeset HC_ARCHIVE=""
typeset HC_CHECK=""
typeset HC_COMMENT=""
typeset HC_DISABLE=""
typeset HC_ENABLE=""
typeset HC_RUN=""
@ -102,6 +102,10 @@ typeset HC_MIN_TIME_OUT=30
typeset HC_MSG_VAR=""
typeset HC_STDOUT_LOG=""
typeset HC_STDERR_LOG=""
set -A HC_STDOUT_LOG_ARRAY
set -A HC_STDERR_LOG_ARRAY
# shellcheck disable=SC2034
typeset HC_COUNT_ARCHVES=""
typeset HC_WILL_FIX=""
# shellcheck disable=SC2034
typeset HC_REPORT_CACHE_LAST=""
@ -111,6 +115,7 @@ typeset HC_REPORT_CACHE_TODAY=""
typeset LINUX_DISTRO=""
# shellcheck disable=SC2034
typeset LINUX_RELEASE=""
typeset PREVIOUS_HC_TIME_OUT=""
typeset ARCHIVE_RC=0
typeset DISABLE_RC=0
typeset ENABLE_RC=0
@ -126,6 +131,7 @@ typeset DEBUG_OPTS=""
# command-line parameters
typeset ARG_ACTION=0 # HC action flag
typeset ARG_CHECK_HOST=0 # host check is off by default
typeset ARG_COMMENT=""
typeset ARG_CONFIG_FILE="" # custom configuration file for a HC, none by default
typeset ARG_DEBUG=0 # debug is off by default
typeset ARG_DEBUG_LEVEL=0 # debug() only by default
@ -285,7 +291,7 @@ case "${KSH_VERSION}" in
# shellcheck source=/dev/null
(( ARG_DEBUG > 0 )) && print -u2 "DEBUG: including ${INCLUDE_FILE}"
# shellcheck source=/dev/null
. ${INCLUDE_FILE}
. "${INCLUDE_FILE}"
else
print -u2 "ERROR: library file ${INCLUDE_FILE} exists but has no symlink. Run --fix-symlinks"
exit 1
@ -334,18 +340,19 @@ function check_lock_dir
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
if (( ARG_LOCK > 0 ))
then
mkdir ${LOCK_DIR} >/dev/null 2>/dev/null || {
mkdir "${LOCK_DIR}" >/dev/null 2>/dev/null || {
print -u2 "ERROR: unable to acquire lock ${LOCK_DIR}"
ARG_VERBOSE=0 warn "unable to acquire lock ${LOCK_DIR}"
if [[ -f ${LOCK_DIR}/.pid ]]
then
typeset LOCK_PID="$(<${LOCK_DIR}/.pid)"
# shellcheck disable=SC2086
typeset LOCK_PID=$(<"${LOCK_DIR}/.pid")
print -u2 "ERROR: active health checker running on PID: ${LOCK_PID}"
ARG_VERBOSE=0 warn "active health checker running on PID: ${LOCK_PID}. Exiting!"
fi
exit 1
}
print $$ >${LOCK_DIR}/.pid
print $$ > "${LOCK_DIR}/.pid"
else
(( ARG_DEBUG > 0 )) && print "DEBUG: locking has been disabled"
fi
@ -469,6 +476,15 @@ then
exit 1
fi
fi
# --comment
if [[ -n "${ARG_COMMENT}" ]]
then
if (( ARG_ACTION != 2 )) && (( ARG_ACTION != 6 ))
then
print -u2 "ERROR: you can only use '--comment' in combination with '--disable' or '--disable-all'"
exit 1
fi
fi
# check log location
if (( ARG_LOG > 0 ))
then
@ -570,8 +586,8 @@ cat << EOT
Execute/report simple health checks (HC) on UNIX hosts.
Syntax: ${SCRIPT_DIR}/${SCRIPT_NAME} [--help] | [--help-terse] | [--version] |
[--list=<needle>] | [--list-details] | [--list-core] | [--list-include] | [--fix-symlinks] | [--show-stats] | (--archive-all | --disable-all | --enable-all) | [--fix-logs [--with-history]] |
(--check-host | ((--archive | --check | --enable | --disable | --run [--timeout=<secs>] | --show) --hc=<list_of_checks> [--config-file=<configuration_file>] [hc-args="<arg1,arg2=val,arg3">]))
[--list=<needle>] | [--list-details] | [--list-core] | [--list-include] | [--fix-symlinks] | [--show-stats] | (--archive-all | --disable-all [--comment=<text>] | --enable-all) | [--fix-logs [--with-history]] |
(--check-host | ((--archive | --check | --enable | --disable [--comment=<text>] | --run [--timeout=<secs>] | --show) --hc=<list_of_checks> [--config-file=<configuration_file>] [hc-args="<arg1,arg2=val,arg3">]))
[--display=<method>] ([--debug] [--debug-level=<level>]) [--log-healthy] [--no-fix] [--no-log] [--no-lock] [--no-monitor] [[--flip-rc] [--with-rc=<count|max|sum>]]]
[--notify=<method_list>] [--mail-to=<address_list>] [--sms-to=<sms_rcpt> --sms-provider=<name>]
[--report=<method> [--with-history] ( ([--last] | [--today]) | [(--older|--newer)=<date>] | [--reverse] [--id=<fail_id> [--detail]] )]
@ -587,6 +603,7 @@ Parameters:
--archive-all : move events for all HCs from the HC log file into archive log files
--check : display HC state.
--check-host : execute all configured HC(s) (see check_host.conf)
--comment : add comment to requested action (--disable). WARNING: comments may not contain spaces!
--config-file : custom configuration file for a HC (may only be specified when executing a single HC plugin)
--debug : run script in debug mode
--debug-level : level of debugging information to show (0,1,2)
@ -658,16 +675,28 @@ function do_cleanup
log "performing cleanup ..."
# remove temporary files
[[ -f "${HC_MSG_FILE}" ]] && rm -f ${HC_MSG_FILE} >/dev/null 2>&1
[[ -f "${HC_MSG_FILE}" ]] && rm -f "${HC_MSG_FILE}" >/dev/null 2>&1
# remove trailing log files
[[ -f "${HC_STDOUT_LOG}" ]] && rm -f ${HC_STDOUT_LOG} >/dev/null 2>&1
[[ -f "${HC_STDERR_LOG}" ]] && rm -f ${HC_STDERR_LOG} >/dev/null 2>&1
# remove left over plugin log files (pop from array stacks)
FILE_COUNT=1
while (( FILE_COUNT <= ${#HC_STDOUT_LOG_ARRAY[*]} ))
do
(( ARG_DEBUG > 0 )) && debug "cleaning up plugin log file ${HC_STDOUT_LOG_ARRAY[FILE_COUNT]}"
[[ -f "${HC_STDOUT_LOG_ARRAY[FILE_COUNT]}" ]] && rm -f "${HC_STDOUT_LOG_ARRAY[FILE_COUNT]}" >/dev/null 2>&1
FILE_COUNT=$(( FILE_COUNT + 1 ))
done
FILE_COUNT=1
while (( FILE_COUNT <= ${#HC_STDERR_LOG_ARRAY[*]} ))
do
(( ARG_DEBUG > 0 )) && debug "cleaning up plugin log file ${HC_STDERR_LOG_ARRAY[FILE_COUNT]}"
[[ -f "${HC_STDERR_LOG_ARRAY[FILE_COUNT]}" ]] && rm -f "${HC_STDERR_LOG_ARRAY[FILE_COUNT]}" >/dev/null 2>&1
FILE_COUNT=$(( FILE_COUNT + 1 ))
done
# remove lock directory
if [[ -d ${LOCK_DIR} ]]
then
rm -rf ${LOCK_DIR} >/dev/null 2>&1
rm -rf "${LOCK_DIR}" >/dev/null 2>&1
log "${LOCK_DIR} lock directory removed"
fi
@ -692,6 +721,7 @@ typeset FSYML=""
# find missing symlinks (do not skip core plug-ins here)
print "${FPATH}" | tr ':' '\n' 2>/dev/null | while read -r FDIR
do
# shellcheck disable=SC2086
find ${FDIR} -type f -print 2>/dev/null | while read -r FFILE
do
FSYML="${FFILE%.sh}"
@ -710,7 +740,7 @@ done
print "${FPATH}" | tr ':' '\n' 2>/dev/null | while read -r FDIR
do
# do not use 'find -type l' here!
# shellcheck disable=SC2010
# shellcheck disable=SC2010,SC2086
ls ${FDIR} 2>/dev/null | grep -v "\." 2>/dev/null | while read -r FSYML
do
# check if file is a dead symlink
@ -813,6 +843,12 @@ do
fi
ARG_CHECK_HOST=1
;;
-comment=*)
ARG_COMMENT="${CMD_PARAMETER#-comment=}"
;;
--comment=*)
ARG_COMMENT="${CMD_PARAMETER#--comment=}"
;;
-config-file=*)
ARG_CONFIG_FILE="${CMD_PARAMETER#-config-file=}"
;;
@ -1213,7 +1249,13 @@ case ${ARG_ACTION} in
# shellcheck disable=SC2181
if (( $? == 0 ))
then
HC_COMMENT=$(get_disable_comment "${HC_CHECK}")
if [[ -n "${HC_COMMENT}" ]]
then
log "HC ${HC_CHECK} is currently disabled (${HC_COMMENT})"
else
log "HC ${HC_CHECK} is currently disabled"
fi
else
log "HC ${HC_CHECK} is currently enabled"
fi
@ -1235,6 +1277,11 @@ case ${ARG_ACTION} in
exists_hc "${HC_DISABLE}" && die "cannot find HC: ${HC_DISABLE}"
log "disabling HC: ${HC_DISABLE}"
touch "${STATE_PERM_DIR}/${HC_DISABLE}.disabled" >/dev/null 2>&1
# write comment if supplied
if [[ -n "${ARG_COMMENT}" ]]
then
print "${ARG_COMMENT}" >"${STATE_PERM_DIR}/${HC_DISABLE}.disabled"
fi
# shellcheck disable=SC2181
if (( $? == 0 ))
then
@ -1282,7 +1329,7 @@ case ${ARG_ACTION} in
# re-initialize messages stash (log of failed checks)
# shellcheck disable=SC2034
HC_MSG_VAR=""
: >${HC_MSG_FILE} 2>/dev/null
: > "${HC_MSG_FILE}" 2>/dev/null
# shellcheck disable=SC2181
if (( $? > 0 ))
then
@ -1320,13 +1367,16 @@ case ${ARG_ACTION} in
# set & initialize STDOUT/STDERR locations (not in init_hc()!)
HC_STDOUT_LOG="${TMP_DIR}/${HC_RUN}.stdout.log.$$"
HC_STDERR_LOG="${TMP_DIR}/${HC_RUN}.stderr.log.$$"
: >${HC_STDOUT_LOG} 2>/dev/null
# push plugin log files to array stacks (index starts at 1!)
HC_STDOUT_LOG_ARRAY[${#HC_STDOUT_LOG_ARRAY[*]}+1]="${HC_STDOUT_LOG}"
HC_STDERR_LOG_ARRAY[${#HC_STDERR_LOG_ARRAY[*]}+1]="${HC_STDERR_LOG}"
: > "${HC_STDOUT_LOG}" 2>/dev/null
# shellcheck disable=SC2181
if (( $? > 0 ))
then
die "unable to reset the \${HC_STDOUT_LOG} file"
fi
: >${HC_STDERR_LOG} 2>/dev/null
: > "${HC_STDERR_LOG}" 2>/dev/null
# shellcheck disable=SC2181
if (( $? > 0 ))
then
@ -1336,6 +1386,7 @@ case ${ARG_ACTION} in
# --check-host handling: alternative configuration file, mangle ARG_CONFIG_FILE & HC_TIME_OUT
if (( ARG_CHECK_HOST == 1 ))
then
PREVIOUS_HC_TIME_OUT=${HC_TIME_OUT}
ARG_CONFIG_FILE="" # reset from previous call
RUN_CONFIG_FILE=$(grep -i -E -e "^hc:${HC_RUN}:" ${HOST_CONFIG_FILE} 2>/dev/null | cut -f3 -d':')
[[ -n "${RUN_CONFIG_FILE}" ]] && ARG_CONFIG_FILE="${CONFIG_DIR}/${RUN_CONFIG_FILE}"
@ -1345,13 +1396,14 @@ case ${ARG_ACTION} in
(( RUN_TIME_OUT > HC_TIME_OUT )) && HC_TIME_OUT=${RUN_TIME_OUT}
else
# reset for next HC
HC_TIME_OUT=60
HC_TIME_OUT=${PREVIOUS_HC_TIME_OUT}
fi
fi
# run HC with or without monitor
if (( ARG_MONITOR == 0 ))
then
# shellcheck disable=SC2086
${HC_RUN} ${ARG_HC_ARGS}
RUN_RC=$?
EXIT_CODE=${RUN_RC}
@ -1390,6 +1442,7 @@ case ${ARG_ACTION} in
# SLEEP_PID is the PID of the sleep subshell itself
SLEEP_PID=$!
# shellcheck disable=SC2086
${HC_RUN} ${ARG_HC_ARGS} &
CHILD_PID=$!
log "spawning child process with time-out of ${HC_TIME_OUT} secs for HC call [PID=${CHILD_PID}]"
@ -1440,7 +1493,7 @@ case ${ARG_ACTION} in
handle_hc "${HC_RUN}"
# exit with return code from handle_hc() (see --flip-rc)
EXIT_CODE=$?
rm -f ${HC_MSG_FILE} >/dev/null 2>&1
rm -f "${HC_MSG_FILE}" >/dev/null 2>&1
done
;;
5) # show info on HC (single)
@ -1460,6 +1513,11 @@ case ${ARG_ACTION} in
exists_hc "${HC_DISABLE}" && die "cannot find HC: ${HC_DISABLE}"
log "disabling HC: ${HC_DISABLE}"
touch "${STATE_PERM_DIR}/${HC_DISABLE}.disabled" >/dev/null 2>&1
# write comment if supplied
if [[ -n "${ARG_COMMENT}" ]]
then
print "${ARG_COMMENT}" >"${STATE_PERM_DIR}/${HC_DISABLE}.disabled"
fi
DISABLE_RC=$?
if (( DISABLE_RC == 0 ))
then
@ -1534,26 +1592,7 @@ case ${ARG_ACTION} in
esac
;;
13) # archive current log entries for all HCs
list_hc "list" | while read -r HC_ARCHIVE
do
# check for HC (function)
exists_hc "${HC_ARCHIVE}" && die "cannot find HC: ${HC_ARCHIVE}"
log "archiving current log entries for HC: ${HC_ARCHIVE}"
archive_hc "${HC_ARCHIVE}"
ARCHIVE_RC=$?
case ${ARCHIVE_RC} in
0)
log "no archiving needed for ${HC_ARCHIVE}"
;;
1)
log "successfully archived log entries for ${HC_ARCHIVE}"
;;
2)
log "failed to archive log entries for ${HC_ARCHIVE} [RC=${ARCHIVE_RC}]"
EXIT_CODE=1
;;
esac
done
archive_hc_all
;;
esac

View File

@ -30,7 +30,7 @@
# RETURNS: 0
function version_include_core
{
typeset _VERSION="2020-04-15" # YYYY-MM-DD
typeset _VERSION="2022-10-14" # YYYY-MM-DD
print "INFO: $0: ${_VERSION#version_*}"
@ -50,6 +50,7 @@ typeset HC_NAME="${1}"
typeset ARCHIVE_FILE=""
typeset ARCHIVE_RC=0
typeset YEAR_MONTH=""
typeset COUNT_STATS=1
typeset LOG_COUNT=0
typeset PRE_LOG_COUNT=0
typeset TODO_LOG_COUNT=0
@ -63,15 +64,25 @@ typeset TMP2_FILE="${TMP_DIR}/.$0.tmp2.archive.$$"
trap "rm -f ${TMP1_FILE} ${TMP2_FILE} ${SAVE_LOG_FILE} >/dev/null 2>&1; return 1" 1 2 3 15
# get pre-archive log count
PRE_LOG_COUNT=$(wc -l ${HC_LOG} 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
PRE_LOG_COUNT=$(wc -l "${HC_LOG}" 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
if (( PRE_LOG_COUNT == 0 ))
then
warn "${HC_LOG} is empty, nothing to archive"
return 0
fi
# check log count toggle (only affects $LOG_COUNT)
case "${HC_COUNT_ARCHIVES}" in
No|no|NO)
COUNT_STATS=0
;;
*)
: # default is to do additional stats
;;
esac
# isolate messages from HC, find unique %Y-%m combinations
grep ".*${LOG_SEP}${HC_NAME}${LOG_SEP}" ${HC_LOG} 2>/dev/null |\
grep ".*${LOG_SEP}${HC_NAME}${LOG_SEP}" "${HC_LOG}" 2>/dev/null |\
cut -f1 -d"${LOG_SEP}" 2>/dev/null | cut -f1 -d' ' 2>/dev/null |\
cut -f1-2 -d'-' 2>/dev/null | sort -u 2>/dev/null |\
while read -r YEAR_MONTH
@ -84,50 +95,105 @@ do
fi
# find all messages for that YEAR-MONTH combination
grep "${YEAR_MONTH}.*${LOG_SEP}${HC_NAME}${LOG_SEP}" ${HC_LOG} >${TMP1_FILE}
TODO_LOG_COUNT=$(wc -l ${TMP1_FILE} 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
grep "${YEAR_MONTH}.*${LOG_SEP}${HC_NAME}${LOG_SEP}" "${HC_LOG}" >"${TMP1_FILE}"
TODO_LOG_COUNT=$(wc -l "${TMP1_FILE}" 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
log "# of entries in ${YEAR_MONTH} to archive: ${TODO_LOG_COUNT}"
# combine existing archived messages and resort
ARCHIVE_FILE="${ARCHIVE_DIR}/hc.${YEAR_MONTH}.log"
cat ${ARCHIVE_FILE} ${TMP1_FILE} 2>/dev/null | sort -u >${TMP2_FILE} 2>/dev/null
mv ${TMP2_FILE} ${ARCHIVE_FILE} 2>/dev/null || {
cat "${ARCHIVE_FILE}" "${TMP1_FILE}" 2>/dev/null | sort -u >"${TMP2_FILE}" 2>/dev/null
mv "${TMP2_FILE}" "${ARCHIVE_FILE}" 2>/dev/null || {
warn "failed to move archive file, aborting"
return 2
}
LOG_COUNT=$(wc -l ${ARCHIVE_FILE} 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
if (( COUNT_STATS > 0 ))
then
LOG_COUNT=$(wc -l "${ARCHIVE_FILE}" 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
log "# of entries in ${ARCHIVE_FILE} now: ${LOG_COUNT}"
fi
# remove archived messages from the $HC_LOG (but create a backup first!)
cp -p ${HC_LOG} ${SAVE_HC_LOG} 2>/dev/null
cp -p "${HC_LOG}" "${SAVE_HC_LOG}" 2>/dev/null
# compare with the sorted $HC_LOG
sort ${HC_LOG} >${TMP1_FILE}
comm -23 ${TMP1_FILE} ${ARCHIVE_FILE} 2>/dev/null >${TMP2_FILE}
sort "${HC_LOG}" >"${TMP1_FILE}"
comm -23 "${TMP1_FILE}" "${ARCHIVE_FILE}" 2>/dev/null >"${TMP2_FILE}"
# check archive action (HC_LOG should not be empty unless it contained
# only messages from one single HC plugin before archival)
if [[ -s ${TMP2_FILE} ]] || (( PRE_LOG_COUNT == TODO_LOG_COUNT ))
then
mv ${TMP2_FILE} ${HC_LOG} 2>/dev/null || {
mv "${TMP2_FILE}" "${HC_LOG}" 2>/dev/null || {
warn "failed to move HC log file, aborting"
return 2
}
LOG_COUNT=$(wc -l ${HC_LOG} 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
if (( COUNT_STATS > 0 ))
then
LOG_COUNT=$(wc -l "${HC_LOG}" 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
log "# entries in ${HC_LOG} now: ${LOG_COUNT}"
fi
ARCHIVE_RC=1
else
warn "a problem occurred. Rolling back archival"
mv ${SAVE_HC_LOG} ${HC_LOG} 2>/dev/null
mv "${SAVE_HC_LOG}" "${HC_LOG}" 2>/dev/null
ARCHIVE_RC=2
fi
done
# clean up temporary file(s)
rm -f ${TMP1_FILE} ${TMP2_FILE} ${SAVE_HC_LOG} >/dev/null 2>&1
rm -f "${TMP1_FILE}" "${TMP2_FILE}" "${SAVE_HC_LOG}" >/dev/null 2>&1
return ${ARCHIVE_RC}
}
# -----------------------------------------------------------------------------
# @(#) FUNCTION: archive_hc_all()
# DOES: archive log entries for all HCs
# EXPECTS: n/a
# RETURNS: 0
# REQUIRES: ${HC_LOG}
function archive_hc_all
{
typeset HC_ARCHIVE=""
# build list with all HCs in $HC_LOG and sort them by highest number of messages
# first (to speed up the archiving operation)
log "parsing log file ${HC_LOG} for messages ..."
awk -F"${LOG_SEP}" '
{
# only do records with a proper HC name in $2
if ($2 ~ /check_/) {
count[$2]++;
}
}
END {
for (hc in count) {
print count[hc] ":" hc;
}
}' "${HC_LOG}" 2>/dev/null | sort -rn 2>/dev/null |\
while IFS=":" read -r HC_COUNT HC_ARCHIVE
do
# check for HC (function)
exists_hc "${HC_ARCHIVE}" && die "cannot find HC: ${HC_ARCHIVE}"
log "archiving ${HC_COUNT} log entries for HC ${HC_ARCHIVE}"
archive_hc "${HC_ARCHIVE}"
ARCHIVE_RC=$?
case ${ARCHIVE_RC} in
0)
log "no archiving needed for ${HC_ARCHIVE}"
;;
1)
log "successfully archived log entries for ${HC_ARCHIVE}"
;;
2)
warn "failed to archive log entries for ${HC_ARCHIVE} [RC=${ARCHIVE_RC}]"
;;
esac
done
return 0
}
# -----------------------------------------------------------------------------
# @(#) FUNCTION: count_log_errors()
# DOES: check hc log file(s) for rogue entries (=lines with NF<>$NUM_LOG_FIELDS
@ -145,7 +211,7 @@ function count_log_errors
typeset LOG_STASH="${1}"
typeset ERROR_COUNT=0
# shellcheck disable=SC2002
# shellcheck disable=SC2002,SC2086
ERROR_COUNT=$(cat ${LOG_STASH} 2>/dev/null | awk -F"${LOG_SEP}" '
BEGIN { num = 0 }
{
@ -155,7 +221,7 @@ ERROR_COUNT=$(cat ${LOG_STASH} 2>/dev/null | awk -F"${LOG_SEP}" '
}
END { print num }' 2>/dev/null)
print ${ERROR_COUNT}
print "${ERROR_COUNT}"
return 0
}
@ -197,7 +263,7 @@ then
print - "$*" | while read -r LOG_LINE
do
# shellcheck disable=SC2153
print "${NOW}: ERROR: [$$]:" "${LOG_LINE}" >>${LOG_FILE}
print "${NOW}: ERROR: [$$]:" "${LOG_LINE}" >>"${LOG_FILE}"
done
fi
print - "$*" | while read -r LOG_LINE
@ -241,6 +307,7 @@ DO_DISPLAY_CUSTOM9=0
DO_NOTIFY_EIF=0
DO_NOTIFY_MAIL=0
DO_NOTIFY_SMS=0
DO_NOTIFY_SLACK=0
DO_REPORT_STD=0
HAS_DISPLAY_CSV=0
HAS_DISPLAY_INIT=0
@ -259,12 +326,13 @@ HAS_DISPLAY_CUSTOM9=0
HAS_NOTIFY_EIF=0
HAS_NOTIFY_MAIL=0
HAS_NOTIFY_SMS=0
HAS_NOTIFY_SLACK=0
HAS_REPORT_STD=0
# check which core display/notification plugins are installed
# do not use a while-do loop here because mksh/pdksh does not pass updated
# variables back from the sub shell (only works for true ksh88/ksh93)
# shellcheck disable=SC2010
# shellcheck disable=SC2010,SC2086
for FFILE in $(ls -1 ${FPATH_PARENT}/core/*.sh 2>/dev/null | grep -v "include_" 2>/dev/null)
do
case "${FFILE}" in
@ -336,6 +404,10 @@ do
HAS_NOTIFY_EIF=1
(( ARG_DEBUG > 0 )) && debug "notify_eif plugin is available"
;;
*notify_slack.sh)
HAS_NOTIFY_SLACK=1
(( ARG_DEBUG > 0 )) && debug "notify_slack plugin is available"
;;
*report_std.sh)
# shellcheck disable=SC2034
HAS_REPORT_STD=1
@ -493,6 +565,9 @@ then
*mail*) # by mail
DO_NOTIFY_MAIL=1
;;
*slack*) # by Slack
DO_NOTIFY_SLACK=1
;;
*sms*) # by sms
DO_NOTIFY_SMS=1
;;
@ -651,8 +726,10 @@ return 0
function dump_logs
{
log "=== STDOUT ==="
# shellcheck disable=SC2086
log "$(<${HC_STDOUT_LOG})"
log "=== STDERR ==="
# shellcheck disable=SC2086
log "$(<${HC_STDERR_LOG})"
return 0
@ -741,25 +818,26 @@ fi
trap "[[ -f ${TMP_FILE} ]] && rm -f ${TMP_FILE} >/dev/null 2>&1; return 1" 1 2 3 15
# check and rewrite log file(s)
# shellcheck disable=SC2086
find ${LOG_STASH} -type f -print 2>/dev/null | while read -r FIX_FILE
do
log "fixing log file ${FIX_FILE} ..."
# count before rewrite
STASH_COUNT=$(wc -l ${FIX_FILE} 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
STASH_COUNT=$(wc -l "${FIX_FILE}" 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
# does it have errors?
ERROR_COUNT=$(count_log_errors ${FIX_FILE})
ERROR_COUNT=$(count_log_errors "${FIX_FILE}")
# we count the empty lines (again)
EMPTY_COUNT=$(grep -c -E -e '^$' ${FIX_FILE} 2>/dev/null)
EMPTY_COUNT=$(grep -c -E -e '^$' "${FIX_FILE}" 2>/dev/null)
# rewrite if needed
if (( ERROR_COUNT > 0 ))
then
: >${TMP_FILE} 2>/dev/null
: >"${TMP_FILE}" 2>/dev/null
# shellcheck disable=SC2002
cat ${FIX_FILE} 2>/dev/null | awk -F"${LOG_SEP}" -v OFS="${LOG_SEP}" '
cat "${FIX_FILE}" 2>/dev/null | awk -F"${LOG_SEP}" -v OFS="${LOG_SEP}" '
BEGIN { max_log_fields = '"${NUM_LOG_FIELDS}"'
max_fields = (max_log_fields - 1) * 2
@ -835,10 +913,10 @@ do
# correct log line, no rewrite needed
print $0
}
}' >${TMP_FILE} 2>/dev/null
}' >"${TMP_FILE}" 2>/dev/null
# count after rewrite (include empty lines again in the count)
TMP_COUNT=$(wc -l ${TMP_FILE} 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
TMP_COUNT=$(wc -l "${TMP_FILE}" 2>/dev/null | cut -f1 -d' ' 2>/dev/null)
TMP_COUNT=$(( TMP_COUNT + EMPTY_COUNT ))
# bail out when we do not have enough records
@ -849,16 +927,16 @@ do
fi
# swap log file (but create a backup first!)
cp -p ${FIX_FILE} ${SAVE_TMP_FILE} 2>/dev/null
cp -p "${FIX_FILE}" "${SAVE_TMP_FILE}" 2>/dev/null
# shellcheck disable=SC2181
if (( $? == 0 ))
then
mv ${TMP_FILE} ${FIX_FILE} 2>/dev/null
mv "${TMP_FILE}" "${FIX_FILE}" 2>/dev/null
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to move/update log file, rolling back"
mv ${SAVE_TMP_FILE} ${FIX_FILE} 2>/dev/null
mv "${SAVE_TMP_FILE}" "${FIX_FILE}" 2>/dev/null
return 2
fi
FIX_RC=1
@ -868,7 +946,7 @@ do
fi
# clean up temporary file(s)
rm -f ${SAVE_TMP_FILE} ${TMP_FILE} >/dev/null 2>&1
rm -f "${SAVE_TMP_FILE}" "${TMP_FILE}" >/dev/null 2>&1
else
log "no fixing needed for ${FIX_FILE}"
fi
@ -879,6 +957,26 @@ done
return ${FIX_RC}
}
# -----------------------------------------------------------------------------
# @(#) FUNCTION: get_disable_comment()
# DOES: retrieve comment for a disabled HC
# EXPECTS: HC name [string]
# OUTPUTS: comment [string]
# RETURNS: 0
# REQUIRES: n/a
function get_disable_comment
{
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
typeset COMMENT_HC="${1}"
if [[ -s "${STATE_PERM_DIR}/${COMMENT_HC}.disabled" ]]
then
cat "${STATE_PERM_DIR}/${COMMENT_HC}.disabled" 2>/dev/null
fi
return 0
}
# -----------------------------------------------------------------------------
# @(#) FUNCTION: handle_hc()
# DOES: handle HC results
@ -913,7 +1011,7 @@ if [[ -s ${HC_MSG_FILE} ]]
then
# load messages file into memory
# do not use array: max 1024 items in ksh88; regular variable is only 32-bit memory limited
HC_MSG_VAR=$(<${HC_MSG_FILE})
HC_MSG_VAR=$(<"${HC_MSG_FILE}")
# DEBUG: dump TMP file
if (( ARG_DEBUG > 0 ))
@ -931,6 +1029,7 @@ else
# nothing to do, respect current EXIT_CODE
if (( EXIT_CODE > 0 ))
then
# shellcheck disable=SC2086
return ${EXIT_CODE}
else
return 0
@ -1152,50 +1251,50 @@ then
if (( ONE_MSG_STC > 0 ))
then
# build log string
LOG_STRING_FAIL=$(printf "%s${LOG_SEP}%s${LOG_SEP}%s${LOG_SEP}%s${LOG_SEP}%s${LOG_SEP}" "${ONE_MSG_TIME}" "${HC_NAME}" ${ONE_MSG_STC} "${ONE_MSG_TEXT}" "${HC_FAIL_ID}")
LOG_STRING_FAIL=$(printf "%s${LOG_SEP}%s${LOG_SEP}%s${LOG_SEP}%s${LOG_SEP}%s${LOG_SEP}" "${ONE_MSG_TIME}" "${HC_NAME}" "${ONE_MSG_STC}" "${ONE_MSG_TEXT}" "${HC_FAIL_ID}")
# do atomic log update
# shellcheck disable=SC1117
print "${LOG_STRING_FAIL}" >>${HC_LOG}
print "${LOG_STRING_FAIL}" >>"${HC_LOG}"
# cache report (--report --last)
HC_REPORT_CACHE_LAST_FILE="${HC_REPORT_CACHE_LAST_STUB}-${HC_NAME}"
case "${HC_REPORT_CACHE_LAST}" in
Yes|yes|YES)
# fetch date of last cache entry (did we rollover from last HC event?)
HC_CACHE_LAST_DATE=$(tail -n 1 ${HC_REPORT_CACHE_LAST_FILE} 2>/dev/null | cut -f1 -d${LOG_SEP} 2>/dev/null)
HC_CACHE_LAST_DATE=$(tail -n 1 "${HC_REPORT_CACHE_LAST_FILE}" 2>/dev/null | cut -f1 -d"${LOG_SEP}" 2>/dev/null)
if [[ -z "${HC_CACHE_LAST_DATE}" ]] || [[ "${HC_CACHE_LAST_DATE}" != "${HC_CACHE_LAST_NOW}" ]]
then
# set and update cache file
print "${LOG_STRING_FAIL}" >${HC_REPORT_CACHE_LAST_FILE}
print "${LOG_STRING_FAIL}" >"${HC_REPORT_CACHE_LAST_FILE}"
else
# append cache file
print "${LOG_STRING_FAIL}" >>${HC_REPORT_CACHE_LAST_FILE}
print "${LOG_STRING_FAIL}" >>"${HC_REPORT_CACHE_LAST_FILE}"
fi
;;
*)
# remove cache file if it exists
[[ -f ${HC_REPORT_CACHE_LAST_FILE} ]] && rm -f ${HC_REPORT_CACHE_LAST_FILE} >/dev/null 2>/dev/null
[[ -f "${HC_REPORT_CACHE_LAST_FILE}" ]] && rm -f "${HC_REPORT_CACHE_LAST_FILE}" >/dev/null 2>/dev/null
;;
esac
# cache report (--report --today)
case "${HC_REPORT_CACHE_TODAY}" in
Yes|yes|YES)
# fetch date of last cache entry (did we rollover midnight?)
HC_CACHE_TODAY_DATE=$(tail -n 1 ${HC_REPORT_CACHE_TODAY_FILE} 2>/dev/null | cut -f1 -d${LOG_SEP} 2>/dev/null | awk '{ print $1 }' 2>/dev/null)
HC_CACHE_TODAY_DATE=$(tail -n 1 "${HC_REPORT_CACHE_TODAY_FILE}" 2>/dev/null | cut -f1 -d"${LOG_SEP}" 2>/dev/null | awk '{ print $1 }' 2>/dev/null)
if [[ -z "${HC_CACHE_TODAY_DATE}" ]] || [[ "${HC_CACHE_TODAY_DATE}" != "${HC_CACHE_TODAY_NOW}" ]]
then
# rotate and update cache file
(( ARG_DEBUG > 0 )) && debug "rotating today's cache file at ${HC_REPORT_CACHE_TODAY_FILE}"
print "${LOG_STRING_FAIL}" >${HC_REPORT_CACHE_TODAY_FILE}
print "${LOG_STRING_FAIL}" >"${HC_REPORT_CACHE_TODAY_FILE}"
else
# append cache file
print "${LOG_STRING_FAIL}" >>${HC_REPORT_CACHE_TODAY_FILE}
print "${LOG_STRING_FAIL}" >>"${HC_REPORT_CACHE_TODAY_FILE}"
fi
;;
*)
# remove cache file if it exists
[[ -f ${HC_REPORT_CACHE_TODAY_FILE} ]] && rm -f ${HC_REPORT_CACHE_TODAY_FILE} >/dev/null 2>/dev/null
[[ -f "${HC_REPORT_CACHE_TODAY_FILE}" ]] && rm -f "${HC_REPORT_CACHE_TODAY_FILE}" >/dev/null 2>/dev/null
;;
esac
# RC handling (max/sum/count)
@ -1218,50 +1317,50 @@ then
fi
else
# build log string
LOG_STRING_GOOD=$(printf "%s${LOG_SEP}%s${LOG_SEP}%s${LOG_SEP}%s${LOG_SEP}" "${ONE_MSG_TIME}" "${HC_NAME}" ${ONE_MSG_STC} "${ONE_MSG_TEXT}")
LOG_STRING_GOOD=$(printf "%s${LOG_SEP}%s${LOG_SEP}%s${LOG_SEP}%s${LOG_SEP}" "${ONE_MSG_TIME}" "${HC_NAME}" "${ONE_MSG_STC}" "${ONE_MSG_TEXT}")
# do atomic log update
# shellcheck disable=SC1117
print "${LOG_STRING_GOOD}" >>${HC_LOG}
print "${LOG_STRING_GOOD}" >>"${HC_LOG}"
# cache report (--report --last)
HC_REPORT_CACHE_LAST_FILE="${HC_REPORT_CACHE_LAST_STUB}-${HC_NAME}"
case "${HC_REPORT_CACHE_LAST}" in
Yes|yes|YES)
# fetch date of last cache entry (did we rollover from last HC event?)
HC_CACHE_LAST_DATE=$(tail -n 1 ${HC_REPORT_CACHE_LAST_FILE} 2>/dev/null | cut -f1 -d${LOG_SEP} 2>/dev/null)
HC_CACHE_LAST_DATE=$(tail -n 1 "${HC_REPORT_CACHE_LAST_FILE}" 2>/dev/null | cut -f1 -d"${LOG_SEP}" 2>/dev/null)
if [[ -z "${HC_CACHE_LAST_DATE}" ]] || [[ "${HC_CACHE_LAST_DATE}" != "${HC_CACHE_LAST_NOW}" ]]
then
# set and update cache file
print "${LOG_STRING_GOOD}" >${HC_REPORT_CACHE_LAST_FILE}
print "${LOG_STRING_GOOD}" >"${HC_REPORT_CACHE_LAST_FILE}"
else
# append cache file
print "${LOG_STRING_GOOD}" >>${HC_REPORT_CACHE_LAST_FILE}
print "${LOG_STRING_GOOD}" >>"${HC_REPORT_CACHE_LAST_FILE}"
fi
;;
*)
# remove cache file if it exists
[[ -f ${HC_REPORT_CACHE_LAST_FILE} ]] && rm -f ${HC_REPORT_CACHE_LAST_FILE} >/dev/null 2>/dev/null
[[ -f "${HC_REPORT_CACHE_LAST_FILE}" ]] && rm -f "${HC_REPORT_CACHE_LAST_FILE}" >/dev/null 2>/dev/null
;;
esac
# cache report (--report --today)
case "${HC_REPORT_CACHE_TODAY}" in
Yes|yes|YES)
# fetch date of last cache last_entry (did we rollover midnight?)
HC_CACHE_TODAY_DATE=$(tail -n 1 ${HC_REPORT_CACHE_TODAY_FILE} 2>/dev/null | cut -f1 -d${LOG_SEP} 2>/dev/null | awk '{ print $1 }' 2>/dev/null)
HC_CACHE_TODAY_DATE=$(tail -n 1 "${HC_REPORT_CACHE_TODAY_FILE}" 2>/dev/null | cut -f1 -d"${LOG_SEP}" 2>/dev/null | awk '{ print $1 }' 2>/dev/null)
if [[ -z "${HC_CACHE_TODAY_DATE}" ]] || [[ "${HC_CACHE_TODAY_DATE}" != "${HC_CACHE_TODAY_NOW}" ]]
then
# rotate and update cache file
(( ARG_DEBUG > 0 )) && debug "rotating today's cache file at ${HC_REPORT_CACHE_TODAY_FILE}"
print "${LOG_STRING_GOOD}" >${HC_REPORT_CACHE_TODAY_FILE}
print "${LOG_STRING_GOOD}" >"${HC_REPORT_CACHE_TODAY_FILE}"
else
# append cache file
print "${LOG_STRING_GOOD}" >>${HC_REPORT_CACHE_TODAY_FILE}
print "${LOG_STRING_GOOD}" >>"${HC_REPORT_CACHE_TODAY_FILE}"
fi
;;
*)
# remove cache file if it exists
[[ -f ${HC_REPORT_CACHE_TODAY_FILE} ]] && rm -f ${HC_REPORT_CACHE_TODAY_FILE} >/dev/null 2>/dev/null
[[ -f ${HC_REPORT_CACHE_TODAY_FILE} ]] && rm -f "${HC_REPORT_CACHE_TODAY_FILE}" >/dev/null 2>/dev/null
;;
esac
fi
@ -1280,14 +1379,14 @@ then
then
# cut off the path and the .$$ part from the file location
HC_STDOUT_LOG_SHORT="${HC_STDOUT_LOG##*/}"
mv ${HC_STDOUT_LOG} "${EVENTS_DIR}/${DIR_PREFIX}/${HC_FAIL_ID}/${HC_STDOUT_LOG_SHORT%.*}" >/dev/null 2>&1 || \
mv "${HC_STDOUT_LOG}" "${EVENTS_DIR}/${DIR_PREFIX}/${HC_FAIL_ID}/${HC_STDOUT_LOG_SHORT%.*}" >/dev/null 2>&1 || \
die "failed to move ${HC_STDOUT_LOG} to event directory at ${1}"
fi
if [[ -f ${HC_STDERR_LOG} ]]
then
# cut off the path and the .$$ part from the file location
HC_STDERR_LOG_SHORT="${HC_STDERR_LOG##*/}"
mv ${HC_STDERR_LOG} "${EVENTS_DIR}/${DIR_PREFIX}/${HC_FAIL_ID}/${HC_STDERR_LOG_SHORT%.*}" >/dev/null 2>&1 || \
mv "${HC_STDERR_LOG}" "${EVENTS_DIR}/${DIR_PREFIX}/${HC_FAIL_ID}/${HC_STDERR_LOG_SHORT%.*}" >/dev/null 2>&1 || \
die "failed to move ${HC_STDERR_LOG} to event directory at ${1}"
fi
fi
@ -1326,6 +1425,17 @@ then
warn "notify_sms plugin is not avaible, cannot send alert via sms!"
fi
fi
# by Slack?
if (( DO_NOTIFY_SLACK == 1 ))
then
if (( HAS_NOTIFY_SLACK == 1 ))
then
# call plugin
notify_slack "${HC_NAME}" "${HC_FAIL_ID}"
else
warn "notify_slack plugin is not avaible, cannot send alert via Slack!"
fi
fi
fi
fi
@ -1350,6 +1460,7 @@ fi
function handle_timeout
{
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
# shellcheck disable=SC2086
[[ -n "${CHILD_PID}" ]] && kill -s TERM ${CHILD_PID}
warn "child process with PID ${CHILD_PID} has been forcefully stopped"
# shellcheck disable=SC2034
@ -1479,7 +1590,7 @@ esac
# mangle $ARG_HC to build the full list of HCs to be executed
ARG_HC=""
grep -i '^hc:' ${HOST_CONFIG_FILE} 2>/dev/null |\
grep -i '^hc:' "${HOST_CONFIG_FILE}" 2>/dev/null |\
while IFS=':' read -r _ HC_EXEC _ _
do
ARG_HC="${ARG_HC},${HC_EXEC}"
@ -1541,13 +1652,13 @@ case "${OS_NAME}" in
# check system crontabs
if (( CRON_COUNT == 0 ))
then
# shellcheck disable=SC2002
# shellcheck disable=SC2002,SC2086
CRON_COUNT=$(cat ${CRON_SYS_LOCATIONS} 2>/dev/null | grep -c -E -e "^[^#].*${CRON_HC}" 2>/dev/null)
fi
# check anacron
if (( CRON_COUNT == 0 ))
then
# shellcheck disable=SC2002
# shellcheck disable=SC2002,SC2086
CRON_COUNT=$(cat ${CRON_ANACRON_LOCATIONS} 2>/dev/null | grep -c -E -e "^[^#].*${CRON_HC}" 2>/dev/null)
fi
;;
@ -1557,6 +1668,7 @@ case "${OS_NAME}" in
;;
esac
# shellcheck disable=SC2086
return ${CRON_COUNT}
}
@ -1588,11 +1700,11 @@ printf "%80s\n" | tr ' ' -
print "${FPATH}" | tr ':' '\n' 2>/dev/null | grep "core$" | sort 2>/dev/null | while read -r FDIR
do
# exclude core helper librar(y|ies)
# shellcheck disable=SC2010
# shellcheck disable=SC2010,SC2086
ls -1 ${FDIR}/*.sh 2>/dev/null | grep -v "include_" | sort 2>/dev/null | while read -r FFILE
do
# cache script contents in memory
FSCRIPT=$(<${FFILE})
FSCRIPT="$(<${FFILE})"
# reset state
FSTATE="enabled"
@ -1634,12 +1746,12 @@ print -n "Dead links: "
print "${FPATH}" | tr ':' '\n' 2>/dev/null | grep "core$" 2>/dev/null | while read -r FDIR
do
# do not use 'find -type l' here!
# shellcheck disable=SC2010,SC1117
# shellcheck disable=SC2010,SC1117,SC2086
ls ${FDIR} 2>/dev/null | grep -v "\." 2>/dev/null | while read -r FFILE
do
if [[ -h "${FDIR}/${FFILE}" ]] && [[ ! -f "${FDIR}/${FFILE}" ]]
then
printf "%s " ${FFILE##*/}
printf "%s " "${FFILE##*/}"
fi
done
done
@ -1705,11 +1817,11 @@ fi
print "${FPATH}" | tr ':' '\n' 2>/dev/null | grep -v "core$" 2>/dev/null | sort 2>/dev/null |\
while read -r FDIR
do
# shellcheck disable=SC2012
# shellcheck disable=SC2012,SC2086
ls -1 ${FDIR}/${FNEEDLE} 2>/dev/null | sort 2>/dev/null | while read -r FFILE
do
# cache script contents in memory
FSCRIPT=$(<${FFILE})
FSCRIPT="$(<${FFILE})"
# --list (basic)
# find function name but skip helper functions in the plug-in file (function _name)
@ -1836,12 +1948,12 @@ then
print "${FPATH}" | tr ':' '\n' 2>/dev/null | grep -v "core" 2>/dev/null | while read -r FDIR
do
# do not use 'find -type l' here!
# shellcheck disable=SC2010,SC1117
# shellcheck disable=SC2010,SC1117,SC2086
ls ${FDIR} 2>/dev/null | grep -v "\." 2>/dev/null | while read -r FFILE
do
if [[ -h "${FDIR}/${FFILE}" ]] && [[ ! -f "${FDIR}/${FFILE}" ]]
then
printf "%s " ${FFILE##*/}
printf "%s " "${FFILE##*/}"
fi
done
done
@ -1899,11 +2011,11 @@ printf "%100s\n" | tr ' ' -
print "${FPATH}" | tr ':' '\n' 2>/dev/null | grep "core$" 2>/dev/null | sort 2>/dev/null | while read -r FDIR
do
# exclude core helper librar(y|ies)
# shellcheck disable=SC2010
# shellcheck disable=SC2010,SC2086
ls -1 ${FDIR}/*.sh 2>/dev/null | grep "include_" 2>/dev/null | sort 2>/dev/null | while read -r FFILE
do
# cache script contents in memory
FSCRIPT=$(<${FFILE})
FSCRIPT="$(<${FFILE})"
# find function name
FNAME=$(print -R "${FSCRIPT}" | grep -E -e "^function[[:space:]].*version_" 2>/dev/null)
@ -1936,12 +2048,12 @@ print -n "Dead links: "
print "${FPATH}" | tr ':' '\n' 2>/dev/null | grep "core$" 2>/dev/null | while read -r FDIR
do
# do not use 'find -type l' here!
# shellcheck disable=SC2010,SC1117
# shellcheck disable=SC2010,SC1117,SC2086
ls ${FDIR} 2>/dev/null | grep -v "\." 2>/dev/null | while read -r FFILE
do
if [[ -h "${FDIR}/${FFILE}" ]] && [[ ! -f "${FDIR}/${FFILE}" ]]
then
printf "%s " ${FFILE##*/}
printf "%s " "${FFILE##*/}"
fi
done
done
@ -1972,7 +2084,7 @@ then
then
print - "$*" | while read -r LOG_LINE
do
print "${NOW}: INFO: [$$]:" "${LOG_LINE}" >>${LOG_FILE}
print "${NOW}: INFO: [$$]:" "${LOG_LINE}" >>"${LOG_FILE}"
done
fi
if (( ARG_VERBOSE > 0 ))
@ -2041,7 +2153,7 @@ fi
# save the HC failure message for now
print "${HC_STC}${MSG_SEP}${HC_NOW}${MSG_SEP}${HC_MSG_TEXT}${MSG_SEP}${HC_MSG_CUR_VAL}${MSG_SEP}${HC_MSG_EXP_VAL}" \
>>${HC_MSG_FILE}
>>"${HC_MSG_FILE}"
return 0
}
@ -2096,13 +2208,14 @@ awk -F"${LOG_SEP}" '{
}
}
}
' ${HC_LOG} 2>/dev/null
' "${HC_LOG}" 2>/dev/null
# archived events
print; print
print -R "--- ARCHIVED events --"
print
find ${ARCHIVE_DIR} -type f -name "hc.*.log" 2>/dev/null | while read -r _ARCHIVE_FILE
# shellcheck disable=SC2086
find ${ARCHIVE_DIR} -type f -name "hc.*.log" 2>/dev/null | sort -rn 2>/dev/null | while read -r _ARCHIVE_FILE
do
print "${_ARCHIVE_FILE}:"
awk -F"${LOG_SEP}" '{
@ -2138,7 +2251,7 @@ do
}
}
}
' ${_ARCHIVE_FILE} 2>/dev/null
' "${_ARCHIVE_FILE}" 2>/dev/null
done
return 0
@ -2179,7 +2292,7 @@ then
then
print - "$*" | while read -r LOG_LINE
do
print "${NOW}: WARN: [$$]:" "${LOG_LINE}" >>${LOG_FILE}
print "${NOW}: WARN: [$$]:" "${LOG_LINE}" >>"${LOG_FILE}"
done
fi
if (( ARG_VERBOSE > 0 ))

View File

@ -30,7 +30,7 @@
# RETURNS: 0
function version_include_data
{
typeset _VERSION="2020-03-06" # YYYY-MM-DD
typeset _VERSION="2020-12-27" # YYYY-MM-DD
print "INFO: $0: ${_VERSION#version_*}"
@ -51,7 +51,7 @@ typeset _PARAMETER="${1}"
typeset _LVALUE=""
typeset _RC=0
_LVALUE=$(grep -i "^${_PARAMETER} *=" ${_CONFIG_FILE} | cut -f2- -d'=')
_LVALUE=$(grep -i "^${_PARAMETER} *=" "${_CONFIG_FILE}" | cut -f2- -d'=')
if [[ -n "${_LVALUE}" ]]
then
@ -637,7 +637,7 @@ case "${1}" in
return 1
fi
# check if X < Y
if $(print "${1}" | awk -F '-' '{ if ($1 < $2) { exit 1 }}' 2>/dev/null)
if print "${1}" | awk -F '-' '{ if ($1 < $2) { exit 1 }}' 2>/dev/null
then
(( ARG_DEBUG > 0 )) && debug "in range $1 operator Y is smaller or equal to operator Y"
return 1
@ -937,6 +937,7 @@ print ${_EPOCH}
# REQUIRES: n/a
function data_epoch2date
{
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
typeset _UNIX_EPOCH="${1}"
typeset _CONVERT_DATE=""
@ -962,6 +963,154 @@ fi
return 0
}
# -----------------------------------------------------------------------------
# @(#) FUNCTION: data_timestring_to_days()
# DOES: converts a specific timestring to days (rounded to integer)
# EXPECTS: time definition with a single s|m|h|d suffix [string]
# OUTPUTS: time value in hours [string]
# RETURNS: 0=conversion OK; 1=conversion failed
# REQUIRES: n/a
function data_timestring_to_days
{
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
typeset _DAYS=""
case "${1}" in
*s|*s)
_DAYS=$(( $(print "${1%*[sS]}") / 60 / 60 / 24 ))
;;
*m|*M)
_DAYS=$(( $(print "${1%*[mM]}") / 60 / 24 ))
;;
*h|*H)
_DAYS=$(( $(print "${1%*[hH]}") / 24 ))
;;
*d|*D)
_DAYS=$(print "${1%*[dD]}")
;;
*)
# invalid suffix specified
(( ARG_DEBUG > 0 )) && debug "invalid time suffix specified (only s[econds]|m[inutes]|h[ours]|d[days] allowed)"
return 1
;;
esac
print "${_DAYS}"
return 0
}
# -----------------------------------------------------------------------------
# @(#) FUNCTION: data_timestring_to_hours()
# DOES: converts a specific timestring to hours (rounded to integer)
# EXPECTS: time definition with a single s|m|h|d suffix [string]
# OUTPUTS: time value in hours [string]
# RETURNS: 0=conversion OK; 1=conversion failed
# REQUIRES: n/a
function data_timestring_to_hours
{
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
typeset _HOURS=""
case "${1}" in
*s|*s)
_HOURS=$(( $(print "${1%*[sS]}") / 60 / 24 ))
;;
*m|*M)
_HOURS=$(( $(print "${1%*[mM]}") / 60 ))
;;
*h|*H)
_HOURS=$(print "${1%*[hH]}")
;;
*d|*D)
_HOURS=$(( $(print "${1%*[dD]}") * 24 ))
;;
*)
# invalid suffix specified
(( ARG_DEBUG > 0 )) && debug "invalid time suffix specified (only s[econds]|m[inutes]|h[ours]|d[days] allowed)"
return 1
;;
esac
print "${_HOURS}"
return 0
}
# -----------------------------------------------------------------------------
# @(#) FUNCTION: data_timestring_to_mins()
# DOES: converts a specific timestring to minutes (rounded to integer)
# EXPECTS: time definition with a single s|m|h|d suffix [string]
# OUTPUTS: time value in minutes [string]
# RETURNS: 0=conversion OK; 1=conversion failed
# REQUIRES: n/a
function data_timestring_to_mins
{
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
typeset _MINUTES=""
case "${1}" in
*s|*s)
_MINUTES=$(( $(print "${1%*[sS]}") / 60 ))
;;
*m|*M)
_MINUTES=$(print "${1%*[mM]}")
;;
*h|*H)
_MINUTES=$(( $(print "${1%*[hH]}") * 60 ))
;;
*d|*D)
_MINUTES=$(( $(print "${1%*[dD]}") * 60 * 24 ))
;;
*)
# invalid suffix specified
(( ARG_DEBUG > 0 )) && debug "invalid time suffix specified (only s[econds]|m[inutes]|h[ours]|d[days] allowed)"
return 1
;;
esac
print "${_MINUTES}"
return 0
}
# -----------------------------------------------------------------------------
# @(#) FUNCTION: data_timestring_to_secs()
# DOES: converts a specific timestring to seconds (rounded to integer)
# EXPECTS: time definition with a single m|h|d suffix [string]
# OUTPUTS: time value in seconds [string]
# RETURNS: 0=conversion OK; 1=conversion failed
# REQUIRES: n/a
function data_timestring_to_secs
{
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
typeset _SECONDS=""
case "${1}" in
*s|*s)
_SECONDS=$(print "${1%*[sS]}")
;;
*m|*M)
_SECONDS=$(( $(print "${1%*[Mm]}") * 60 ))
;;
*h|*H)
_SECONDS=$(( $(print "${1%*[hH]}") * 60 * 60 ))
;;
*d|*D)
_SECONDS=$(( $(print "${1%*[dD]}") * 60 * 60 * 24 ))
;;
*)
# invalid suffix specified
(( ARG_DEBUG > 0 )) && debug "invalid time suffix specified (only s[econds]|m[inutes]|h[ours]|d[days] allowed)"
return 1
;;
esac
print "${_SECONDS}"
return 0
}
#******************************************************************************
# END of script
#******************************************************************************

View File

@ -30,7 +30,7 @@
function notify_mail
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _VERSION="2019-04-20" # YYYY-MM-DD
typeset _VERSION="2022-02-16" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="AIX,HP-UX,Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
@ -58,6 +58,7 @@ typeset _MAIL_ATTACH_BIT=""
typeset _MAIL_METHOD=""
typeset _MAIL_RC=0
typeset _MAILX_BIN=""
typeset _MAILX_ATTACH_SWITCH=""
typeset _MUTT_BIN=""
typeset _SENDMAIL_BIN=""
typeset _UUENCODE_BIN=""
@ -90,6 +91,17 @@ case "${OS_NAME}" in
if [[ -x ${_MAILX_BIN} ]] && [[ -n "${_MAILX_BIN}" ]]
then
_MAIL_METHOD="mailx"
# check which switch we need for attaching a file:
# Debian/Ubuntu: -A file
# Redhat (Heirloom version): -a file
${_MAILX_BIN} -h 2>&1 | grep -q -e "-a FILE" >/dev/null 2>/dev/null
# shellcheck disable=SC2181
if (( $? == 0 ))
then
_MAILX_ATTACH_SWITCH="-a "
else
_MAILX_ATTACH_SWITCH="-A "
fi
else
_MAIL_METHOD="sendmail"
fi
@ -122,18 +134,18 @@ then
[[ -r "${_MAIL_INFO_TPL}" ]] || die "cannot read mail info template at ${_MAIL_INFO_TPL}"
eval "cat << __EOT
$(sed 's/[\$`]/\\&/g;s/<## @\([^ ]*\) ##>/${\1}/g' <${_MAIL_INFO_TPL})
__EOT" >${_TMP1_MAIL_FILE}
__EOT" >"${_TMP1_MAIL_FILE}"
fi
# create header part
[[ -r "${_MAIL_HEADER_TPL}" ]] || die "cannot read mail header template at ${_MAIL_HEADER_TPL}"
eval "cat << __EOT
$(sed 's/[\$`]/\\&/g;s/<## @\([^ ]*\) ##>/${\1}/g' <${_MAIL_HEADER_TPL})
__EOT" >>${_TMP1_MAIL_FILE}
print "" >>${_TMP1_MAIL_FILE}
__EOT" >>"${_TMP1_MAIL_FILE}"
print "" >>"${_TMP1_MAIL_FILE}"
# create body part (from $HC_MSG_VAR)
print "${HC_MSG_VAR}" | while IFS=${MSG_SEP} read _MAIL_MSG_STC _ _MAIL_MSG_TEXT _MAIL_MSG_CUR_VAL _MAIL_MSG_EXP_VAL
print "${HC_MSG_VAR}" | while IFS=${MSG_SEP} read -r _MAIL_MSG_STC _ _MAIL_MSG_TEXT _MAIL_MSG_CUR_VAL _MAIL_MSG_EXP_VAL
do
# magically unquote if needed
if [[ -n "${_MAIL_MSG_TEXT}" ]]
@ -175,8 +187,8 @@ done
[[ -r "${_MAIL_BODY_TPL}" ]] || die "cannot read mail body template at ${_MAIL_BODY_TPL}"
eval "cat << __EOT
$(sed 's/[\$`]/\\&/g;s/<## @\([^ ]*\) ##>/${\1}/g' <${_MAIL_BODY_TPL})
__EOT" >>${_TMP1_MAIL_FILE}
print "" >>${_TMP1_MAIL_FILE}
__EOT" >>"${_TMP1_MAIL_FILE}"
print "" >>"${_TMP1_MAIL_FILE}"
# HC STDOUT log? (drop the .$$ bit)
_MAIL_STDOUT_LOG="${EVENTS_DIR}/${DIR_PREFIX}/${_MAIL_FAIL_ID}/${_HC_STDOUT_LOG_SHORT%.*}"
@ -184,7 +196,14 @@ if [[ -s "${_MAIL_STDOUT_LOG}" ]]
then
# shellcheck disable=SC2034
_MAIL_STDOUT_MSG="${_MAIL_STDOUT_LOG}"
case "${_MAIL_METHOD}" in
"mailx")
_MAIL_ATTACH_BIT="${_MAILX_ATTACH_SWITCH} ${_MAIL_STDOUT_LOG}"
;;
*)
_MAIL_ATTACH_BIT="-a ${_MAIL_STDOUT_LOG}"
;;
esac
else
# shellcheck disable=SC2034
_MAIL_STDOUT_MSG="no log file available"
@ -195,7 +214,14 @@ if [[ -s "${_MAIL_STDERR_LOG}" ]]
then
# shellcheck disable=SC2034
_MAIL_STDERR_MSG="${_MAIL_STDERR_LOG}"
case "${_MAIL_METHOD}" in
"mailx")
_MAIL_ATTACH_BIT="${_MAIL_ATTACH_BIT} ${_MAILX_ATTACH_SWITCH} ${_MAIL_STDERR_LOG}"
;;
*)
_MAIL_ATTACH_BIT="${_MAIL_ATTACH_BIT} -a ${_MAIL_STDERR_LOG}"
;;
esac
else
# shellcheck disable=SC2034
_MAIL_STDERR_MSG="no log file available"
@ -205,28 +231,29 @@ fi
[[ -r ${_MAIL_FOOTER_TPL} ]] || die "cannot read mail body template at ${_MAIL_FOOTER_TPL}"
eval "cat << __EOT
$(sed 's/[\$`]/\\&/g;s/<## @\([^ ]*\) ##>/${\1}/g' <${_MAIL_FOOTER_TPL})
__EOT" >>${_TMP1_MAIL_FILE}
__EOT" >>"${_TMP1_MAIL_FILE}"
# combine and send message components
case "${_MAIL_METHOD}" in
"mailx")
# remove non-ASCII characters to avoid Exchange ATT00001.bin
cat ${_TMP1_MAIL_FILE} | tr -cd '[:print:]\n' 2>/dev/null |\
# shellcheck disable=SC2086
tr -cd '[:print:]\n' < "${_TMP1_MAIL_FILE}" 2>/dev/null |\
${_MAILX_BIN} ${_MAIL_ATTACH_BIT} -s "${_SUBJ_MSG}" "${ARG_MAIL_TO}"
_MAIL_RC=$?
;;
"mutt")
# attach bit goes at the end
cat ${_TMP1_MAIL_FILE} 2>/dev/null |\
${_MUTT_BIN} -s "${_SUBJ_MSG}" "${ARG_MAIL_TO}" ${_MAIL_ATTACH_BIT}
# shellcheck disable=SC2086
${_MUTT_BIN} -s "${_SUBJ_MSG}" "${ARG_MAIL_TO}" ${_MAIL_ATTACH_BIT} <"${_TMP1_MAIL_FILE}"
_MAIL_RC=$?
;;
"sendmail")
[[ -s "${_MAIL_STDOUT_LOG}" ]] && \
uuencode ${_MAIL_STDOUT_LOG} stdout.log >>${_TMP2_MAIL_FILE} 2>/dev/null
uuencode "${_MAIL_STDOUT_LOG}" stdout.log >>"${_TMP2_MAIL_FILE}" 2>/dev/null
[[ -s "${_MAIL_STDERR_LOG}" ]] && \
uuencode ${_MAIL_STDERR_LOG} stderr.log >>${_TMP2_MAIL_FILE} 2>/dev/null
cat ${_TMP1_MAIL_FILE} ${_TMP2_MAIL_FILE} 2>/dev/null | ${_SENDMAIL_BIN} -t
uuencode "${_MAIL_STDERR_LOG}" stderr.log >>"${_TMP2_MAIL_FILE}" 2>/dev/null
cat "${_TMP1_MAIL_FILE}" "${_TMP2_MAIL_FILE}" 2>/dev/null | ${_SENDMAIL_BIN} -t
_MAIL_RC=$?
;;
*)
@ -242,8 +269,8 @@ else
fi
# clean up temporary files
[[ -f ${_TMP1_MAIL_FILE} ]] && rm -f ${_TMP1_MAIL_FILE} >/dev/null 2>&1
[[ -f ${_TMP2_MAIL_FILE} ]] && rm -f ${_TMP2_MAIL_FILE} >/dev/null 2>&1
[[ -f ${_TMP1_MAIL_FILE} ]] && rm -f "${_TMP1_MAIL_FILE}" >/dev/null 2>&1
[[ -f ${_TMP2_MAIL_FILE} ]] && rm -f "${_TMP2_MAIL_FILE}" >/dev/null 2>&1
return 0
}

View File

@ -0,0 +1,135 @@
#!/usr/bin/env ksh
#******************************************************************************
# @(#) notify_slack.sh
#******************************************************************************
# @(#) Copyright (C) 2022 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#******************************************************************************
#
# DOCUMENTATION (MAIN)
# -----------------------------------------------------------------------------
# @(#) MAIN: notify_slack
# DOES: send message to slack app
# EXPECTS: 1=HC name [string], 2=HC FAIL_ID [string]
# RETURNS: 0
# REQUIRES: data_contains_string(), data_get_lvalue_from_config(), data_magic_unquote(),
# init_hc(), log(), warn(), curl
#
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
# -----------------------------------------------------------------------------
function notify_slack
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/core/providers/$0.conf"
typeset _VERSION="2022-10-14" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="AIX,HP-UX,Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _SLACK_HC="$1"
typeset _SLACK_FAIL_ID="$2"
typeset _SLACK_TEXT=""
typeset _SLACK_MSG_STC=""
typeset _SLACK_MSG_TEXT=""
typeset _SLACK_MSG_CUR_VAL=""
typeset _SLACK_MSG_EXP_VAL=""
typeset _CURL_BIN=""
typeset _SLACK_WEBHOOK=""
# handle config file
if [[ ! -r ${_CONFIG_FILE} ]]
then
warn "unable to read configuration file at ${_CONFIG_FILE}"
return 1
fi
# read required config values
_SLACK_WEBHOOK=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'SLACK_WEBHOOK')
if [[ -z "${_SLACK_WEBHOOK}" ]]
then
warn "no value set for 'SLACK_WEBHOOK' in ${_CONFIG_FILE}"
return 1
fi
# create header part
_SLACK_TEXT="${EXEC_USER}@${HOST_NAME}: HC ${_SLACK_HC} failed, FAIL_ID=${_SLACK_FAIL_ID}"
# create body part (from $HC_MSG_VAR)
print "${HC_MSG_VAR}" | while IFS=${MSG_SEP} read -r _SLACK_MSG_STC _ _SLACK_MSG_TEXT _SLACK_MSG_CUR_VAL _SLACK_MSG_EXP_VAL
do
# magically unquote if needed
if [[ -n "${_SLACK_MSG_TEXT}" ]]
then
data_contains_string "${_SLACK_MSG_TEXT}" "${MAGIC_QUOTE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
_SLACK_MSG_TEXT=$(data_magic_unquote "${_SLACK_MSG_TEXT}")
fi
fi
if [[ -n "${_SLACK_MSG_CUR_VAL}" ]]
then
data_contains_string "${_SLACK_MSG_CUR_VAL}" "${MAGIC_QUOTE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
_SLACK_MSG_CUR_VAL=$(data_magic_unquote "${_SLACK_MSG_CUR_VAL}")
fi
fi
if [[ -n "${_SLACK_MSG_EXP_VAL}" ]]
then
data_contains_string "${_SLACK_MSG_EXP_VAL}" "${MAGIC_QUOTE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
_SLACK_MSG_EXP_VAL=$(data_magic_unquote "${_SLACK_MSG_EXP_VAL}")
fi
fi
if (( _SLACK_MSG_STC > 0 ))
then
# shellcheck disable=SC1117
_SLACK_BODY=$(printf "%s\n%s\n" "${_SLACK_BODY}" "${_SLACK_MSG_TEXT}")
fi
done
# send message
# find 'curl'
_CURL_BIN="$(command -v curl 2>/dev/null)"
if [[ -x ${_CURL_BIN} ]] && [[ -n "${_CURL_BIN}" ]]
then
if (( ARG_DEBUG == 0 ))
then
${_CURL_BIN} --silent --data-urlencode \
"$(printf 'payload={"text": "%s\n\n%s" }' "${_SLACK_TEXT}" "${_SLACK_BODY}")" \
"${_SLACK_WEBHOOK}" >/dev/null 2>&1
else
${_CURL_BIN} --data-urlencode \
"$(printf 'payload={"text": "%s\n\n%s" }' "${_SLACK_TEXT}" "${_SLACK_BODY}")" \
"${_SLACK_WEBHOOK}"
fi
else
die "unable to send message to Slack - curl is not installed here"
fi
log "Slack alert sent: ${_SLACK_HC} failed, FAIL_ID=${_SLACK_FAIL_ID}"
return 0
}
#******************************************************************************
# END of script
#******************************************************************************

View File

@ -20,7 +20,8 @@
# DOES: send sms alert
# EXPECTS: 1=HC name [string], 2=HC FAIL_ID [string]
# RETURNS: 0
# REQUIRES: data_get_lvalue_from_config(), init_hc(), log(), warn()
# REQUIRES: data_encode_url(), data_get_lvalue_from_config(), init_hc(),
# log(), warn(), curl
#
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
@ -31,7 +32,7 @@ function notify_sms
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/core/providers/$0.conf"
typeset _VERSION="2018-10-28" # YYYY-MM-DD
typeset _VERSION="2022-10-14" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="AIX,HP-UX,Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------

View File

@ -30,6 +30,7 @@
# @(#) 2019-03-09: added support for --log-healthy [Patrick Van der Veken]
# @(#) 2019-03-16: replace 'which' [Patrick Van der Veken]
# @(#) 2020-09-05: fix log_hc call for failed checksum + quote fix [Patrick Van der Veken]
# @(#) 2021-01-13: fix log_hc call (wrong logic) [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
@ -39,7 +40,7 @@ function check_aix_file_change
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2020-09-05" # YYYY-MM-DD
typeset _VERSION="2021-01-13" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
@ -322,7 +323,7 @@ do
fi
# bounce failures back and jump to next file
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
if (( _LOG_HEALTHY > 0 && _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
continue

View File

@ -0,0 +1,349 @@
#!/usr/bin/env ksh
#------------------------------------------------------------------------------
# @(#) check_aix_uptime
#------------------------------------------------------------------------------
# @(#) Copyright (C) 2020 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#------------------------------------------------------------------------------
#
# DOCUMENTATION (MAIN)
# -----------------------------------------------------------------------------
# @(#) MAIN: check_aix_uptime
# DOES: see _show_usage()
# EXPECTS: see _show_usage()
# REQUIRES: data_is_numeric(), data_timestring_to_mins(), data_comma2space(),
# init_hc(), log_hc(), warn()
#
# @(#) HISTORY:
# @(#) 2020-12-21: initial version [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------
function check_aix_uptime
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _STATE_FILE="${STATE_PERM_DIR}/current.uptime"
typeset _VERSION="2020-12-21" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="AIX" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
typeset _MSG=""
typeset _STC=0
typeset _LOG_HEALTHY=0
typeset _CFG_HEALTHY=""
typeset _CFG_CHECK_REBOOT=""
typeset _CFG_REBOOT_TIME=""
typeset _CFG_CHECK_OLD_AGE=""
typeset _CFG_OLD_AGE_TIME=""
typeset _CHECK_REBOOT=""
typeset _REBOOT_TIME=""
typeset _REBOOT_TIME_MINS=""
typeset _CHECK_OLD_AGE=""
typeset _OLD_AGE_TIME=""
typeset _OLD_AGE_TIME_MINS=""
typeset _CURRENT_UPTIME=""
typeset _CURRENT_UPTIME_MINS=""
typeset _INIT_TIME=""
typeset _PREVIOUS_UPTIME=""
typeset _PREVIOUS_UPTIME_MINS=""
typeset _THRESHOLD_UPTIME_MINS=""
# handle arguments (originally comma-separated)
for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage "$0" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
# handle config file
[[ -n "${ARG_CONFIG_FILE}" ]] && _CONFIG_FILE="${ARG_CONFIG_FILE}"
if [[ ! -r ${_CONFIG_FILE} ]]
then
warn "unable to read configuration file at ${_CONFIG_FILE}"
return 1
fi
# read required config values
_CFG_HEALTHY=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'log_healthy')
case "${_CFG_HEALTHY}" in
yes|YES|Yes)
_LOG_HEALTHY=1
;;
*)
# do not override hc_arg
(( _LOG_HEALTHY > 0 )) || _LOG_HEALTHY=0
;;
esac
_CFG_CHECK_REBOOT=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'check_reboot')
case "${_CFG_CHECK_REBOOT}" in
no|No|NO)
_CHECK_REBOOT=0
;;
*)
_CHECK_REBOOT=1
;;
esac
_CFG_REBOOT_TIME=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'reboot_time')
if [[ -z "${_CFG_REBOOT_TIME}" ]]
then
# default
_REBOOT_TIME="60m"
else
_REBOOT_TIME="${_CFG_REBOOT_TIME}"
fi
_CFG_CHECK_OLD_AGE=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'check_old_age')
case "${_CFG_CHECK_OLD_AGE}" in
yes|Yes|Yes)
_CHECK_OLD_AGE=1
;;
*)
_CHECK_OLD_AGE=0
;;
esac
_CFG_OLD_AGE_TIME=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'old_age_time')
if [[ -z "${_CFG_OLD_AGE_TIME}" ]]
then
# default
_OLD_AGE_TIME="365d"
else
_OLD_AGE_TIME="${_CFG_OLD_AGE_TIME}"
fi
# log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
if (( _LOG_HEALTHY > 0 ))
then
if (( ARG_LOG > 0 ))
then
log "logging/showing passed health checks"
else
log "showing passed health checks (but not logging)"
fi
else
log "not logging/showing passed health checks"
fi
#------------------------------------------------------------------------------
# read uptime from init process
# shellcheck disable=SC1007
_INIT_TIME=$(UNIX95= ps -p 1 -o etime 2>/dev/null | tail -1)
if [[ -n "${_INIT_TIME}" ]]
then
# calculate exact uptime (seconds)
_CURRENT_UPTIME=$(print "${_INIT_TIME}" |\
awk '
BEGIN { days = 0; hours = 0; mins = 0; seconds = 0 };
{
gsub(/[ \t]/, "");
# get days
split ($0, day_str, "-");
if (2 in day_str) {
# string has days
days = day_str[1];
split (day_str[2], hour_str, ":");
} else {
split (day_str[1], hour_str, ":");
}
# get hours/minutes/seconds
hours = hour_str[1];
mins = hour_str[2];
if (3 in hour_str) {
# string has seconds
secs = hour_str[3];
}
}
END {
time = (days * 24 * 60 * 60) + (hours * 60 * 60) + (mins * 60) + secs;
print time;
}' 2>/dev/null)
data_is_numeric "${_CURRENT_UPTIME}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate uptime value (seconds)"
(( ARG_DEBUG )) && debug "_CURRENT_UPTIME=${_CURRENT_UPTIME}"
return 1
fi
else
warn "uptime of INIT (1) process cannot be determined"
return 1
fi
#------------------------------------------------------------------------------
# read state file
if [[ -r ${_STATE_FILE} ]]
then
_PREVIOUS_UPTIME=$(<"${_STATE_FILE}")
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to read state file at ${_STATE_FILE}"
_PREVIOUS_UPTIME=""
fi
fi
#------------------------------------------------------------------------------
# convert uptimes values
_CURRENT_UPTIME_MINS=$(( _CURRENT_UPTIME / 60 ))
data_is_numeric "${_CURRENT_UPTIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate current uptime value (minutes)"
(( ARG_DEBUG )) && debug "_CURRENT_UPTIME_MINS=${_CURRENT_UPTIME_MINS}"
return 1
fi
_PREVIOUS_UPTIME_MINS=$(( _PREVIOUS_UPTIME / 60 ))
data_is_numeric "${_CURRENT_UPTIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate previous uptime value (minutes)"
(( ARG_DEBUG )) && debug "_PREVIOUS_UPTIME_MINS=${_PREVIOUS_UPTIME_MINS}"
return 1
fi
#------------------------------------------------------------------------------
# check reboot event
if (( _CHECK_REBOOT > 0 ))
then
# convert _REBOOT_TIME to minutes
_REBOOT_TIME_MINS=$(data_timestring_to_mins "${_REBOOT_TIME}")
data_is_numeric "${_REBOOT_TIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate 'reboot_time' value from configuration file ${_CONFIG_FILE}"
(( ARG_DEBUG )) && debug "_REBOOT_TIME=${_REBOOT_TIME}"
return 1
fi
# previous uptime missing?
if [[ -z "${_PREVIOUS_UPTIME}" ]]
then
if (( ARG_LOG > 0 ))
then
print "${_CURRENT_UPTIME}" >"${_STATE_FILE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to update state file at ${_STATE_FILE}"
return 1
else
log "unable to find previously recorded uptime, resetting to current uptime"
return 0
fi
else
log "unable to find previously recorded uptime, resetting to current uptime"
fi
else
# current uptime + reboot time is smaller than previous uptime?
_THRESHOLD_UPTIME_MINS=$(( _CURRENT_UPTIME_MINS + _REBOOT_TIME_MINS ))
if (( _THRESHOLD_UPTIME_MINS < _PREVIOUS_UPTIME_MINS ))
then
_MSG="reboot check: current uptime is NOK; check if reboot occurred"
_STC=1
else
_MSG="reboot check: current uptime is OK"
_STC=0
fi
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}" "${_THRESHOLD_UPTIME_MINS}" "${_PREVIOUS_UPTIME_MINS}"
fi
# update state file
if (( ARG_LOG > 0 ))
then
print "${_CURRENT_UPTIME}" >"${_STATE_FILE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to update state file at ${_STATE_FILE}"
return 1
fi
fi
else
log "reboot check: not enabled"
fi
#------------------------------------------------------------------------------
# check old age event
if (( _CHECK_OLD_AGE > 0 ))
then
# convert _OLD_AGE_TIME to minutes
_OLD_AGE_TIME_MINS=$(data_timestring_to_mins "${_OLD_AGE_TIME}")
data_is_numeric "${_OLD_AGE_TIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate 'old_age_time' value from configuration file ${_CONFIG_FILE}"
(( ARG_DEBUG )) && debug "_OLD_AGE_TIME=${_OLD_AGE_TIME}"
return 1
fi
# are we old age yet?
if (( _CURRENT_UPTIME_MINS > _OLD_AGE_TIME_MINS ))
then
_MSG="old_age check: current uptime is NOK; old age has arrived (>${_OLD_AGE_TIME})"
_STC=1
else
_MSG="old_age check: current uptime is OK"
_STC=0
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}" "${_CURRENT_UPTIME_MINS}" "${_OLD_AGE_TIME_MINS}"
fi
else
log "old age check: not enabled"
fi
return 0
}
# -----------------------------------------------------------------------------
function _show_usage
{
cat <<- EOT
NAME : $1
VERSION : $2
CONFIG : $3 with:
log_healthy=<yes|no>
check_reboot=<yes|no>
reboot_time=<timestring>
check_old_age=<yes|no>
old_age_time=<timestring>
PURPOSE : Checks for unexpected/unplanned reboot events based on uptime
values.
Checks whether the host has been up and running for too much time.
LOG HEALTHY : Supported
EOT
return 0
}
#------------------------------------------------------------------------------
# END of script
#------------------------------------------------------------------------------

View File

@ -19,12 +19,13 @@
# @(#) MAIN: check_hpux_cron_status
# DOES: see _show_usage()
# EXPECTS: n/a
# REQUIRES: data_comma2space(), init_hc(), log_hc()
# REQUIRES: data_is_numeric(), data_comma2space(), init_hc(), log_hc()
#
# @(#) HISTORY:
# @(#) 2018-02-08: initial version [Patrick Van der Veken]µ
# @(#) 2018-02-13: fix to avoid log check if cron is not active [Patrick Van der Veken]
# @(#) 2019-03-16: replace 'which' [Patrick Van der Veken]
# @(#) 2021-03-25: make _WAIT_TIME & _CRON_LOG_FILE configurable [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
@ -33,20 +34,25 @@
function check_hpux_cron_status
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CRON_LOG_FILE="/var/adm/cron/log"
typeset _WAIT_TIME=10
typeset _VERSION="2019-02-16" # YYYY-MM-DD
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2021-03-25" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="HP-UX" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set ${DEBUG_OPTS}
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
typeset _MSG=""
typeset _STC=0
typeset _CFG_HEALTHY=""
typeset _LOG_HEALTHY=0
typeset _CFG_CRON_LOG_FILE=""
typeset _CFG_WAIT_TIME=""
typeset _LOG_HEALTHY=0
typeset _CRON_LOG_FILE=""
typeset _WAIT_TIME=""
typeset _JOB_ID=""
typeset _AT_BIN=""
@ -55,11 +61,56 @@ for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage $0 ${_VERSION} ${_CONFIG_FILE} && return 0
_show_usage "${0}" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
# handle configuration file
[[ -n "${ARG_CONFIG_FILE}" ]] && _CONFIG_FILE="${ARG_CONFIG_FILE}"
if [[ ! -r ${_CONFIG_FILE} ]]
then
warn "unable to read configuration file at ${_CONFIG_FILE}"
return 1
fi
_CFG_WAIT_TIME=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'wait_time')
if [[ -z "${_CFG_WAIT_TIME}" ]]
then
# default
_WAIT_TIME=10
log "setting value for parameter wait_time to its default (${_WAIT_TIME})"
else
data_is_numeric "${_CFG_WAIT_TIME}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "wait time parameter is not numeric in configuration file ${_CONFIG_FILE}"
return 1
else
_WAIT_TIME=${_CFG_WAIT_TIME}
fi
fi
_CFG_CRON_LOG_FILE=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'cron_log')
if [[ -z "${_CFG_CRON_LOG_FILE}" ]]
then
# default
_CRON_LOG_FILE="/var/adm/cron/log"
log "setting value for parameter cron_log to its default (${_CRON_LOG_FILE})"
else
_CRON_LOG_FILE="${_CFG_CRON_LOG_FILE}"
log "setting value for parameter cron_log (${_CRON_LOG_FILE})"
fi
_CFG_HEALTHY=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'log_healthy')
case "${_CFG_HEALTHY}" in
yes|YES|Yes)
_LOG_HEALTHY=1
;;
*)
# do not override hc_arg
(( _LOG_HEALTHY > 0 )) || _LOG_HEALTHY=0
;;
esac
# log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
if (( _LOG_HEALTHY > 0 ))
@ -74,10 +125,20 @@ else
log "not logging/showing passed health checks"
fi
# check timeout (_WAIT_TIME must be at least 30 secs smaller than health check timeout)
if (( _WAIT_TIME > 0 ))
then
if (( (_WAIT_TIME + 30) > HC_TIME_OUT ))
then
warn "wait time value will conflict with health check timeout. Specify a (larger) --timeout value"
return 1
fi
fi
# ---- process state ----
# try the pgrep way (note: old pgreps do not support '-c')
(( ARG_DEBUG > 0 )) && debug "checking cron service via pgrep"
(( $(pgrep -u root cron 2>>${HC_STDERR_LOG} | wc -l 2>/dev/null) == 0 )) && _STC=1
(( $(pgrep -u root cron 2>>"${HC_STDERR_LOG}" | wc -l 2>/dev/null) == 0 )) && _STC=1
# evaluate results
case ${_STC} in
@ -99,18 +160,30 @@ then
fi
# ---- log state ----
_AT_BIN="$(command -v at 2>>${HC_STDERR_LOG})"
# check cron log file
if [[ ! -r ${_CRON_LOG_FILE} ]]
then
_MSG="cron log does not exist (${_CRON_LOG_FILE})"
_STC=1
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" 1 "${_MSG}"
fi
return 0
fi
# create test event
_AT_BIN=$(command -v at 2>>"${HC_STDERR_LOG}")
if [[ -x ${_AT_BIN} && -n "${_AT_BIN}" ]]
then
# start test job
(( ARG_DEBUG > 0 )) && debug "checking cron log via {${_AT_BIN}}"
(echo "*** CHECK LOG ***" >/dev/null | ${_AT_BIN} now) >>${HC_STDOUT_LOG} 2>>${HC_STDERR_LOG}
sleep ${_WAIT_TIME}
if (( $(grep -c 'cron may not be running' ${HC_STDERR_LOG} 2>/dev/null) == 0 ))
(echo "*** CHECK LOG ***" >/dev/null | ${_AT_BIN} now) >>"${HC_STDOUT_LOG}" 2>>"${HC_STDERR_LOG}"
sleep "${_WAIT_TIME}"
if (( $(grep -c 'cron may not be running' "${HC_STDERR_LOG}" 2>/dev/null) == 0 ))
then
# find job results
_JOB_ID=$(grep -E -e '^job' ${HC_STDERR_LOG} 2>/dev/null | awk '{ print $2}' 2>/dev/null)
if [[ -n "${_JOB_ID}" ]] && (( $(grep -c "${_JOB_ID}" ${_CRON_LOG_FILE} 2>/dev/null) > 0 ))
_JOB_ID=$(grep -E -e '^job' "${HC_STDERR_LOG}" 2>/dev/null | awk '{ print $2}' 2>/dev/null)
if [[ -n "${_JOB_ID}" ]] && (( $(grep -c "${_JOB_ID}" "${_CRON_LOG_FILE}" 2>/dev/null) > 0 ))
then
_MSG="cron is logging correctly, schedule via {${_AT_BIN}} OK"
_STC=0
@ -125,7 +198,7 @@ then
else
# check cron log itself
(( ARG_DEBUG > 0 )) && debug "checking cron log via file check"
if [[ -r ${_CRON_LOG_FILE} ]] && [[ -s ${_CRON_LOG_FILE} ]]
if [[ -s ${_CRON_LOG_FILE} ]]
then
_MSG="cron is logging correctly (${_CRON_LOG_FILE})"
_STC=0
@ -148,9 +221,12 @@ function _show_usage
cat <<- EOT
NAME : $1
VERSION : $2
CONFIG : $3
CONFIG : $3 with parameters:
log_healthy=<yes|no>
wait_time=<seconds>
cron_log=<file_path>
PURPOSE : Checks whether cron (CRON) service is running and whether cron is
actually logging to ${_CRON_LOG_FILE}.
actually logging to the cron log file.
LOG HEALTHY : Supported
EOT

View File

@ -0,0 +1,212 @@
#!/usr/bin/env ksh
#******************************************************************************
# @(#) check_hpux_defunct_processes.sh
#******************************************************************************
# @(#) Copyright (C) 2021 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#******************************************************************************
#
# DOCUMENTATION (MAIN)
# -----------------------------------------------------------------------------
# @(#) MAIN: check_hpux_defunct_processes
# DOES: see _show_usage()
# EXPECTS: n/a
# REQUIRES: data_comma2space(), data_is_numeric(), init_hc(), log_hc()
#
# @(#) HISTORY:
# @(#) 2021-04-07: initial version [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
# -----------------------------------------------------------------------------
function check_hpux_defunct_processes
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2021-04-07" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="HP-UX" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
typeset _MSG=""
typeset _STC=0
typeset _CFG_GROUP_BY_PPID=""
typeset _GROUP_BY_PPID=""
typeset _CFG_PROCESS_THRESHOLD=""
typeset _PROCESS_THRESHOLD=""
typeset _CFG_HEALTHY=""
typeset _LOG_HEALTHY=0
typeset _DEFUNCT_PROCS=""
typeset _NUM_DEFUNCT_PROCS=""
typeset _PPID=""
# handle arguments (originally comma-separated)
for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage "${0}" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
# handle configuration file
[[ -n "${ARG_CONFIG_FILE}" ]] && _CONFIG_FILE="${ARG_CONFIG_FILE}"
if [[ ! -r ${_CONFIG_FILE} ]]
then
warn "unable to read configuration file at ${_CONFIG_FILE}"
return 1
fi
# read required configuration values
_CFG_PROCESS_THRESHOLD=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'process_threshold')
if [[ -z "${_CFG_PROCESS_THRESHOLD}" ]]
then
# default
_PROCESS_THRESHOLD=10
log "setting value for parameter process_threshold to its default (10)"
else
data_is_numeric "${_CFG_PROCESS_THRESHOLD}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "value for parameter process_threshold in configuration file ${_CONFIG_FILE} is invalid"
return 1
else
_PROCESS_THRESHOLD=${_CFG_PROCESS_THRESHOLD}
log "setting value for parameter collect_interval (${_PROCESS_THRESHOLD})"
fi
fi
_CFG_GROUP_BY_PPID=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'group_by_ppid')
case "${_CFG_GROUP_BY_PPID}" in
no|NO|No)
_GROUP_BY_PPID=0
log "setting value for parameter group_by_ppid (No)"
;;
*)
# default
_GROUP_BY_PPID=1
log "setting value for parameter group_by_ppid to its default (Yes)"
;;
esac
_CFG_HEALTHY=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'log_healthy')
case "${_CFG_HEALTHY}" in
yes|YES|Yes)
_LOG_HEALTHY=1
;;
*)
# do not override hc_arg
(( _LOG_HEALTHY > 0 )) || _LOG_HEALTHY=0
;;
esac
# log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
if (( _LOG_HEALTHY > 0 ))
then
if (( ARG_LOG > 0 ))
then
log "logging/showing passed health checks"
else
log "showing passed health checks (but not logging)"
fi
else
log "not logging/showing passed health checks"
fi
# collect defunct processes
# shellcheck disable=SC2009
_DEFUNCT_PROCS=$(UNIX95=1 ps -eo ppid,pid,comm,etime 2>"${HC_STDERR_LOG}" | tee -a "${HC_STDOUT_LOG}" 2>/dev/null | grep '[d]efunct' 2>/dev/null)
# check defunct processes
if [[ -z "${_DEFUNCT_PROCS}" ]]
then
_MSG="no defunct process(es) detected"
_STC=0
if (( _LOG_HEALTHY > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
return 0
else
if (( _GROUP_BY_PPID > 0 ))
then
# per by PPID
print -R "${_DEFUNCT_PROCS}" | awk '
{
# count PIDs per PPID
counts[$1]++;
}
END {
for (i in counts) print i ":" counts[i]
}' 2>/dev/null | while IFS=":" read -r _PPID _NUM_DEFUNCT_PROCS
do
(( ARG_DEBUG > 0 )) && debug "awk found PPID: ${_PPID} with # procs: ${_NUM_DEFUNCT_PROCS}"
if (( _NUM_DEFUNCT_PROCS <= _PROCESS_THRESHOLD ))
then
_MSG="defunct process(es) detected for PPID (${_PPID}) but are still under threshold (${_NUM_DEFUNCT_PROCS}<=${_PROCESS_THRESHOLD})"
_STC=0
else
_MSG="defunct process(es) detected for PPID (${_PPID}) and are over threshold (${_NUM_DEFUNCT_PROCS}>${_PROCESS_THRESHOLD})"
_STC=1
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}" "${_NUM_DEFUNCT_PROCS}" "${_PROCESS_THRESHOLD}"
fi
done
else
_NUM_DEFUNCT_PROCS=$(print -R "${_DEFUNCT_PROCS}" | wc -l 2>/dev/null)
if (( _NUM_DEFUNCT_PROCS <= _PROCESS_THRESHOLD ))
then
_MSG="defunct process(es) detected but are still under threshold (${_NUM_DEFUNCT_PROCS}<=${_PROCESS_THRESHOLD})"
_STC=0
else
_MSG="defunct process(es) detected and are over threshold (${_NUM_DEFUNCT_PROCS}>${_PROCESS_THRESHOLD})"
_STC=1
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}" "${_NUM_DEFUNCT_PROCS}" "${_PROCESS_THRESHOLD}"
fi
fi
fi
return 0
}
# -----------------------------------------------------------------------------
function _show_usage
{
cat <<- EOT
NAME : $1
VERSION : $2
CONFIG : $3 with parameters:
log_healthy=<yes|no>
process_threshold=<#_of_processes>
group_by_ppid=<yes|no>
PURPOSE : Checks whether there are (too many) defunct processes on the host.
LOG HEALTHY : Supported
EOT
return 0
}
#******************************************************************************
# END of script
#******************************************************************************

View File

@ -30,6 +30,7 @@
# @(#) 2019-03-09: added support for --log-healthy [Patrick Van der Veken]
# @(#) 2019-03-16: replace 'which' [Patrick Van der Veken]
# @(#) 2020-09-05: fix log_hc call for failed checksum + quote fix [Patrick Van der Veken]
# @(#) 2021-01-13: fix log_hc call (wrong logic) [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
@ -39,7 +40,7 @@ function check_hpux_file_change
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2020-05-20" # YYYY-MM-DD
typeset _VERSION="2021-01-13" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="HP-UX" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
@ -322,7 +323,7 @@ do
fi
# bounce failures back and jump to next file
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
if (( _LOG_HEALTHY > 0 && _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
continue

View File

@ -32,6 +32,7 @@
# @(#) 2018-10-28: fixed (linter) errors [Patrick Van der Veken]
# @(#) 2019-01-24: arguments fix [Patrick Van der Veken]
# @(#) 2019-03-09: added support for --log-healthy [Patrick Van der Veken]
# @(#) 2021-04-07: quotes & shellcheck fixes [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
@ -43,13 +44,13 @@ function check_hpux_ioscan
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _IOSCAN_BIN="/usr/sbin/ioscan"
typeset _IOSCAN_OPTS="-Fn"
typeset _VERSION="2019-03-09" # YYYY-MM-DD
typeset _VERSION="2021-04-07" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="HP-UX" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set ${DEBUG_OPTS}
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "${0}" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
typeset _MSG=""
@ -71,7 +72,7 @@ for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage $0 ${_VERSION} ${_CONFIG_FILE} && return 0
_show_usage "${0}" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
@ -154,7 +155,8 @@ else
_IOSCAN_OPTS="${_IOSCAN_OPTS}u"
fi
log "executing ioscan with options: ${_IOSCAN_OPTS}"
${_IOSCAN_BIN} ${_IOSCAN_OPTS} >>${HC_STDOUT_LOG} 2>>${HC_STDERR_LOG}
${_IOSCAN_BIN} ${_IOSCAN_OPTS} >>"${HC_STDOUT_LOG}" 2>>"${HC_STDERR_LOG}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
_MSG="unable to run command: {${_IOSCAN_BIN}}"
@ -166,13 +168,13 @@ else
fi
# check for requested device classes
grep -E -e ".*:.*:.*:.*:.*:.*:.*:.*:${_IOSCAN_CLASSES}:.*" ${HC_STDOUT_LOG} 2>/dev/null |\
while read _IOSCAN_LINE
grep -E -e ".*:.*:.*:.*:.*:.*:.*:.*:${_IOSCAN_CLASSES}:.*" "${HC_STDOUT_LOG}" 2>/dev/null |\
while read -r _IOSCAN_LINE
do
# possible states are: CLAIMED, UNCLAIMED, DIFF_HW, NO_HW, ERROR, SCAN
_HW_CLASS="$(print ${_IOSCAN_LINE} | cut -f9 -d':')"
_HW_PATH="$(print ${_IOSCAN_LINE} | cut -f11 -d':')"
_HW_STATE="$(print ${_IOSCAN_LINE} | cut -f16 -d':')"
_HW_CLASS=$(print "${_IOSCAN_LINE}" | cut -f9 -d':')
_HW_PATH=$(print "${_IOSCAN_LINE}" | cut -f11 -d':')
_HW_STATE=$(print "${_IOSCAN_LINE}" | cut -f16 -d':')
case "${_HW_STATE}" in
NO_HW)
@ -214,7 +216,6 @@ function _show_usage
cat <<- EOT
NAME : $1
VERSION : $2
CONFIG : $3 with:
CONFIG : $3 with parameters:
log_healthy=<yes|no>
ioscan_classes=<list_of_device_classes_to_check>

View File

@ -30,6 +30,7 @@
# @(#) with offset calculation [Patrick Van der Veken]
# @(#) 2019-01-24: arguments fix [Patrick Van der Veken]
# @(#) 2019-03-09: Text updates [Patrick Van der Veken]
# @(#) 2020-12-21: fixes for --log-healthy [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#------------------------------------------------------------------------------
@ -39,14 +40,14 @@ function check_hpux_ntp_status
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2019-03-09" # YYYY-MM-DD
typeset _VERSION="2020-12-21" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="HP-UX" # uname -s match
typeset _NTPQ_BIN="/usr/sbin/ntpq"
typeset _NTPQ_OPTS="-pn"
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set ${DEBUG_OPTS}
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
@ -65,7 +66,7 @@ for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage $0 ${_VERSION} ${_CONFIG_FILE} && return 0
_show_usage "$0" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
@ -148,7 +149,10 @@ case "${_NTP_PEER}" in
_MSG="NTP is synchronizing against ${_NTP_PEER##*\*}"
;;
esac
log_hc "$0" ${_STC} "${_MSG}"
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
# 2) offset value
if (( _STC == 0 ))
@ -165,7 +169,10 @@ then
else
_MSG="NTP offset of ${_CURR_OFFSET} is within the acceptable range"
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
;;
*)
# not numeric

View File

@ -26,6 +26,7 @@
# @(#) 2019-01-24: arguments fix [Patrick Van der Veken]
# @(#) 2019-03-09: added support for --log-healthy [Patrick Van der Veken]
# @(#) 2019-03-16: replace 'which' [Patrick Van der Veken]
# @(#) 2020-12-27: add configuration check + quoting fixes [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
@ -34,16 +35,17 @@
function check_hpux_postfix_status
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _VERSION="2019-03-09" # YYYY-MM-DD
typeset _VERSION="2020-12-27" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="HP-UX" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set ${DEBUG_OPTS}
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
typeset _POSTFIX_BIN=""
typeset _POSTFIX_CHECKER=""
typeset _MSG=""
typeset _STC=0
typeset _LOG_HEALTHY=0
@ -53,7 +55,7 @@ for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage $0 ${_VERSION} ${_CONFIG_FILE} && return 0
_show_usage "$0" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
@ -72,10 +74,14 @@ else
log "not logging/showing passed health checks"
fi
#-------------------------------------------------------------------------------
# process state
_POSTFIX_BIN="$(command -v postfix 2>>${HC_STDERR_LOG})"
if [[ -x ${_POSTFIX_BIN} && -n "${_POSTFIX_BIN}" ]]
then
${_POSTFIX_BIN} status >>${HC_STDOUT_LOG} 2>>${HC_STDERR_LOG}
${_POSTFIX_BIN} status >>"${HC_STDOUT_LOG}" 2>>"${HC_STDERR_LOG}"
# shellcheck disable=SC2181
if (( $? == 0 ))
then
_MSG="postfix is running"
@ -87,13 +93,35 @@ else
warn "postfix is not installed here"
return 1
fi
# report result
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
#-------------------------------------------------------------------------------
# configuration state
_POSTFIX_CHECKER="$(command -v postconf 2>>${HC_STDERR_LOG})"
if [[ -x ${_POSTFIX_CHECKER} && -n "${_POSTFIX_CHECKER}" ]]
then
# dump configuration
${_POSTFIX_CHECKER} -n >>"${HC_STDOUT_LOG}" 2>>"${HC_STDERR_LOG}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
_MSG="postfix configuration files have syntax error(s) {${_POSTFIX_CHECKER} -n}"
_STC=1
else
_MSG="postfix configuration files are syntactically correct"
_STC=0
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
else
warn "skipping syntax check (unable to find syntax check tool)"
fi
return 0
}
@ -103,7 +131,8 @@ function _show_usage
cat <<- EOT
NAME : $1
VERSION : $2
PURPOSE : Checks whether postfix (mail system) is running
PURPOSE : Checks whether postfix (mail system) is running and whether the
postfix configuration files are syntactically correct
LOG HEALTHY : Supported
EOT

View File

@ -0,0 +1,349 @@
#!/usr/bin/env ksh
#------------------------------------------------------------------------------
# @(#) check_hpux_uptime
#------------------------------------------------------------------------------
# @(#) Copyright (C) 2020 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#------------------------------------------------------------------------------
#
# DOCUMENTATION (MAIN)
# -----------------------------------------------------------------------------
# @(#) MAIN: check_hpux_uptime
# DOES: see _show_usage()
# EXPECTS: see _show_usage()
# REQUIRES: data_is_numeric(), data_timestring_to_mins(), data_comma2space(),
# init_hc(), log_hc(), warn()
#
# @(#) HISTORY:
# @(#) 2020-12-21: initial version [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------
function check_hpux_uptime
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _STATE_FILE="${STATE_PERM_DIR}/current.uptime"
typeset _VERSION="2020-12-21" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="HP-UX" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
typeset _MSG=""
typeset _STC=0
typeset _LOG_HEALTHY=0
typeset _CFG_HEALTHY=""
typeset _CFG_CHECK_REBOOT=""
typeset _CFG_REBOOT_TIME=""
typeset _CFG_CHECK_OLD_AGE=""
typeset _CFG_OLD_AGE_TIME=""
typeset _CHECK_REBOOT=""
typeset _REBOOT_TIME=""
typeset _REBOOT_TIME_MINS=""
typeset _CHECK_OLD_AGE=""
typeset _OLD_AGE_TIME=""
typeset _OLD_AGE_TIME_MINS=""
typeset _CURRENT_UPTIME=""
typeset _CURRENT_UPTIME_MINS=""
typeset _INIT_TIME=""
typeset _PREVIOUS_UPTIME=""
typeset _PREVIOUS_UPTIME_MINS=""
typeset _THRESHOLD_UPTIME_MINS=""
# handle arguments (originally comma-separated)
for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage "$0" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
# handle config file
[[ -n "${ARG_CONFIG_FILE}" ]] && _CONFIG_FILE="${ARG_CONFIG_FILE}"
if [[ ! -r ${_CONFIG_FILE} ]]
then
warn "unable to read configuration file at ${_CONFIG_FILE}"
return 1
fi
# read required config values
_CFG_HEALTHY=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'log_healthy')
case "${_CFG_HEALTHY}" in
yes|YES|Yes)
_LOG_HEALTHY=1
;;
*)
# do not override hc_arg
(( _LOG_HEALTHY > 0 )) || _LOG_HEALTHY=0
;;
esac
_CFG_CHECK_REBOOT=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'check_reboot')
case "${_CFG_CHECK_REBOOT}" in
no|No|NO)
_CHECK_REBOOT=0
;;
*)
_CHECK_REBOOT=1
;;
esac
_CFG_REBOOT_TIME=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'reboot_time')
if [[ -z "${_CFG_REBOOT_TIME}" ]]
then
# default
_REBOOT_TIME="60m"
else
_REBOOT_TIME="${_CFG_REBOOT_TIME}"
fi
_CFG_CHECK_OLD_AGE=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'check_old_age')
case "${_CFG_CHECK_OLD_AGE}" in
yes|Yes|Yes)
_CHECK_OLD_AGE=1
;;
*)
_CHECK_OLD_AGE=0
;;
esac
_CFG_OLD_AGE_TIME=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'old_age_time')
if [[ -z "${_CFG_OLD_AGE_TIME}" ]]
then
# default
_OLD_AGE_TIME="365d"
else
_OLD_AGE_TIME="${_CFG_OLD_AGE_TIME}"
fi
# log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
if (( _LOG_HEALTHY > 0 ))
then
if (( ARG_LOG > 0 ))
then
log "logging/showing passed health checks"
else
log "showing passed health checks (but not logging)"
fi
else
log "not logging/showing passed health checks"
fi
#------------------------------------------------------------------------------
# read uptime from init process
# shellcheck disable=SC1007
_INIT_TIME=$(UNIX95= ps -p 1 -o etime 2>/dev/null | tail -1)
if [[ -n "${_INIT_TIME}" ]]
then
# calculate exact uptime (seconds)
_CURRENT_UPTIME=$(print "${_INIT_TIME}" |\
awk '
BEGIN { days = 0; hours = 0; mins = 0; seconds = 0 };
{
gsub(/[ \t]/, "");
# get days
split ($0, day_str, "-");
if (2 in day_str) {
# string has days
days = day_str[1];
split (day_str[2], hour_str, ":");
} else {
split (day_str[1], hour_str, ":");
}
# get hours/minutes/seconds
hours = hour_str[1];
mins = hour_str[2];
if (3 in hour_str) {
# string has seconds
secs = hour_str[3];
}
}
END {
time = (days * 24 * 60 * 60) + (hours * 60 * 60) + (mins * 60) + secs;
print time;
}' 2>/dev/null)
data_is_numeric "${_CURRENT_UPTIME}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate uptime value (seconds)"
(( ARG_DEBUG )) && debug "_CURRENT_UPTIME=${_CURRENT_UPTIME}"
return 1
fi
else
warn "uptime of INIT (1) process cannot be determined"
return 1
fi
#------------------------------------------------------------------------------
# read state file
if [[ -r ${_STATE_FILE} ]]
then
_PREVIOUS_UPTIME=$(<"${_STATE_FILE}")
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to read state file at ${_STATE_FILE}"
_PREVIOUS_UPTIME=""
fi
fi
#------------------------------------------------------------------------------
# convert uptimes values
_CURRENT_UPTIME_MINS=$(( _CURRENT_UPTIME / 60 ))
data_is_numeric "${_CURRENT_UPTIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate current uptime value (minutes)"
(( ARG_DEBUG )) && debug "_CURRENT_UPTIME_MINS=${_CURRENT_UPTIME_MINS}"
return 1
fi
_PREVIOUS_UPTIME_MINS=$(( _PREVIOUS_UPTIME / 60 ))
data_is_numeric "${_CURRENT_UPTIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate previous uptime value (minutes)"
(( ARG_DEBUG )) && debug "_PREVIOUS_UPTIME_MINS=${_PREVIOUS_UPTIME_MINS}"
return 1
fi
#------------------------------------------------------------------------------
# check reboot event
if (( _CHECK_REBOOT > 0 ))
then
# convert _REBOOT_TIME to minutes
_REBOOT_TIME_MINS=$(data_timestring_to_mins "${_REBOOT_TIME}")
data_is_numeric "${_REBOOT_TIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate 'reboot_time' value from configuration file ${_CONFIG_FILE}"
(( ARG_DEBUG )) && debug "_REBOOT_TIME=${_REBOOT_TIME}"
return 1
fi
# previous uptime missing?
if [[ -z "${_PREVIOUS_UPTIME}" ]]
then
if (( ARG_LOG > 0 ))
then
print "${_CURRENT_UPTIME}" >"${_STATE_FILE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to update state file at ${_STATE_FILE}"
return 1
else
log "unable to find previously recorded uptime, resetting to current uptime"
return 0
fi
else
log "unable to find previously recorded uptime, resetting to current uptime"
fi
else
# current uptime + reboot time is smaller than previous uptime?
_THRESHOLD_UPTIME_MINS=$(( _CURRENT_UPTIME_MINS + _REBOOT_TIME_MINS ))
if (( _THRESHOLD_UPTIME_MINS < _PREVIOUS_UPTIME_MINS ))
then
_MSG="reboot check: current uptime is NOK; check if reboot occurred"
_STC=1
else
_MSG="reboot check: current uptime is OK"
_STC=0
fi
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}" "${_THRESHOLD_UPTIME_MINS}" "${_PREVIOUS_UPTIME_MINS}"
fi
# update state file
if (( ARG_LOG > 0 ))
then
print "${_CURRENT_UPTIME}" >"${_STATE_FILE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to update state file at ${_STATE_FILE}"
return 1
fi
fi
else
log "reboot check: not enabled"
fi
#------------------------------------------------------------------------------
# check old age event
if (( _CHECK_OLD_AGE > 0 ))
then
# convert _OLD_AGE_TIME to minutes
_OLD_AGE_TIME_MINS=$(data_timestring_to_mins "${_OLD_AGE_TIME}")
data_is_numeric "${_OLD_AGE_TIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate 'old_age_time' value from configuration file ${_CONFIG_FILE}"
(( ARG_DEBUG )) && debug "_OLD_AGE_TIME=${_OLD_AGE_TIME}"
return 1
fi
# are we old age yet?
if (( _CURRENT_UPTIME_MINS > _OLD_AGE_TIME_MINS ))
then
_MSG="old_age check: current uptime is NOK; old age has arrived (>${_OLD_AGE_TIME})"
_STC=1
else
_MSG="old_age check: current uptime is OK"
_STC=0
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}" "${_CURRENT_UPTIME_MINS}" "${_OLD_AGE_TIME_MINS}"
fi
else
log "old age check: not enabled"
fi
return 0
}
# -----------------------------------------------------------------------------
function _show_usage
{
cat <<- EOT
NAME : $1
VERSION : $2
CONFIG : $3 with:
log_healthy=<yes|no>
check_reboot=<yes|no>
reboot_time=<timestring>
check_old_age=<yes|no>
old_age_time=<timestring>
PURPOSE : Checks for unexpected/unplanned reboot events based on uptime
values.
Checks whether the host has been up and running for too much time.
LOG HEALTHY : Supported
EOT
return 0
}
#------------------------------------------------------------------------------
# END of script
#------------------------------------------------------------------------------

View File

@ -34,6 +34,8 @@
# @(#) added support for --log-healthy [Patrick Van der Veken]
# @(#) 2019-03-10: fix for burp v2
# @(#) 2019-03-16: replace 'which' [Patrick Van der Veken]
# @(#) 2021-03-28: updated code for changing 'burp -v' option as of burp v2.2 +
# quote fixes [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
@ -45,12 +47,12 @@ function check_linux_burp_backup
typeset _BURP_SERVER_CONFIG_FILE="/etc/burp/burp-server.conf"
typeset _BURP_CLIENT_CONFIG_FILE="/etc/burp/burp.conf"
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2019-03-16" # YYYY-MM-DD
typeset _VERSION="2021-03-28" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set ${DEBUG_OPTS}
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
@ -64,6 +66,7 @@ typeset _BURP_BACKUP_DIR=""
typeset _BURP_CLIENTCONF_DIR=""
typeset _BURP_CLIENT=""
typeset _BURP_VERSION=""
typeset _BURP_V_OUTPUT=""
typeset _BURP_WARNINGS=""
typeset _GNU_DATE=""
typeset _COUNT=1
@ -75,7 +78,7 @@ for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage $0 ${_VERSION} ${_CONFIG_FILE} && return 0
_show_usage "$0" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
@ -99,7 +102,7 @@ case "${_CFG_HEALTHY}" in
esac
# check for old-style configuration file (non-prefixed stanzas)
_IS_OLD_STYLE=$(grep -c -E -e "^client:" ${_CONFIG_FILE} 2>/dev/null)
_IS_OLD_STYLE=$(grep -c -E -e "^client:" "${_CONFIG_FILE}" 2>/dev/null)
if (( _IS_OLD_STYLE == 0 ))
then
warn "no 'client:' stanza(s) found in ${_CONFIG_FILE}; possibly an old-style configuration?"
@ -123,6 +126,7 @@ fi
# check for capable GNU date
_GNU_DATE=$(date --date="1 day ago" '+%s' 2>/dev/null)
data_is_numeric "${_GNU_DATE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "no capable GNU date found here"
@ -137,8 +141,20 @@ then
return 1
fi
# burp v1 or v2?
_BURP_VERSION="$(${_BURP_BIN} -v 2>/dev/null)"
# burp v1 or v2? (up to v2.1 burp -v; as of burp v2.2 use burp -V but we can still use burp -v with a workaround)
_BURP_V_OUTPUT="$(${_BURP_BIN} -v 2>/dev/null)"
# check if the output contains 'server version'
case "${_BURP_V_OUTPUT}" in
*Server\ version*)
# burp 2.2 and above
_BURP_VERSION=$(print "${_BURP_V_OUTPUT}" | grep "Server version" | awk -F":" '{ print $NF}')
_BURP_VERSION="burp-"$(data_strip_outer_space "${_BURP_VERSION}")
;;
*)
# burp 2.1 and below
_BURP_VERSION="${_BURP_V_OUTPUT}"
;;
esac
(( ARG_DEBUG > 0 )) && debug "burp version: ${_BURP_VERSION}"
case "${_BURP_VERSION}" in
burp-2*)
@ -183,8 +199,8 @@ case "${_BURP_VERSION}" in
esac
# check backup runs of clients
grep -E -e "^client:" ${_CONFIG_FILE} 2>/dev/null |\
while IFS=':' read _ _BURP_CLIENT _BURP_WARNINGS _BURP_AGE
grep -E -e "^client:" "${_CONFIG_FILE}" 2>/dev/null |\
while IFS=':' read -r _ _BURP_CLIENT _BURP_WARNINGS _BURP_AGE
do
typeset _BACKUP_AGING=""
typeset _BACKUP_DATE=""
@ -222,10 +238,10 @@ do
# ex.:
# Backup: 0000078 2016-11-27 03:39:03 (deletable)
# Backup: 0000079 2016-12-04 03:59:04
_BACKUP_STATS="$(${_BURP_BIN} -a l -C ${_BURP_CLIENT} 2>>${HC_STDERR_LOG} | grep '^Backup' | tail -n 1 | cut -f2- -d':')"
_BACKUP_STATS="$(${_BURP_BIN} -a l -C "${_BURP_CLIENT}" 2>>"${HC_STDERR_LOG}" | grep '^Backup' | tail -n 1 | cut -f2- -d':')"
if [[ -n "${_BACKUP_STATS}" ]]
then
_BACKUP_RUN="$(print ${_BACKUP_STATS} | awk '{print $1}')"
_BACKUP_RUN="$(print "${_BACKUP_STATS}" | awk '{print $1}')"
# output format: YYYYMMDD HHMM
_BACKUP_DATE=$(print "${_BACKUP_STATS}" | awk '{gsub(/-/,"",$2); gsub(/:/,"",$3); print $2" "substr($3,0,4)}' 2>/dev/null)
# convert to UNIX seconds
@ -267,16 +283,16 @@ do
continue
fi
fi
if [[ -r ${_BURP_BACKUP_DIR}/${_BURP_CLIENT}/current/log.gz ]]
if [[ -r "${_BURP_BACKUP_DIR}"/"${_BURP_CLIENT}"/current/log.gz ]]
then
_BACKUP_WARNINGS=$(zcat ${_BURP_BACKUP_DIR}/${_BURP_CLIENT}/current/log.gz 2>/dev/null | grep -c "WARNING:" 2>/dev/null)
_BACKUP_WARNINGS=$(zcat "${_BURP_BACKUP_DIR}"/"${_BURP_CLIENT}"/current/log.gz 2>/dev/null | grep -c "WARNING:" 2>/dev/null)
else
warn "could not find ${_BURP_BACKUP_DIR}/${_BURP_CLIENT}/current/log.gz"
continue
fi
;;
burp-1*)
_BACKUP_WARNINGS=$(${_BURP_BIN} -c ${_BURP_SERVER_CONFIG_FILE} -a S -C ${_BURP_CLIENT} -b ${_BACKUP_RUN} -z backup_stats 2>>${HC_STDERR_LOG} |\
_BACKUP_WARNINGS=$(${_BURP_BIN} -c ${_BURP_SERVER_CONFIG_FILE} -a S -C "${_BURP_CLIENT}" -b "${_BACKUP_RUN}" -z backup_stats 2>>"${HC_STDERR_LOG}" |\
grep '^warnings' 2>/dev/null | cut -f2 -d':' 2>/dev/null)
;;
esac
@ -325,16 +341,16 @@ do
# save STDOUT
if (( _STC > 0 ))
then
print "=== ${_BURP_CLIENT}: ${_BACKUP_RUN} ===" >>${HC_STDOUT_LOG}
print "=== ${_BURP_CLIENT}: ${_BACKUP_RUN} ===" >>"${HC_STDOUT_LOG}"
case "${_BURP_VERSION}" in
burp-2*)
if [[ -r ${_BURP_BACKUP_DIR}/${_BURP_CLIENT}/current/log.gz ]]
if [[ -r "${_BURP_BACKUP_DIR}"/"${_BURP_CLIENT}"/current/log.gz ]]
then
zcat ${_BURP_BACKUP_DIR}/${_BURP_CLIENT}/current/log.gz >>${HC_STDOUT_LOG} 2>>${HC_STDERR_LOG}
zcat "${_BURP_BACKUP_DIR}"/"${_BURP_CLIENT}"/current/log.gz >>"${HC_STDOUT_LOG}" 2>>"${HC_STDERR_LOG}"
fi
;;
burp-1*)
${_BURP_BIN} -c ${_BURP_SERVER_CONFIG_FILE} -a S -C ${_BURP_CLIENT} -b ${_BACKUP_RUN} -z log.gz >>${HC_STDOUT_LOG} 2>>${HC_STDERR_LOG}
${_BURP_BIN} -c ${_BURP_SERVER_CONFIG_FILE} -a S -C "${_BURP_CLIENT}" -b "${_BACKUP_RUN}" -z log.gz >>"${HC_STDOUT_LOG}" 2>>"${HC_STDERR_LOG}"
;;
esac
fi

View File

@ -0,0 +1,209 @@
#!/usr/bin/env ksh
#******************************************************************************
# @(#) check_linux_dovecot_status.sh
#******************************************************************************
# @(#) Copyright (C) 2020 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#******************************************************************************
#
# DOCUMENTATION (MAIN)
# -----------------------------------------------------------------------------
# @(#) MAIN: check_linux_dovecot_status
# DOES: see _show_usage()
# EXPECTS: n/a
# REQUIRES: data_comma2space(), linux_get_init(), init_hc(), log_hc(), warn()
#
# @(#) HISTORY:
# @(#) 2020-12-27: initial version [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
# -----------------------------------------------------------------------------
function check_linux_dovecot_status
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _DOVECOT_INIT_SCRIPT="/etc/init.d/dovecot"
typeset _DOVECOT_SYSTEMD_SERVICE="dovecot.service"
typeset _VERSION="2020-12-27" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
typeset _DOVECOT_BIN=""
typeset _DOVECOT_CHECKER=""
typeset _MSG=""
typeset _STC=0
typeset _LOG_HEALTHY=0
typeset _RC=0
typeset _CHECK_SYSTEMD_SERVICE=0
# handle arguments (originally comma-separated)
for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage "$0" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
# log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
if (( _LOG_HEALTHY > 0 ))
then
if (( ARG_LOG > 0 ))
then
log "logging/showing passed health checks"
else
log "showing passed health checks (but not logging)"
fi
else
log "not logging/showing passed health checks"
fi
#-------------------------------------------------------------------------------
# process state
# 1) try using the init ways
linux_get_init
case "${LINUX_INIT}" in
'systemd')
# Debian8/Ubuntu16 do not correctly report a unit file for dovecot,
# do not check for it and instead just query systemd service
linux_get_distro
if [[ "${LINUX_DISTRO}" = "Debian" ]] && (( ${LINUX_RELEASE%%.*} < 9 ))
then
_CHECK_SYSTEMD_SERVICE=1
elif [[ "${LINUX_DISTRO}" = "Ubuntu" ]] && (( ${LINUX_RELEASE%%.*} < 17 ))
then
_CHECK_SYSTEMD_SERVICE=1
else
_CHECK_SYSTEMD_SERVICE=$(linux_has_systemd_service "${_DOVECOT_SYSTEMD_SERVICE}")
fi
if (( _CHECK_SYSTEMD_SERVICE > 0 ))
then
systemctl --quiet is-active ${_DOVECOT_SYSTEMD_SERVICE} 2>>"${HC_STDERR_LOG}" || _STC=1
else
warn "systemd unit file not found {${_DOVECOT_SYSTEMD_SERVICE}}"
_RC=1
fi
;;
'upstart')
warn "code for upstart managed systems not implemented, NOOP"
_RC=1
;;
'sysv')
# check running SysV
if [[ -x ${_DOVECOT_INIT_SCRIPT} ]]
then
if (( $(${_DOVECOT_INIT_SCRIPT} status 2>>"${HC_STDERR_LOG}" | grep -c -i 'is running' 2>/dev/null) == 0 ))
then
_STC=1
fi
else
warn "sysv init script not found {${_DOVECOT_INIT_SCRIPT}}"
_RC=1
fi
;;
*)
_RC=1
;;
esac
# 2) try the dovecot way
if (( _RC > 0 ))
then
_DOVECOT_BIN="$(command -v dovecot 2>>${HC_STDERR_LOG})"
if [[ -x ${_DOVECOT_BIN} && -n "${_DOVECOT_BIN}" ]]
then
if (( $(${_DOVECOT_BIN} status 2>>"${HC_STDERR_LOG}" | grep -c -i 'is running' 2>/dev/null) == 0 ))
then
_RC=1
fi
else
warn "dovecot is not installed here"
return 1
fi
fi
# 3) try the pgrep way (note: old pgreps do not support '-c')
if (( _RC > 0 ))
then
(( $(pgrep -u dovecot 2>>"${HC_STDERR_LOG}" | wc -l 2>/dev/null) == 0 )) && _STC=1
fi
# evaluate results
case ${_STC} in
0)
_MSG="dovecot is running"
;;
1)
_MSG="dovecot is not running"
;;
*)
_MSG="could not determine status of dovecot"
;;
esac
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
#-------------------------------------------------------------------------------
# configuration state
_DOVECOT_CHECKER="$(command -v doveconf 2>>${HC_STDERR_LOG})"
if [[ -x ${_DOVECOT_CHECKER} && -n "${_DOVECOT_CHECKER}" ]]
then
# dump configuration
${_DOVECOT_CHECKER} -n >>"${HC_STDOUT_LOG}" 2>>"${HC_STDERR_LOG}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
_MSG="dovecot configuration files have syntax error(s) {${_DOVECOT_CHECKER} -n}"
_STC=1
else
_MSG="dovecot configuration files are syntactically correct"
_STC=0
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
else
warn "skipping syntax check (unable to find syntax check tool)"
fi
return 0
}
# -----------------------------------------------------------------------------
function _show_usage
{
cat <<- EOT
NAME : $1
VERSION : $2
PURPOSE : Checks whether dovecot (mail system) is running and whether the
dovecot configuration files are syntactically correct
LOG HEALTHY : Supported
EOT
return 0
}
#******************************************************************************
# END of script
#******************************************************************************

View File

@ -0,0 +1,319 @@
#!/usr/bin/env ksh
#******************************************************************************
# @(#) check_linux_fetchmail_status.sh
#******************************************************************************
# @(#) Copyright (C) 2020 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#******************************************************************************
#
# DOCUMENTATION (MAIN)
# -----------------------------------------------------------------------------
# @(#) MAIN: check_linux_fetchmail_status
# DOES: see _show_usage()
# EXPECTS: n/a
# REQUIRES: data_comma2space(), init_hc(), log_hc(), warn')
#
# @(#) HISTORY:
# @(#) 2016-12-26: initial version [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
# -----------------------------------------------------------------------------
function check_linux_fetchmail_status
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2020-12-26" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
typeset _MSG=""
typeset _STC=0
typeset _LOG_HEALTHY=0
typeset _CFG_HEALTHY=""
typeset _CFG_ERROR_REGEX=""
typeset _ERROR_REGEX=""
typeset _CFG_ACCOUNT=""
typeset _CFG_RC_FILE=""
typeset _CFG_CHECK_LOG=""
typeset _OPENSSL_BIN=""
typeset _MD5SUM_BIN=""
typeset _HAS_OPENSSL=0
typeset _HAS_MD5SUM=0
typeset _USE_OPENSSL=0
typeset _USE_MD5SUM=0
typeset _DO_LOG=0
typeset _LOG_FILE=""
typeset _HASH_FILE_NAME=""
typeset _STATE_FILE=""
typeset _LAST_POINTER=""
typeset _NEW_LAST_POINTER=""
typeset _LOG_COUNT=""
typeset _LINE_NR=""
typeset _LINE_TEXT=""
# handle arguments (originally comma-separated)
for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage "$0" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
# handle config file
[[ -n "${ARG_CONFIG_FILE}" ]] && _CONFIG_FILE="${ARG_CONFIG_FILE}"
if [[ ! -r ${_CONFIG_FILE} ]]
then
warn "unable to read configuration file at ${_CONFIG_FILE}"
return 1
fi
# read required config values
_CFG_ERROR_REGEX=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'error_regex')
if [[ -n "${_CFG_ERROR_REGEX}" ]]
then
_ERROR_REGEX="${_CFG_ERROR_REGEX}"
else
_ERROR_REGEX="error|authfail|lockbusy|ioerr"
(( ARG_DEBUG > 0 )) && debug "setting error_regex to default value: ${_ERROR_REGEX}"
fi
_CFG_HEALTHY=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'log_healthy')
case "${_CFG_HEALTHY}" in
yes|YES|Yes)
_LOG_HEALTHY=1
;;
*)
# do not override hc_arg
(( _LOG_HEALTHY > 0 )) || _LOG_HEALTHY=0
;;
esac
# log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
if (( _LOG_HEALTHY > 0 ))
then
if (( ARG_LOG > 0 ))
then
log "logging/showing passed health checks"
else
log "showing passed health checks (but not logging)"
fi
else
log "not logging/showing passed health checks"
fi
#-------------------------------------------------------------------------------
# check for auxiliary tools
_OPENSSL_BIN="$(command -v openssl 2>>${HC_STDERR_LOG})"
[[ -x ${_OPENSSL_BIN} && -n "${_OPENSSL_BIN}" ]] && _HAS_OPENSSL=1
_MD5SUM_BIN="$(command -v md5sum 2>>${HC_STDERR_LOG})"
[[ -x ${_MD5SUM_BIN} && -n "${_MD5SUM_BIN}" ]] && _HAS_MD5SUM=1
# prefer openssl
if (( _HAS_OPENSSL == 1 ))
then
_USE_OPENSSL=1
elif (( _HAS_MD5SUM == 1 ))
then
_USE_MD5SUM=1
else
warn "unable to find the 'openssl/md5sum' tools, will not do fetchmail log checking"
return 1
fi
#-------------------------------------------------------------------------------
# perform check(s)
grep -E -e "^fetchmail:" "${_CONFIG_FILE}" 2>/dev/null | while IFS=":" read -r _ _CFG_ACCOUNT _CFG_RC_FILE _CFG_CHECK_LOG
do
_STC=0
# check config
if [[ -z "${_CFG_ACCOUNT}" ]] && [[ -z "${_CFG_RC_FILE}" ]]
then
warn "missing values in configuration file at ${_CONFIG_FILE}"
return 1
fi
# check if account exists
id "${_CFG_ACCOUNT}" >/dev/null 2>/dev/null || {
warn "account ${_CFG_ACCOUNT} does not exist on host, skipping"
continue
}
# check if fetchmailrc file exists
[[ -r "${_CFG_RC_FILE}" ]] || {
warn "unable to read fetchmailrc file at ${_CFG_RC_FILE} for account ${_CFG_ACCOUNT}, skipping"
continue
}
# get process details
(( $(pgrep -u "${_CFG_ACCOUNT}" -f "fetchmail.*${_CFG_RC_FILE}" | wc -l 2>/dev/null) == 0 )) && _STC=1
# evaluate results
case ${_STC} in
0)
_MSG="fetchmail is running for account ${_CFG_ACCOUNT} (${_CFG_RC_FILE})"
;;
1)
_MSG="fetchmail is not running for account ${_CFG_ACCOUNT} (${_CFG_RC_FILE})"
;;
*)
_MSG="could not determine status of fetchmail for account ${_CFG_ACCOUNT} (${_CFG_RC_FILE})"
;;
esac
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
# check log?
case "${_CFG_CHECK_LOG}" in
Yes|YES|yes)
(( ARG_DEBUG > 0 )) && debug "doing log check for account ${_CFG_ACCOUNT} (${_CFG_RC_FILE})"
_DO_LOG=1;
;;
*)
log "skipping fetchmail log check for account ${_CFG_ACCOUNT} (${_CFG_RC_FILE})"
_DO_LOG=0;
;;
esac
# check auxiliary tools
if (( _HAS_OPENSSL == 0 && _HAS_MD5SUM == 0 ))
then
warn "unable to find the 'openssl/md5sum' tools, will not do fetchmail log checking for account ${_CFG_ACCOUNT}"
_DO_LOG=0
fi
if (( _DO_LOG > 0 ))
then
(( ARG_DEBUG > 0 )) && debug "will do log check for account ${_CFG_ACCOUNT} [${_CFG_RC_FILE}]"
# get logfile statement in .fetchmailrc
_LOG_FILE=$(grep "^set logfile" "${_CFG_RC_FILE}" 2>/dev/null | awk '{ print $3 }' 2>/dev/null)
[[ -z "${_LOG_FILE}" ]] && {
warn "no fetchmail log file defined in fetchmailrc file at ${_CFG_RC_FILE} for account ${_CFG_ACCOUNT}, skipping log check"
continue
}
[[ -r "${_LOG_FILE}" ]] || {
warn "unable to read fetchmail log file at ${_LOG_FILE} for account ${_CFG_ACCOUNT}, skipping log check"
continue
}
(( ARG_DEBUG > 0 )) && debug "log file found at ${_LOG_FILE}"
# determine state file (we use a hashed file name based on the fetchmail log file full path
# to avoid globbing when account has the same name for multiple entries in the configuration file)
(( _USE_OPENSSL == 1 )) && \
_HASH_FILE_NAME=$(${_OPENSSL_BIN} dgst -md5 "${_LOG_FILE}" 2>>"${HC_STDERR_LOG}" | cut -f2 -d'=' 2>/dev/null | tr -d ' ' 2>/dev/null)
(( _USE_MD5SUM == 1 )) && \
_HASH_FILE_NAME=$(${_MD5SUM_BIN} dgst -md5 "${_LOG_FILE}" 2>>"${HC_STDERR_LOG}" | cut -f1 -d' ' 2>/dev/null)
if [[ -z "${_HASH_FILE_NAME}" ]]
then
warn "unable to determine log state file for account ${_CFG_ACCOUNT}, skipping log check"
continue
fi
# get log pointer from state file
_STATE_FILE="${STATE_PERM_DIR}/${_HASH_FILE_NAME}.fetchmail"
if [[ -r "${_STATE_FILE}" ]]
then
_LAST_POINTER=$(<"${_STATE_FILE}")
fi
if [[ -z "${_LAST_POINTER}" ]]
then
(( ARG_DEBUG > 0 )) && debug "could not determine last known log entry, resetting to 0"
_LAST_POINTER=0
else
(( ARG_DEBUG > 0 )) && debug "old _LAST_POINTER=${_LAST_POINTER}"
fi
# check last known vs current pointer
_LOG_COUNT=$(wc -l "${_LOG_FILE}" 2>/dev/null | cut -f1 -d' ')
(( ARG_DEBUG > 0 )) && debug "line count for current log: ${_LOG_COUNT}"
if (( _LOG_COUNT >= _LAST_POINTER ))
then
# find errors in later log lines
awk -F':' -v error_regex="${_ERROR_REGEX}" -v last_pointer=${_LAST_POINTER} '
{
# find error lines which have a line count > last pointer
if (NR > last_pointer && $0 ~ error_regex) {
# cut fetchmail: prefix & replce possible pipes
gsub(/^fetchmail: +/, "");
gsub(/\|/, "_");
# report issue with line number
print $0 "|" NR;
}
}' "${_LOG_FILE}" 2>/dev/null | while IFS="|" read -r _LINE_TEXT _LINE_NR
do
_MSG="found issue in ${_LOG_FILE}: ${_LINE_TEXT} (LINENO=${_LINE_NR})"
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" 1 "${_MSG}"
fi
# update new last pointer
(( ARG_DEBUG > 0 )) && debug "updating _NEW_LAST_POINTER=${_LINE_NR}"
_NEW_LAST_POINTER=${_LINE_NR}
done
else
# log small has shrunk, assume it has been rotated, resetting pointer to zero
log "log file for account ${_CFG_ACCOUNT} seems to have been rotated, resetting log file pointer to 0"
_LAST_POINTER=0
fi
# update state file with new last pointer
if (( ARG_LOG > 0 ))
then
if [[ -n "${_NEW_LAST_POINTER}" ]] && (( _NEW_LAST_POINTER > _LAST_POINTER ))
then
_LAST_POINTER=${_NEW_LAST_POINTER}
fi
(( ARG_DEBUG > 0 )) && debug "new _LAST_POINTER=${_LAST_POINTER}"
print "${_LAST_POINTER}" >"${_STATE_FILE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to update state file at ${_STATE_FILE}"
return 1
fi
fi
fi
done
return 0
}
# -----------------------------------------------------------------------------
function _show_usage
{
cat <<- EOT
NAME : $1
VERSION : $2
CONFIG : $3 with parameters:
log_healthy=<yes|no>
and formatted stanzas:
fetchmail:<account>:<rc_file>:<check_log=Yes|No>
PURPOSE : Checks the status of local fetchmail services (process & log).
Fetchmail should be configured to run in daemon mode.
LOG HEALTHY : Supported
EOT
return 0
}
#******************************************************************************
# END of script
#******************************************************************************

View File

@ -31,6 +31,7 @@
# @(#) 2019-03-09: added support for --log-healthy [Patrick Van der Veken]
# @(#) 2019-03-16: replace 'which' [Patrick Van der Veken]
# @(#) 2020-09-05: fix log_hc call for failed checksum + quote fix [Patrick Van der Veken]
# @(#) 2021-01-13: fix log_hc call (wrong logic) [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
@ -40,7 +41,7 @@ function check_linux_file_change
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2020-09-05" # YYYY-MM-DD
typeset _VERSION="2021-01-13" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
@ -323,7 +324,7 @@ do
fi
# bounce failures back and jump to next file
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
if (( _LOG_HEALTHY > 0 && _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
continue

View File

@ -29,6 +29,7 @@
# @(#) 2019-01-24: arguments fix [Patrick Van der Veken]
# @(#) 2019-03-09: added code for data_is_numeric() & support for
# @(#) --log-healthy [Patrick Van der Veken]
# @(#) 2020-02-03: made slot num detection smarter [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
@ -38,7 +39,7 @@ function check_linux_hpacucli
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2019-03-09" # YYYY-MM-DD
typeset _VERSION="2020-02-03" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
@ -193,7 +194,7 @@ then
# get all slot numbers for multiple raid controllers
cat ${_TMP_FILE} | grep "in Slot [0-9]" 2>/dev/null | while read _ACU_LINE
do
_SLOT_NUM="$(print ${_ACU_LINE} | cut -f6 -d' ' 2>/dev/null)"
_SLOT_NUM="$(print ${_ACU_LINE} | sed 's/.*in Slot \([0-9][0-9]*\).*/\1/' 2>/dev/null)"
data_is_numeric "${_SLOT_NUM}"
if (( $? == 0 ))
then

View File

@ -29,6 +29,8 @@
# @(#) 2019-01-24: arguments fix [Patrick Van der Veken]
# @(#) 2019-03-09: added code for data_is_numeric() & support for
# @(#) --log-healthy [Patrick Van der Veken]
# @(#) 2020-02-03: made slot num detection smarter + fixed error in reporting
# @(#) when no problems [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
@ -38,7 +40,7 @@ function check_linux_hpssacli
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _VERSION="2019-03-09" # YYYY-MM-DD
typeset _VERSION="2020-02-03" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
@ -193,7 +195,7 @@ then
# get all slot numbers for multiple raid controllers
cat ${_TMP_FILE} | grep "in Slot [0-9]" 2>/dev/null | while read _SSA_LINE
do
_SLOT_NUM="$(print ${_SSA_LINE} | cut -f6 -d' ' 2>/dev/null)"
_SLOT_NUM="$(print ${_SSA_LINE} | sed 's/.*in Slot \([0-9][0-9]*\).*/\1/' 2>/dev/null)"
data_is_numeric "${_SLOT_NUM}"
if (( $? == 0 ))
then
@ -279,7 +281,7 @@ else
fi
# report OK situation
if (( _LOG_HEALTHY > 0 && _STC_COUNT > 0 ))
if (( _LOG_HEALTHY > 0 && _STC_COUNT == 0 ))
then
_MSG="no problems detected by {${_HPSSACLI_BIN}}"
log_hc "$0" 0 "${_MSG}"

View File

@ -35,6 +35,9 @@
# @(#) fixed problem with offset calculation [Patrick Van der Veken]
# @(#) 2019-01-24: arguments fix [Patrick Van der Veken]
# @(#) 2019-03-24: set dynamic path to client tools [Patrick Van der Veken]
# @(#) 2020-12-21: fixes for --log-healthy [Patrick Van der Veken]
# @(#) 2022-01-30: added support for systemd-timesyncd, new force_systemd
# @(#) configuration parameter [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#------------------------------------------------------------------------------
@ -50,13 +53,13 @@ typeset _CHRONYD_SYSTEMD_SERVICE="chronyd.service"
typeset _NTPD_SYSTEMD_SERVICE="ntpd.service"
typeset _CHRONYD_USER="chrony"
typeset _NTPD_USER="ntp"
typeset _VERSION="2019-03-24" # YYYY-MM-DD
typeset _VERSION="2022-01-30" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
typeset _NTPQ_OPTS="-pn"
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set ${DEBUG_OPTS}
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
@ -74,15 +77,18 @@ typeset _NTP_PEER=""
typeset _CHECK_OFFSET=0
typeset _USE_CHRONYD=0
typeset _USE_NTPD=0
typeset _USE_SYSTEMD=0
typeset _CHRONYC_BIN=""
typeset _NTPQ_BIN=""
typeset _TIMEDATECTL_BIN=""
typeset _IS_SYNCHRONIZED=0
# handle arguments (originally comma-separated)
for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage $0 ${_VERSION} ${_CONFIG_FILE} && return 0
_show_usage "$0" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
force_chrony)
log "forcing chrony since force_chrony was used"
@ -92,6 +98,10 @@ do
log "forcing ntp since force_ntp was used"
_USE_NTPD=1
;;
force_systemd)
log "forcing systemd-timesyncd since force_systemd was used"
_USE_SYSTEMD=1
;;
esac
done
@ -140,6 +150,17 @@ case "${_CFG_FORCE_NTP}" in
: # not set
;;
esac
# force_systemd (optional)
_CFG_FORCE_SYSTEMD=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'force_systemd')
case "${_CFG_FORCE_SYSTEMD}" in
yes|YES|Yes)
log "forcing systemd-timesyncd since force_systemd was set"
_USE_SYSTEMD=1
;;
*)
: # not set
;;
esac
_CFG_NTPQ_IPV4=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'ntpq_use_ipv4')
case "${_CFG_NTPQ_IPV4}" in
yes|YES|Yes)
@ -155,6 +176,16 @@ then
warn "you cannot force chrony and ntp at the same time"
return 1
fi
if (( _USE_CHRONYD > 0 && _USE_SYSTEMD > 0 ))
then
warn "you cannot force chrony and systemd at the same time"
return 1
fi
if (( _USE_NTPD > 0 && _USE_SYSTEMD > 0 ))
then
warn "you cannot force ntp and systemd at the same time"
return 1
fi
# log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
@ -172,19 +203,17 @@ fi
#------------------------------------------------------------------------------
# check for client tools
_CHRONYC_BIN="$(command -v chronyc 2>>${HC_STDERR_LOG})"
_NTPQ_BIN="$(command -v ntpq 2>>${HC_STDERR_LOG})"
_CHRONYC_BIN=$(command -v chronyc 2>>"${HC_STDERR_LOG}")
_NTPQ_BIN=$(command -v ntpq 2>>"${HC_STDERR_LOG}")
_TIMEDATECTL_BIN=$(command -v timedatectl 2>>"${HC_STDERR_LOG}")
#------------------------------------------------------------------------------
# chronyd (prefer) or ntpd (fallback)
# but do not check if _USE_CHRONYD or _USE_NTPD is already set
if (( _USE_CHRONYD == 0 && _USE_NTPD == 0 ))
# but do not check if _USE_CHRONYD, _USE_NTPD or _USE_SYSTEMD is already set
if (( _USE_CHRONYD == 0 && _USE_NTPD == 0 && _USE_SYSTEMD == 0 ))
then
linux_get_init
_CHRONYC_BIN="$(command -v chronyc 2>>${HC_STDERR_LOG})"
_CHRONYC_BIN=$(command -v chronyc 2>>"${HC_STDERR_LOG}")
if [[ -n "${_CHRONYC_BIN}" && -x ${_CHRONYC_BIN} ]]
then
# check that chrony is actually enabled
@ -194,14 +223,15 @@ then
_CHECK_SYSTEMD_SERVICE=$(linux_has_systemd_service "${_CHRONYD_SYSTEMD_SERVICE}")
if (( _CHECK_SYSTEMD_SERVICE > 0 ))
then
systemctl --quiet is-enabled ${_CHRONYD_SYSTEMD_SERVICE} 2>>${HC_STDERR_LOG} && _USE_CHRONYD=1
systemctl --quiet is-enabled ${_CHRONYD_SYSTEMD_SERVICE} 2>>"${HC_STDERR_LOG}" && _USE_CHRONYD=1
else
warn "systemd unit file not found {${_CHRONYD_SYSTEMD_SERVICE}}"
_USE_CHRONYD=0
fi
;;
'sysv')
chkconfig chronyd >>${HC_STDOUT_LOG} 2>>${HC_STDERR_LOG}
chkconfig chronyd >>"${HC_STDOUT_LOG}" 2>>"${HC_STDERR_LOG}"
# shellcheck disable=SC2181
if (( $? == 0 ))
then
_USE_CHRONYD=1
@ -215,14 +245,14 @@ then
esac
(( ARG_DEBUG > 0 )) && debug "chronyd service state: ${_USE_CHRONYD}"
fi
_NTPQ_BIN="$(command -v ntpq 2>>${HC_STDERR_LOG})"
_NTPQ_BIN=$(command -v ntpq 2>>"${HC_STDERR_LOG}")
if (( _USE_CHRONYD == 0 )) && [[ -n "${_NTPQ_BIN}" && -x ${_NTPQ_BIN} ]]
then
# shellcheck disable=SC2034
_USE_NTPD=1
(( ARG_DEBUG > 0 )) && debug "ntpd service state: ${_USE_NTPD}"
fi
if (( _USE_CHRONYD == 0 && _USE_NTPD == 0 ))
if (( _USE_CHRONYD == 0 && _USE_NTPD == 0 && _USE_SYSTEMD == 0 ))
then
_MSG="unable to find chronyd or ntpd (or they are not enabled)"
log_hc "$0" 1 "${_MSG}"
@ -233,10 +263,12 @@ then
fi
#------------------------------------------------------------------------------
# check ntp service
# 1) try using the init ways
linux_get_init
case "${LINUX_INIT}" in
# check ntp service (unless _USE_SYSTEMD is explicitly set)
if (( _USE_SYSTEMD == 0 ))
then
# 1) try using the init ways
linux_get_init
case "${LINUX_INIT}" in
'systemd')
if (( _USE_CHRONYD > 0 ))
then
@ -269,7 +301,7 @@ case "${LINUX_INIT}" in
then
if [[ -x ${_CHRONY_INIT_SCRIPT} ]]
then
if (( $(${_CHRONY_INIT_SCRIPT} status 2>>${HC_STDERR_LOG} | grep -c -i 'is running' 2>/dev/null) == 0 ))
if (( $(${_CHRONY_INIT_SCRIPT} status 2>>"${HC_STDERR_LOG}" | grep -c -i 'is running' 2>/dev/null) == 0 ))
then
_STC=1
fi
@ -280,7 +312,7 @@ case "${LINUX_INIT}" in
else
if [[ -x ${_NTPD_INIT_SCRIPT} ]]
then
if (( $(${_NTPD_INIT_SCRIPT} status 2>>${HC_STDERR_LOG} | grep -c -i 'is running' 2>/dev/null) == 0 ))
if (( $(${_NTPD_INIT_SCRIPT} status 2>>"${HC_STDERR_LOG}" | grep -c -i 'is running' 2>/dev/null) == 0 ))
then
_STC=1
fi
@ -293,21 +325,21 @@ case "${LINUX_INIT}" in
*)
_RC=1
;;
esac
esac
# 2) try the pgrep way (note: old pgreps do not support '-c')
if (( _RC > 0 ))
then
# 2) try the pgrep way (note: old pgreps do not support '-c')
if (( _RC > 0 ))
then
if (( _USE_CHRONYD > 0 ))
then
(( $(pgrep -u "${_CHRONYD_USER}" 'chronyd' 2>>${HC_STDERR_LOG} | wc -l 2>/dev/null) == 0 )) && _STC=1
(( $(pgrep -u "${_CHRONYD_USER}" 'chronyd' 2>>"${HC_STDERR_LOG}" | wc -l 2>/dev/null) == 0 )) && _STC=1
else
(( $(pgrep -u "${_NTPD_USER}" 'ntpd' 2>>${HC_STDERR_LOG} | wc -l 2>/dev/null) == 0 )) && _STC=1
(( $(pgrep -u "${_NTPD_USER}" 'ntpd' 2>>"${HC_STDERR_LOG}" | wc -l 2>/dev/null) == 0 )) && _STC=1
fi
fi
fi
# evaluate results
case ${_STC} in
# evaluate results
case ${_STC} in
0)
if (( _USE_CHRONYD > 0 ))
then
@ -332,15 +364,18 @@ case ${_STC} in
_MSG="could not determine status of ntpd"
fi
;;
esac
log_hc "$0" ${_STC} "${_MSG}"
esac
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
#------------------------------------------------------------------------------
# check chronyc/ntpq results
_STC=0
if (( _USE_CHRONYD > 0 ))
then
${_CHRONYC_BIN} -nc sources 2>>${HC_STDERR_LOG} >>${HC_STDOUT_LOG}
# check chronyc/ntpq results
_STC=0
if (( _USE_CHRONYD > 0 ))
then
${_CHRONYC_BIN} -nc sources 2>>"${HC_STDERR_LOG}" >>"${HC_STDOUT_LOG}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
_MSG="unable to execute {${_CHRONYC_BIN}}"
@ -368,7 +403,10 @@ then
_MSG="chrony is synchronizing against ${_CHRONY_PEER}"
;;
esac
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
# 2) offset value
if (( _STC == 0 ))
@ -380,6 +418,7 @@ then
# numeric, OK (negatives are OK too!)
# convert from us to ms
_CURR_OFFSET=$(print -R "${_CURR_OFFSET} * 1000" | bc 2>/dev/null)
# shellcheck disable=SC2181
if (( $? > 0 )) || [[ -z "${_CURR_OFFSET}" ]]
then
:
@ -393,7 +432,10 @@ then
else
_MSG="NTP offset of ${_CURR_OFFSET} is within the acceptable range"
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
;;
*)
# not numeric
@ -402,9 +444,8 @@ then
;;
esac
fi
else
${_NTPQ_BIN} ${_NTPQ_OPTS} 2>>${HC_STDERR_LOG} >>${HC_STDOUT_LOG}
else
${_NTPQ_BIN} ${_NTPQ_OPTS} 2>>"${HC_STDERR_LOG}" >>"${HC_STDOUT_LOG}"
# RC is always 0
# 1) active server
@ -425,7 +466,10 @@ else
_MSG="NTP is synchronizing against ${_NTP_PEER##*\*}"
;;
esac
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
# 2) offset value
if (( _STC == 0 ))
@ -442,7 +486,10 @@ else
else
_MSG="NTP offset of ${_CURR_OFFSET} is within the acceptable range"
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
;;
*)
# not numeric
@ -451,6 +498,54 @@ else
;;
esac
fi
fi
fi
#------------------------------------------------------------------------------
# check systemd-timesyncd results
_STC=0
if (( _USE_SYSTEMD > 0 ))
then
${_TIMEDATECTL_BIN} show 2>"${HC_STDERR_LOG}" >"${HC_STDOUT_LOG}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
_MSG="unable to execute {${_TIMEDATECTL_BIN}}"
log_hc "$0" 1 "${_MSG}"
# dump debug info
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && dump_logs
return 1
fi
# check if NTP is active
_STC=0
_IS_ACTIVE=$(grep -c "^NTP=yes" "${HC_STDOUT_LOG}" 2>/dev/null)
if (( _IS_ACTIVE == 0 ))
then
_MSG="NTP is not synchronizing"
_STC=1
else
_MSG="NTP is synchronizing"
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
# check if clock is synchronized
_STC=0
_IS_SYNCHRONIZED=$(grep -c "^NTPSynchronized=yes" "${HC_STDOUT_LOG}" 2>/dev/null)
if (( _IS_SYNCHRONIZED == 0 ))
then
_MSG="NTP is not synchronizing"
_STC=1
else
_MSG="NTP is synchronizing"
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
fi
return 0
@ -467,10 +562,11 @@ CONFIG : $3 with:
max_offset=<max_offset (ms)>
force_chrony=<yes|no>
force_ntp=<yes|no>
force_systemd=<yes|no>
ntpq_use_ipv4=<yes|no>
EXTRA OPTS : --hc-args=force_chrony, --hc-args=force_ntp
EXTRA OPTS : --hc-args=force_chrony, --hc-args=force_ntp, --hc-args=force_systemd
PURPOSE : Checks the status of NTP service & synchronization.
Supports chronyd & ntpd.
Supports chronyd, ntpd & systemd-timesyncd
Assumes chronyd is the preferred time synchronization.
LOG HEALTHY : Supported

View File

@ -19,7 +19,7 @@
# @(#) MAIN: check_linux_postfix_status
# DOES: see _show_usage()
# EXPECTS: n/a
# REQUIRES: data_comma2space(), linux_get_init(), init_hc(), log_hc(), warn')
# REQUIRES: data_comma2space(), linux_get_init(), init_hc(), log_hc(), warn()
#
# @(#) HISTORY:
# @(#) 2016-12-01: initial version [Patrick Van der Veken]
@ -32,6 +32,7 @@
# @(#) 2019-03-16: replace 'which' [Patrick Van der Veken]
# @(#) 2019-03-25: fix for older Debian & Ubuntu [Patrick Van der Veken]
# @(#) 2020-05-08: add pgrep als fallback check [Patrick Van der Veken]
# @(#) 2020-12-27: add configuration check + quoting fixes [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#******************************************************************************
@ -42,16 +43,17 @@ function check_linux_postfix_status
# ------------------------- CONFIGURATION starts here -------------------------
typeset _POSTFIX_INIT_SCRIPT="/etc/init.d/postfix"
typeset _POSTFIX_SYSTEMD_SERVICE="postfix.service"
typeset _VERSION="2020-05-08" # YYYY-MM-DD
typeset _VERSION="2020-12-27" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set ${DEBUG_OPTS}
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
typeset _POSTFIX_BIN=""
typeset _POSTFIX_CHECKER=""
typeset _MSG=""
typeset _STC=0
typeset _LOG_HEALTHY=0
@ -63,7 +65,7 @@ for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage $0 ${_VERSION} ${_CONFIG_FILE} && return 0
_show_usage "$0" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
@ -82,6 +84,9 @@ else
log "not logging/showing passed health checks"
fi
#-------------------------------------------------------------------------------
# process state
# 1) try using the init ways
linux_get_init
case "${LINUX_INIT}" in
@ -100,7 +105,7 @@ case "${LINUX_INIT}" in
fi
if (( _CHECK_SYSTEMD_SERVICE > 0 ))
then
systemctl --quiet is-active ${_POSTFIX_SYSTEMD_SERVICE} 2>>${HC_STDERR_LOG} || _STC=1
systemctl --quiet is-active ${_POSTFIX_SYSTEMD_SERVICE} 2>>"${HC_STDERR_LOG}" || _STC=1
else
warn "systemd unit file not found {${_POSTFIX_SYSTEMD_SERVICE}}"
_RC=1
@ -114,7 +119,7 @@ case "${LINUX_INIT}" in
# check running SysV
if [[ -x ${_POSTFIX_INIT_SCRIPT} ]]
then
if (( $(${_POSTFIX_INIT_SCRIPT} status 2>>${HC_STDERR_LOG} | grep -c -i 'is running' 2>/dev/null) == 0 ))
if (( $(${_POSTFIX_INIT_SCRIPT} status 2>>"${HC_STDERR_LOG}" | grep -c -i 'is running' 2>/dev/null) == 0 ))
then
_STC=1
fi
@ -134,10 +139,9 @@ then
_POSTFIX_BIN="$(command -v postfix 2>>${HC_STDERR_LOG})"
if [[ -x ${_POSTFIX_BIN} && -n "${_POSTFIX_BIN}" ]]
then
if (( $(${_POSTFIX_BIN} status 2>>${HC_STDERR_LOG} | grep -c -i 'is running' 2>/dev/null) == 0 ))
if (( $(${_POSTFIX_BIN} status 2>>"${HC_STDERR_LOG}" | grep -c -i 'is running' 2>/dev/null) == 0 ))
then
_RC=1
fi
else
warn "postfix is not installed here"
@ -148,7 +152,7 @@ fi
# 3) try the pgrep way (note: old pgreps do not support '-c')
if (( _RC > 0 ))
then
(( $(pgrep -u postfix pickup 2>>${HC_STDERR_LOG} | wc -l 2>/dev/null) == 0 )) && _STC=1
(( $(pgrep -u postfix pickup 2>>"${HC_STDERR_LOG}" | wc -l 2>/dev/null) == 0 )) && _STC=1
fi
# evaluate results
@ -168,6 +172,30 @@ then
log_hc "$0" ${_STC} "${_MSG}"
fi
#-------------------------------------------------------------------------------
# configuration state
_POSTFIX_CHECKER="$(command -v postconf 2>>${HC_STDERR_LOG})"
if [[ -x ${_POSTFIX_CHECKER} && -n "${_POSTFIX_CHECKER}" ]]
then
# dump configuration
${_POSTFIX_CHECKER} -n >>"${HC_STDOUT_LOG}" 2>>"${HC_STDERR_LOG}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
_MSG="postfix configuration files have syntax error(s) {${_POSTFIX_CHECKER} -n}"
_STC=1
else
_MSG="postfix configuration files are syntactically correct"
_STC=0
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}"
fi
else
warn "skipping syntax check (unable to find syntax check tool)"
fi
return 0
}
@ -177,7 +205,8 @@ function _show_usage
cat <<- EOT
NAME : $1
VERSION : $2
PURPOSE : Checks whether postfix (mail system) is running
PURPOSE : Checks whether postfix (mail system) is running and whether the
postfix configuration files are syntactically correct
LOG HEALTHY : Supported
EOT

View File

@ -0,0 +1,313 @@
#!/usr/bin/env ksh
#------------------------------------------------------------------------------
# @(#) check_linux_uptime
#------------------------------------------------------------------------------
# @(#) Copyright (C) 2020 by KUDOS BVBA (info@kudos.be). All rights reserved.
#
# This program is a free software; you can redistribute it and/or modify
# it under the same terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
#------------------------------------------------------------------------------
#
# DOCUMENTATION (MAIN)
# -----------------------------------------------------------------------------
# @(#) MAIN: check_linux_uptime
# DOES: see _show_usage()
# EXPECTS: see _show_usage()
# REQUIRES: data_is_numeric(), data_timestring_to_mins(), data_comma2space(),
# init_hc(), log_hc(), warn()
#
# @(#) HISTORY:
# @(#) 2020-12-21: initial version [Patrick Van der Veken]
# -----------------------------------------------------------------------------
# DO NOT CHANGE THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
#------------------------------------------------------------------------------
# -----------------------------------------------------------------------------
function check_linux_uptime
{
# ------------------------- CONFIGURATION starts here -------------------------
typeset _CONFIG_FILE="${CONFIG_DIR}/$0.conf"
typeset _STATE_FILE="${STATE_PERM_DIR}/current.uptime"
typeset _VERSION="2020-12-21" # YYYY-MM-DD
typeset _SUPPORTED_PLATFORMS="Linux" # uname -s match
# ------------------------- CONFIGURATION ends here ---------------------------
# set defaults
(( ARG_DEBUG > 0 && ARG_DEBUG_LEVEL > 0 )) && set "${DEBUG_OPTS}"
init_hc "$0" "${_SUPPORTED_PLATFORMS}" "${_VERSION}"
typeset _ARGS=$(data_comma2space "$*")
typeset _ARG=""
typeset _MSG=""
typeset _STC=0
typeset _LOG_HEALTHY=0
typeset _CFG_HEALTHY=
typeset _CFG_CHECK_REBOOT=""
typeset _CFG_REBOOT_TIME=""
typeset _CFG_CHECK_OLD_AGE=""
typeset _CFG_OLD_AGE_TIME=""
typeset _CHECK_REBOOT=""
typeset _REBOOT_TIME=""
typeset _REBOOT_TIME_MINS=""
typeset _CHECK_OLD_AGE=""
typeset _OLD_AGE_TIME=""
typeset _OLD_AGE_TIME_MINS=""
typeset _CURRENT_UPTIME=""
typeset _CURRENT_UPTIME_MINS=""
typeset _PREVIOUS_UPTIME=""
typeset _PREVIOUS_UPTIME_MINS=""
typeset _THRESHOLD_UPTIME_MINS=""
# handle arguments (originally comma-separated)
for _ARG in ${_ARGS}
do
case "${_ARG}" in
help)
_show_usage "$0" "${_VERSION}" "${_CONFIG_FILE}" && return 0
;;
esac
done
# handle config file
[[ -n "${ARG_CONFIG_FILE}" ]] && _CONFIG_FILE="${ARG_CONFIG_FILE}"
if [[ ! -r ${_CONFIG_FILE} ]]
then
warn "unable to read configuration file at ${_CONFIG_FILE}"
return 1
fi
# read required config values
_CFG_HEALTHY=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'log_healthy')
case "${_CFG_HEALTHY}" in
yes|YES|Yes)
_LOG_HEALTHY=1
;;
*)
# do not override hc_arg
(( _LOG_HEALTHY > 0 )) || _LOG_HEALTHY=0
;;
esac
_CFG_CHECK_REBOOT=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'check_reboot')
case "${_CFG_CHECK_REBOOT}" in
no|No|NO)
_CHECK_REBOOT=0
;;
*)
_CHECK_REBOOT=1
;;
esac
_CFG_REBOOT_TIME=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'reboot_time')
if [[ -z "${_CFG_REBOOT_TIME}" ]]
then
# default
_REBOOT_TIME="60m"
else
_REBOOT_TIME="${_CFG_REBOOT_TIME}"
fi
_CFG_CHECK_OLD_AGE=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'check_old_age')
case "${_CFG_CHECK_OLD_AGE}" in
yes|Yes|Yes)
_CHECK_OLD_AGE=1
;;
*)
_CHECK_OLD_AGE=0
;;
esac
_CFG_OLD_AGE_TIME=$(_CONFIG_FILE="${_CONFIG_FILE}" data_get_lvalue_from_config 'old_age_time')
if [[ -z "${_CFG_OLD_AGE_TIME}" ]]
then
# default
_OLD_AGE_TIME="365d"
else
_OLD_AGE_TIME="${_CFG_OLD_AGE_TIME}"
fi
# log_healthy
(( ARG_LOG_HEALTHY > 0 )) && _LOG_HEALTHY=1
if (( _LOG_HEALTHY > 0 ))
then
if (( ARG_LOG > 0 ))
then
log "logging/showing passed health checks"
else
log "showing passed health checks (but not logging)"
fi
else
log "not logging/showing passed health checks"
fi
#------------------------------------------------------------------------------
# read /proc/uptime
if [[ -r /proc/uptime ]]
then
# drop decimals
_CURRENT_UPTIME=$(awk '{ printf("%2.d", $1)}' /proc/uptime 2>/dev/null)
else
warn "/proc/uptime cannot be found or queried"
return 1
fi
#------------------------------------------------------------------------------
# read state file
if [[ -r ${_STATE_FILE} ]]
then
_PREVIOUS_UPTIME=$(<"${_STATE_FILE}")
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to read state file at ${_STATE_FILE}"
_PREVIOUS_UPTIME=""
fi
fi
#------------------------------------------------------------------------------
# convert uptimes values
_CURRENT_UPTIME_MINS=$(( _CURRENT_UPTIME / 60 ))
data_is_numeric "${_CURRENT_UPTIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate current uptime value (minutes)"
(( ARG_DEBUG )) && debug "_CURRENT_UPTIME_MINS=${_CURRENT_UPTIME_MINS}"
return 1
fi
_PREVIOUS_UPTIME_MINS=$(( _PREVIOUS_UPTIME / 60 ))
data_is_numeric "${_CURRENT_UPTIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate previous uptime value (minutes)"
(( ARG_DEBUG )) && debug "_PREVIOUS_UPTIME_MINS=${_PREVIOUS_UPTIME_MINS}"
return 1
fi
#------------------------------------------------------------------------------
# check reboot event
if (( _CHECK_REBOOT > 0 ))
then
# convert _REBOOT_TIME to minutes
_REBOOT_TIME_MINS=$(data_timestring_to_mins "${_REBOOT_TIME}")
data_is_numeric "${_REBOOT_TIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate 'reboot_time' value from configuration file ${_CONFIG_FILE}"
(( ARG_DEBUG )) && debug "_REBOOT_TIME=${_REBOOT_TIME}"
return 1
fi
# previous uptime missing?
if [[ -z "${_PREVIOUS_UPTIME}" ]]
then
if (( ARG_LOG > 0 ))
then
print "${_CURRENT_UPTIME}" >"${_STATE_FILE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to update state file at ${_STATE_FILE}"
return 1
else
log "unable to find previously recorded uptime, resetting to current uptime"
return 0
fi
else
log "unable to find previously recorded uptime, resetting to current uptime"
fi
else
# current uptime + reboot time is smaller than previous uptime?
_THRESHOLD_UPTIME_MINS=$(( _CURRENT_UPTIME_MINS + _REBOOT_TIME_MINS ))
if (( _THRESHOLD_UPTIME_MINS < _PREVIOUS_UPTIME_MINS ))
then
_MSG="reboot check: current uptime is NOK; check if reboot occurred"
_STC=1
else
_MSG="reboot check: current uptime is OK"
_STC=0
fi
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}" "${_THRESHOLD_UPTIME_MINS}" "${_PREVIOUS_UPTIME_MINS}"
fi
# update state file
if (( ARG_LOG > 0 ))
then
print "${_CURRENT_UPTIME}" >"${_STATE_FILE}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "failed to update state file at ${_STATE_FILE}"
return 1
fi
fi
else
log "reboot check: not enabled"
fi
#------------------------------------------------------------------------------
# check old age event
if (( _CHECK_OLD_AGE > 0 ))
then
# convert _OLD_AGE_TIME to minutes
_OLD_AGE_TIME_MINS=$(data_timestring_to_mins "${_OLD_AGE_TIME}")
data_is_numeric "${_OLD_AGE_TIME_MINS}"
# shellcheck disable=SC2181
if (( $? > 0 ))
then
warn "unable to calculate 'old_age_time' value from configuration file ${_CONFIG_FILE}"
(( ARG_DEBUG )) && debug "_OLD_AGE_TIME=${_OLD_AGE_TIME}"
return 1
fi
# are we old age yet?
if (( _CURRENT_UPTIME_MINS > _OLD_AGE_TIME_MINS ))
then
_MSG="old_age check: current uptime is NOK; old age has arrived (>${_OLD_AGE_TIME})"
_STC=1
else
_MSG="old_age check: current uptime is OK"
_STC=0
fi
if (( _LOG_HEALTHY > 0 || _STC > 0 ))
then
log_hc "$0" ${_STC} "${_MSG}" "${_CURRENT_UPTIME_MINS}" "${_OLD_AGE_TIME_MINS}"
fi
else
log "old age check: not enabled"
fi
return 0
}
# -----------------------------------------------------------------------------
function _show_usage
{
cat <<- EOT
NAME : $1
VERSION : $2
CONFIG : $3 with:
log_healthy=<yes|no>
check_reboot=<yes|no>
reboot_time=<timestring>
check_old_age=<yes|no>
old_age_time=<timestring>
PURPOSE : Checks for unexpected/unplanned reboot events based on uptime
values.
Checks whether the host has been up and running for too much time.
LOG HEALTHY : Supported
EOT
return 0
}
#------------------------------------------------------------------------------
# END of script
#------------------------------------------------------------------------------