Nk_loadwatch_from_lfd_notifications

Home

Description

nk_loadwatch_from_lfd_notifications() is a Bash function. The purpose of this function is to search for log files related to load averages from the Exim main log and match them with corresponding loadwatch files in the /root/loadwatch directory.

The function begins by changing the IFS (Internal Field Separator) variable to a newline character so that variables with spaces can be handled properly. It also captures the current timezone using the date command and stores it in the timezone variable.

The iter_check() function is defined within nk_loadwatch_from_lfd_notifications(), and its purpose is to check if a loadwatch file exists for a given timestamp +/- a certain number of minutes before and after the timestamp (up to 10 minutes). It does this by using a for loop that iterates over a range of numbers from 1 to 10 (inclusive). For each number n in the range, it calculates a new timestamp by adding or subtracting n minutes from the original timestamp, then formats this new timestamp to match the filename format of a loadwatch file (/root/loadwatch/%Y-%m-%d.%H.%M.txt). If a file with this filename exists, it prints a message indicating that a match has been found and returns 0 to indicate success.

The main body of nk_loadwatch_from_lfd_notifications() uses grep to search for lines in var/log/exim_mainlog that contain the string “load average alert”. For each matching line, it uses awk to extract the timestamp (the first two fields, separated by a space character), removes the milliseconds (the third field, separated by a period), and formats the resulting timestamp string so that it matches the format expected by date (%Y-%m-%d.%H.%M:%S). It then uses date to format this timestamp string as a loadwatch filename and checks if a file with that name exists. If it does, it prints a message indicating that a match has been found. If not, it calls the iter_check() function to search for loadwatch files with timestamps within +/-10 minutes of the original timestamp.

Example

[root@ny1 ~]# nk_loadwatch_from_lfd_notifications
loadwatch file match at /root/loadwatch/2023-04-02.04.27.txt for timestamp 2023-04-02 04:27:00
loadwatch file match at /root/loadwatch/2023-04-02.05.30.txt for timestamp 2023-04-02 05:29:00
loadwatch file match at /root/loadwatch/2023-04-02.06.33.txt for timestamp 2023-04-02 06:32:00
loadwatch file match at /root/loadwatch/2023-04-03.02.03.txt for timestamp 2023-04-03 02:03:00
loadwatch file match at /root/loadwatch/2023-04-03.03.09.txt for timestamp 2023-04-03 03:09:00
loadwatch file match at /root/loadwatch/2023-04-03.04.15.txt for timestamp 2023-04-03 04:14:00
loadwatch file match at /root/loadwatch/2023-04-03.05.18.txt for timestamp 2023-04-03 05:18:00

Code

nk_loadwatch_from_lfd_notifications() {
# I know no one likes messing with IFS, but we need to change it to newlines
# This is so we can have variables with spaces in them, which we'll need to interact with the date command.
# Backup the original IFS, then set it to newline.
SAVEIFS=$IFS
# Might try using printf instead since shell checker is yelling at me about echo.
IFS=$(echo -en "\n\b")
# Date also makes us use the timezone for some reason, so capture that.
timezone=$(date | awk '{print $(NF-1)}')

iter_check() {
# Check if loadwatch file exists for +/-n minutes before and after the timestamp. Up to 10 minutes.
# For 1 through 10 as n do.
for n in $(seq 1 10); do
    # Convert timestamp to logwatch format but subtract n minutes. and save it to loadwatchfile.
    loadwatchfile=$(date '+/root/loadwatch/%Y-%m-%d.%H.%M.txt' --date "$timestamp $timezone -$n min")
    # If the file exists,
    if [ -f "$loadwatchfile" ]; then
        # Then print out that we found a match and exit.
        echo loadwatch file match at "$loadwatchfile" for timestamp "$timestamp"
        return 0
    fi
    # Otherwise convert timestamp to logwatch format but add n minutes.
    loadwatchfile=$(date '+/root/loadwatch/%Y-%m-%d.%H.%M.txt' --date "$timestamp $timezone +$n min")
    # If the file exists,
    if [ -f "$loadwatchfile" ]; then
        # Print that we found a match and exit.
        echo loadwatch file match at "$loadwatchfile" for timestamp "$timestamp"
        return 0
    fi
done
}

# For every load average alert inside of the exim main log.
# Format the timestamp to look like what date is expecting using awk.
for timestamp in $(grep "load average alert" /var/log/exim_mainlog | awk '{print $1,$2}' | awk -F "." '{print $1}' | awk '{gsub(":[0-9][0-9]$",""); print $0":00"}'); do
    # For every timestamp transform it to look like a loadwatch file path. and save it as loadwatchfile
    loadwatchfile=$(date '+/root/loadwatch/%Y-%m-%d.%H.%M.txt' --date "$timestamp $timezone -0 min")
    # If the loadwatchfile is an actual file
    if [ -f "$loadwatchfile" ]; then
        # Then print that we found a match.
        echo loadwatch file match at "$loadwatchfile" for timestamp "$timestamp"
    fi
    # Otherwise run iter_check
    iter_check
done
# Now that everything is done, reset IFS to it's original state.
IFS=$SAVEIFS
}

MISC

Currently this script has two failed shell check warnings. I need to fix those.

Author: Nichole Kernreicht

Created: 2023-04-09 Sun 21:45