Last active
December 11, 2019 11:40
-
-
Save lillesvin/0f1cf5205e169ab3b6579ae877d779a6 to your computer and use it in GitHub Desktop.
Monitor a file looking for a string. If the moving average of the interval is lower than THRESHOLD, do something!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This is executed whenever conditions are met | |
# Change this to whatever you would like to have happen | |
alert() { | |
echo 'ALERT, ALERT!!!' | |
printf "Average hit interval: %.2f sec.\n" "$AVG" | |
printf "Threshold: %d sec.\n" "$THRESHOLD" | |
printf "Window length: %d\n" "$WINDOW_LENGTH" | |
printf "Last window: %s\n" "${INTERVALS[*]}" | |
echo "---" | |
} | |
usage() { | |
cat <<EOF | |
Usage: $0 [-t INT] [-w INT] [-i INT] <SEARCH> <FILE> | |
-t Threshold. When the simple moving average drops below | |
this, trigger an alert. (Default: 5) | |
-w Window length. Amount of samples to base the moving | |
average on. (Default: 10) | |
-i Forced minimum interval between alerts. (Default: 30) | |
EOF | |
} | |
# Defaults | |
THRESHOLD=5 | |
WINDOW_LENGTH=10 | |
ALERT_INTERVAL=30 | |
while getopts ":t:w:i:h" opt; do | |
case "${opt}" in | |
t) | |
THRESHOLD=${OPTARG} | |
;; | |
w) | |
WINDOW_LENGTH=${OPTARG} | |
;; | |
i) | |
ALERT_INTERVAL=${OPTARG} | |
;; | |
h) | |
usage | |
exit | |
;; | |
*) | |
usage | |
exit 1 | |
;; | |
esac | |
done | |
shift $(($OPTIND - 1)) | |
STRING=$1 | |
LOGFILE=$2 | |
INTERVALS=() | |
LAST=`date +%s` | |
LAST_ALERT=0 | |
# Header | |
printf "Monitoring: %s\n" "$LOGFILE" | |
printf "Watching for: %s\n" "$STRING" | |
printf "Threshold: %d sec.\n" "$THRESHOLD" | |
printf "Window length: %d\n" "$WINDOW_LENGTH" | |
echo "---" | |
tail -n 0 -F "$LOGFILE" | grep --line-buffered -F "$STRING" | while read; do | |
# Append latest interval | |
INTERVALS+=("$(($(date +%s) - $LAST))") | |
LAST=`date +%s` | |
# Slice to window length | |
if [[ ${#INTERVALS[@]} -ge $WINDOW_LENGTH ]]; then | |
INTERVALS=("${INTERVALS[@]: -$WINDOW_LENGTH:$WINDOW_LENGTH}") | |
fi | |
# Calculate average | |
if [[ ${#INTERVALS[@]} -gt 1 ]]; then | |
AVG=$(printf "scale=2; (%s)/%d\n" $(IFS=+; echo -n "${INTERVALS[*]}") ${#INTERVALS[@]} | bc) | |
fi | |
# Do stuff | |
if [[ ${#INTERVALS[@]} -ge $WINDOW_LENGTH ]]; then | |
if (( `echo "$AVG < $THRESHOLD" | bc` )) && (( `echo "($LAST_ALERT + $ALERT_INTERVAL) < $(date +%s)" | bc` )); then | |
alert | |
LAST_ALERT=$(date +%s) | |
fi | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment