_thing="$1"
_counter=$(echo "$_thing" | sed -e 's@/@_SLASH_@g' -e 's@ @_@g')
+ _failcount_warn_stamp="${script_state_dir}/${_counter}.last-warning"
}
+case "$CTDB_PLATFORM_STYLE" in
+freebsd)
+ _stat_mtime_seconds()
+ {
+ stat -f '%m' -t '%s' "$@" 2>/dev/null
+ }
+ ;;
+*)
+ _stat_mtime_seconds()
+ {
+ stat -c '%Y' "$@" 2>/dev/null
+ }
+ ;;
+esac
+
+failcount_set_warning_interval()
+{
+ _interval="$1"
+
+ case "$_interval" in
+ none)
+ failcount_interval=""
+ ;;
+ daily)
+ failcount_interval=$((24 * 60 * 60))
+ ;;
+ hourly)
+ failcount_interval=$((60 * 60))
+ ;;
+ [0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9])
+ failcount_interval="$_interval"
+ ;;
+ esac
+}
+failcount_set_warning_interval "hourly"
+
failcount_init()
{
_thing="$1"
printf 'NOTICE: %s: no longer failing\n' "$_thing"
ctdb_counter_init "$_counter"
+ rm -f "$_failcount_warn_stamp"
}
failcount_incr()
fi
fi
+ _print_output=false
+ # If warnings could be issued forever because this situation
+ # will never make the node unhealthy, then issue warnings
+ # according to failcount interval. In this case, also print
+ # the output.
+ if [ -z "$_unhealthy_threshold" ] && [ -n "$failcount_interval" ]; then
+ if _mtime=$(_stat_mtime_seconds "$_failcount_warn_stamp"); then
+ _now=$(date '+%s')
+ if [ $((_now - _mtime)) -lt "$failcount_interval" ]; then
+ return
+ fi
+ fi
+ _print_output=true
+ fi
+
+ touch "$_failcount_warn_stamp"
+
printf 'WARNING: %s: fail count %d >= threshold %d\n' \
"$_thing" \
"$_failcount" \
"$_warn_threshold"
if [ "$_failcount" -eq "$_warn_threshold" ] && [ -n "$_output" ]; then
- # Only print output when reaching the warning threshold
+ # Also print output when reaching the warning threshold
+ _print_output=true
+ fi
+ if $_print_output; then
echo "$_output"
fi
}
<listitem>
<para>
A warning message is logged when failcount is
- initially ≥ WARNING_THRESHOLD. No additional warnings
- are logged (until failcount ≥ ERROR_THRESHOLD). The
- intention is to avoid flooding the log with warnings.
- The event script continues when a warning is logged.
+ initially ≥ WARNING_THRESHOLD. If ERROR_THRESHOLD is
+ provided then no additional warnings are logged (until
+ failcount ≥ ERROR_THRESHOLD). If ERROR_THRESHOLD is
+ not provided then additional warning are logged at
+ intervals of 1 hour. The intention is to avoid
+ flooding the log with warnings. The event script
+ continues when a warning is logged.
</para>
</listitem>
</itemizedlist>
--- /dev/null
+#!/bin/sh
+
+. "${TEST_SCRIPTS_DIR}/unit.sh"
+
+define_test "periodic warnings, up once, down several times, back up, down again"
+
+setup "up"
+
+setup_script_options <<EOF
+CTDB_VSFTPD_MONITOR_THRESHOLDS=1
+EOF
+
+ok_null
+simple_test
+
+setup "down"
+
+ok <<EOF
+WARNING: vsftpd listening on TCP port 21: fail count 1 >= threshold 1
+vsftpd not listening on TCP port 21
+EOF
+simple_test
+
+ok_null
+simple_test
+
+setup_date_one_hour_from_now
+
+ok <<EOF
+WARNING: vsftpd listening on TCP port 21: fail count 3 >= threshold 1
+vsftpd not listening on TCP port 21
+EOF
+simple_test
+
+setup "up"
+
+ok <<EOF
+NOTICE: vsftpd listening on TCP port 21: no longer failing
+EOF
+simple_test
+
+# Above fake date change doesn't affect touch/stat used for upcoming
+# periodic warnings, so reset now to be able to jump forward an hour
+# again later. The main point is to confirm that there is no
+# remaining warning timestamp file that could stop the next warning
+# from being shown.
+setup_date
+
+setup "down"
+
+ok <<EOF
+WARNING: vsftpd listening on TCP port 21: fail count 1 >= threshold 1
+vsftpd not listening on TCP port 21
+EOF
+simple_test
+
+ok_null
+simple_test
+
+setup_date_one_hour_from_now
+
+ok <<EOF
+WARNING: vsftpd listening on TCP port 21: fail count 3 >= threshold 1
+vsftpd not listening on TCP port 21
+EOF
+simple_test
+
+setup "up"
+
+ok <<EOF
+NOTICE: vsftpd listening on TCP port 21: no longer failing
+EOF
+simple_test
export FAKE_DATE_OUTPUT="$1"
}
+setup_date_one_hour_from_now()
+{
+ _now=$(date '+%s')
+ _one_hour_from_now=$((_now + 60 * 60))
+ setup_date "$_one_hour_from_now"
+}
+
setup_tcp_listen()
{
export FAKE_TCP_LISTEN="$*"