Skip to content

Instantly share code, notes, and snippets.

@hiranthi
Last active December 8, 2023 10:34
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiranthi/0f7fe6c657a9b3198e0a032349faa23e to your computer and use it in GitHub Desktop.
Save hiranthi/0f7fe6c657a9b3198e0a032349faa23e to your computer and use it in GitHub Desktop.
Bash script for custom Redis monitoring. The path in the mentioned cronjob is assuming the contents would be placed in a file called `monitor`, which resides in a folder `redis-monitoring` (within the HOME folder)
#!/bin/bash
#####################################################################################
# #
# Cronjob command: #
# #
# bash /home/DA_USER/redis-monitoring/monitor >/dev/null 2>&1 #
# #
#####################################################################################
#################################
# Variables #
#################################
# URL to check as part of the monitoring (must be the correct end-domain that normally results in 200 OK)
REDIS_MNTR_URL='https://domain.com'
# Email address to sent log-files to
REDIS_MNTR_EMAIL="email@domain.com"
# Redis database number
REDIS_MNTR_DB='0'
# Redis key name
REDIS_MNTR_KEY='redis_monitoring_key'
# Number of times an error has to occur before emailing
REDIS_MNTR_NUM_CHECKS='5'
# Flush the Redis database (or not) when the number of REDIS_MNTR_NUM_CHECKS unsuccessful checks is reached
REDIS_MNTR_FLUSH_DB='true'
# Delete `object-cache.php` from `wp-content` when the number of REDIS_MNTR_NUM_CHECKS unsuccessful checks is reached
REDIS_MNTR_DEL_OBJCACHE='true'
# Base for the email subject, %s = domain from REDIS_MNTR_URL
REDIS_MNTR_MAIL_SUBJECT="CRITICAL: Redis issue — %s"
# Base for the email contents, %d = REDIS_MNTR_NUM_CHECKS, %s = REDIS_MNTR_URL
REDIS_MNTR_MAIL_CONTENTS="%d Redis errors on %s!\n\n Check the attached logfile."
# Path to Redis
REDIS_MNTR_PATH='/tmp/redis.sock'
#################################
# Files #
#################################
REDIS_MNTR_FILE="${HOME}/redis-monitoring/redis-monitoring-file.txt"
REDIS_MNTR_LOG="${HOME}/redis-monitoring/redis-monitoring.log"
REDIS_MNTR_DATETIME_START=$(date)
# Get HTTP Status for REDIS_MNTR_URL
REDIS_MNTR_URL_STATUS=$(curl --write-out %{http_code} --silent --output /dev/null ${REDIS_MNTR_URL})
case ${REDIS_MNTR_URL_STATUS} in
# HTTP STATUS equals 500, 503, or 507 (200 as well, just to be sure)
200 | 500 | 503 | 507)
# Write to log-file
echo "[$(date +%d-%m-%Y\ %T)] ${REDIS_MNTR_URL_STATUS} — ${REDIS_MNTR_URL}" >> ${REDIS_MNTR_LOG}
# Ping Redis
REDIS_MNTR_PING=$(redis-cli -s ${REDIS_MNTR_PATH} -n ${REDIS_MNTR_DB} PING 2>&1)
# Redis returned PONG
if [ "${REDIS_MNTR_PING}" == "PONG" ] ; then
# Set the Redis monitoring key in the database
REDIS_MNTR_SETKEY=$(redis-cli -s /tmp/redis.sock -n ${REDIS_MNTR_DB} set ${REDIS_MNTR_KEY} "${REDIS_MNTR_DATETIME_START}" 2>&1)
# Response from setting key was OK
if [ "${REDIS_MNTR_SETKEY}" == "OK" ] ; then
# Get the value of the key we've set
REDIS_MNTR_GETKEY=$(redis-cli -s /tmp/redis.sock -n ${REDIS_MNTR_DB} get ${REDIS_MNTR_KEY} 2>&1)
# When the set value and what was returned aren't the same
if [ "${REDIS_MNTR_DATETIME_START}" != "${REDIS_MNTR_GETKEY}" ] ; then
# Write to log-file
echo "[$(date +%d-%m-%Y\ %T)] ERROR — ${REDIS_MNTR_GETKEY}" >> ${REDIS_MNTR_LOG}
# Write to monitoring-file
echo "[$(date +%d-%m-%Y\ %T)] ERROR" >> ${REDIS_MNTR_FILE}
fi
fi
# Another Redis check, to be sure
REDIS_MNTR_CHECK=$(redis-cli -s ${REDIS_MNTR_PATH} -n ${REDIS_MNTR_DB} INFO 2>&1)
REDIS_MNTR_CHECK_FC=$(printf %.7s "${REDIS_MNTR_CHECK}")
# First 7 characters are `(error)`
if [ "${REDIS_MNTR_CHECK_FC}" == "(error)" ] ; then
# Write to log-file
echo "[$(date +%d-%m-%Y\ %T)] ERROR — ${REDIS_MNTR_CHECK}" >> ${REDIS_MNTR_LOG}
# Write to monitoring-file
echo "[$(date +%d-%m-%Y\ %T)] ERROR" >> ${REDIS_MNTR_FILE}
# No Redis error
else
# HTTP Status 200 OK
if [[ ${REDIS_MNTR_URL_STATUS} -eq 200 ]] ; then
# Make sure REDIS_MNTR_NUM_CHECKS won't be reached unnecessarily
# And the logfile can't keep growing
# So, remove both files
rm -rf ${REDIS_MNTR_LOG}
rm -rf ${REDIS_MNTR_FILE}
# No need to keep going, so we're exiting
exit 1
fi
fi
# No PONG means no Redis
else
# Write to log-file
echo "[$(date +%d-%m-%Y\ %T)] PING ERROR — ${REDIS_MNTR_PING}" >> ${REDIS_MNTR_LOG}
# Write to monitoring-file
echo "[$(date +%d-%m-%Y\ %T)] PING ERROR" >> ${REDIS_MNTR_FILE}
fi
# Write to log-file
echo "——————————————————————————————————————————————————————————————————————————————" >> ${REDIS_MNTR_LOG}
echo "" >> ${REDIS_MNTR_LOG}
# If the Redis-monitoring file exists
if [ -f "${REDIS_MNTR_FILE}" ]; then
# Get number of lines in monitoring file (REDIS_MNTR_FILE)
REDIS_MNTR_FILE_LC=$(wc -l < ${REDIS_MNTR_FILE})
# The monitoring file contains an equal amount of lines as set with REDIS_MNTR_NUM_CHECKS
if [ ${REDIS_MNTR_FILE_LC} -ge ${REDIS_MNTR_NUM_CHECKS} ] ; then
# If REDIS_MNTR_FLUSH_DB is set to flush
if [ "${REDIS_MNTR_FLUSH_DB}" == "true" ] ; then
# Try to flush Redis DB
REDIS_MNTR_FLUSHED=$(redis-cli -n ${REDIS_MNTR_DB} -s ${REDIS_MNTR_PATH} FLUSHDB 2>&1)
# Check if Redis DB was flushed
if [ "${REDIS_MNTR_FLUSHED}" == "OK" ] ; then
echo "[$(date +%d-%m-%Y\ %T)] Redis DB ${REDIS_MNTR_DB} flushed" >> ${REDIS_MNTR_LOG}
else
echo "[$(date +%d-%m-%Y\ %T)] ERROR: Redis DB ${REDIS_MNTR_DB} | ${REDIS_MNTR_FLUSHED}" >> ${REDIS_MNTR_LOG}
# If REDIS_MNTR_DEL_OBJCACHE is set to true
if [ "${REDIS_MNTR_DEL_OBJCACHE}" == "true" ] ; then
# Delete `object-cache.php`
rm -rf "${HOME}/domains/${REDIS_MNTR_DOMAIN}/public_html/wp-content/object-cache.php"
# Log it
echo "[$(date +%d-%m-%Y\ %T)] object-cache.php deleted" >> ${REDIS_MNTR_LOG}
fi
fi
# REDIS_MNTR_FLUSH_DB is false, but REDIS_MNTR_DEL_OBJCACHE is true
elif [ "${REDIS_MNTR_DEL_OBJCACHE}" == "true" ] ; then
# Delete `object-cache.php`
rm -rf "${HOME}/domains/${REDIS_MNTR_DOMAIN}/public_html/wp-content/object-cache.php"
# Log it
echo "[$(date +%d-%m-%Y\ %T)] object-cache.php deleted" >> ${REDIS_MNTR_LOG}
fi
# Get the domain from the monitor URL
REDIS_MNTR_DOMAIN=$(echo "${REDIS_MNTR_URL}" | awk -F/ '{print $3}')
# Set the email subject
REDIS_MNTR_SUBJECT=$(printf "${REDIS_MNTR_MAIL_SUBJECT}" "${REDIS_MNTR_DOMAIN}")
# Set the email contents
REDIS_MNTR_MAIL_CONTENT=$(printf "${REDIS_MNTR_MAIL_CONTENTS}" "${REDIS_MNTR_NUM_CHECKS}" "${REDIS_MNTR_URL}")
# Email the logfile
echo "${REDIS_MNTR_MAIL_CONTENT}" | mail -s "${REDIS_MNTR_SUBJECT}" -a ${REDIS_MNTR_LOG} "${REDIS_MNTR_EMAIL}"
# Remove both files to start over
rm -rf ${REDIS_MNTR_LOG}
rm -rf ${REDIS_MNTR_FILE}
fi
fi
;;
# Default / all other HTTP STATUS codes
*)
# Nothing else needed, so we're exiting
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment