Skip to content

Instantly share code, notes, and snippets.

@mugendi
Last active January 27, 2019 02:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mugendi/29ae9695957aee52d538f0129e0dc9f4 to your computer and use it in GitHub Desktop.
Save mugendi/29ae9695957aee52d538f0129e0dc9f4 to your computer and use it in GitHub Desktop.
Simple Bash Script that creates a monit config script from your PM2 Processes. Run using ./script.sh [-m YOUR_MONIT_DIR]
#!/bin/bash
# Some utility functions....
trailing_slash () {
STR="${1}"
length=${#STR}
last_char=${STR:length-1:1}
[[ $last_char != "/" ]] && STR="$monitDir/";
echo $STR;
}
# To style messages for console
styled_echo () {
case ${2} in
red)
text="\e[31m${1}\e[0m"
;;
green)
text="\e[32m${1}\e[0m"
;;
blue)
text="\e[34m${1}\e[0m"
;;
yellow)
text="\e[33m${1}\e[0m"
;;
*) # default color
text="\e[39m${1}\e[0m"
;;
esac
echo -e $text
}
hasMonit=$(command -v monit)
hasJQ=$(command -v jq)
if ((${#hasMonit}==0))
then
styled_echo "Hey! It doesn't look like monit is installed! Get it here... https://mmonit.com/monit/" red
exit
fi
if ((${#hasJQ}==0))
then
styled_echo "Hey! This script requires you to install JQ: https://stedolan.github.io/jq/" red
exit
fi
while [[ $# -gt 0 ]]
do
# echo $#
key="${1}"
# echo $key
case ${key} in
-m|--monit)
monitDir="${2}"
;;
-h|--help)
cat << EndOfMessage
Usage: ./pm2-make.sh [options]
Options are as follows:
-c config Path to the json configuration file
-m monit Path to the monit folder. (Often /etc/monit/)
EndOfMessage
# shift # past argument
shift
;;
*) # unknown option
shift # past argument
;;
esac
shift
done
# Use Default Dir
monitDir=${monitDir:-"/etc/monit"}
# Ensure Trailing Slash
monitDir=$(trailing_slash $monitDir )
# Ensure directory exists else
if [ ! -d "$monitDir" ]; then
#No need to proceed, stop right here
styled_echo "The monit folder entered '${monitDir}' does not exist!'" red
exit
fi
# Monit Folders
CONF_AVAILABLE_DIR="${monitDir}conf-available/"
CONF_ENABLED_DIR="${monitDir}conf-enabled/" ;
styled_echo "NOTE: This script uses 'pm2 jlist' command to generate your monit script!"
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
# Prepare monit config file
MONIT_FILE="${CONF_AVAILABLE_DIR}PM2";
# Drop File if exists
if [ -f $MONIT_FILE ] ; then
styled_echo "Deleting old monit config file: ${MONIT_FILE}..." red
rm $MONIT_FILE
fi
styled_echo "Writing monit config file: ${MONIT_FILE}..." blue
echo
# Loop through the processes
echo $(pm2 jlist) | jq -cr ".[]" | while read o; do
# Pick name & PID File...
pid=$(echo $o | jq '.pid' | cut -d'"' -f 2)
name=$(echo $o | jq '.name' | cut -d'"' -f 2)
status=$(echo $o | jq '.pm2_env.status' | cut -d'"' -f 2)
pid_file=$(echo $o | jq '.pm2_env.pm_pid_path' | cut -d'"' -f 2)
# echo "${status}";
if [ "${status}" == "online" ]
then
styled_echo "Adding monit config for process '${name}' - [status=${status}]" yellow
# make monit config command & write to file
monitCMD="check process PM2-${name} with pidfile '$pid_file'"
echo $monitCMD $'\n' >> $MONIT_FILE
else
styled_echo "Skipping monit config for process '${name}' - [status=${status}]" red
fi
done
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
# create symbolic link...
styled_echo "Enabling monit config file ${MONIT_FILE} i.e (symbolic link to ${CONF_ENABLED_DIR})" blue
# Check that symbolink link points to the right file in /conf-available
if [[ -L "${CONF_ENABLED_DIR}PM2" && -f "${CONF_AVAILABLE_DIR}PM2" ]]
then
# All good!
styled_echo "Symbolic link exists!" green
else
if [ -f "${CONF_ENABLED_DIR}PM2" ]
then
# Symbolic link does not point to the right file or is broken, replace
styled_echo "Replacing symbolic link..." red
ln -sf $MONIT_FILE $CONF_ENABLED_DIR
else
# Symbolic link does not exist. Create
styled_echo "Creating new symbolic link..." yellow
ln -s $MONIT_FILE $CONF_ENABLED_DIR
fi
fi
printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -
# Reload Monit
styled_echo "Reloading Monit" blue
monit reload
styled_echo "All Ready!" green
#!/bin/bash
#Where
#watchScript=/usr/local/bin/watchfile.sh
#pm2MonitScript=/usr/local/bin/pm2-monit.sh
#command
bash /usr/local/bin/watchfile.sh \
-s "find PM2_HOME/pids/ -type f -print0 | xargs -0 stat" \
-e /usr/local/bin/pm2-monit.sh > /dev/null &
@mugendi
Copy link
Author

mugendi commented Jan 26, 2019

This Gist is a huge improvement on:

Run using ./script.sh [-m YOUR_MONIT_DIR] for example ./script.sh -m /etc/monit

Note:

  • JQ is required to run this script
    -m (if not entered) defaults to "/etc/monit"
    This script uses pm2 ps command and thus will only create config file for processes that are RUNNING on PM2. Also, it only monitors status and does not add stop/start methods. After all, PM2 is a process manager, that's fine. Let PM2 do what it is built to do, i.e manage process restarts and so on.

@mugendi
Copy link
Author

mugendi commented Jan 26, 2019

The script should output something like this

image

Now go ahead and check out monit...

image

@mugendi
Copy link
Author

mugendi commented Jan 26, 2019

You can automate this script by using a utility such as watchfile to run whenever PM2 pids change.

./watchfile.sh -s "find /PM2_HOME/pids/ -type f -print0 | xargs -0 stat" -e /PATH_TO_YOUR_SCRIPT/script.sh

See: https://stackoverflow.com/a/25404832

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment