Skip to content

Instantly share code, notes, and snippets.

@marcosgz
Forked from sudara/puma.monitrc
Created December 13, 2017 15:56
Show Gist options
  • Save marcosgz/6822ee85c996598619a20faf48540208 to your computer and use it in GitHub Desktop.
Save marcosgz/6822ee85c996598619a20faf48540208 to your computer and use it in GitHub Desktop.
Example config needed to use monit with puma, monitoring workers for mem.
# this monit config goes in /etc/monit/conf.d
check process puma_master
with pidfile /data/myapp/current/tmp/puma.pid
start program = "/etc/monit/scripts/puma start"
stop program = "/etc/monit/scripts/puma stop"
group myapp
check process puma_worker_0
with pidfile /data/myapp/current/tmp/puma_worker_0.pid
if totalmem is greater than 230 MB for 2 cycles then exec "/etc/monit/scripts/puma kill_worker 0"
check process puma_worker_1
with pidfile /data/myapp/current/tmp/puma_worker_1.pid
if totalmem is greater than 230 MB for 2 cycles then exec "/etc/monit/scripts/puma kill_worker 1"
check process puma_worker_2
with pidfile /data/myapp/current/tmp/puma_worker_2.pid
if totalmem is greater than 230 MB for 2 cycles then exec "/etc/monit/scripts/puma kill_worker 2"
check process puma_worker_3
with pidfile /data/myapp/current/tmp/puma_worker_3.pid
if totalmem is greater than 230 MB for 2 cycles then exec "/etc/monit/scripts/puma kill_worker 3"
# This goes in the app as config/puma.rb
environment 'production'
workers 4
threads 1,4
preload_app!
daemonize true
pidfile 'tmp/puma.pid'
stdout_redirect 'log/puma.log', 'log/puma.log', true
bind 'unix://tmp/puma.sock'
state_path 'tmp/puma.state'
on_worker_boot do |worker_index|
# write worker pid
File.open("tmp/puma_worker_#{worker_index}.pid", "w") { |f| f.puts Process.pid }
# reconnect to redis
Redis.current.client.reconnect
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.establish_connection
end
end
#!/usr/bin/env bash
# This monit wrapper script will be called by monit as root
# Edit these variables to your liking
RAILS_ENV=production
USER=myapp
APP_DIR=/data/myapp/current
PUMA_CONFIG_FILE=$APP_DIR/config/puma.rb
PUMA_PID_FILE=$APP_DIR/tmp/puma.pid
PUMA_SOCKET=$APP_DIR/tmp/puma.sock
# check if puma process is running
puma_is_running() {
if [ -S $PUMA_SOCKET ] ; then
if [ -e $PUMA_PID_FILE ] ; then
if cat $PUMA_PID_FILE | xargs pgrep -P > /dev/null ; then
return 0
else
echo "No puma process found"
fi
else
echo "No puma pid file found"
fi
else
echo "No puma socket found"
fi
return 1
}
case "$1" in
start)
echo "Starting puma..."
rm -f $PUMA_SOCKET
if [ -e $PUMA_CONFIG_FILE ] ; then
echo "cd $APP_DIR && RAILS_ENV=$RAILS_ENV bundle exec puma -C $PUMA_CONFIG_FILE"
/bin/su - $USER -c "cd $APP_DIR && RAILS_ENV=$RAILS_ENV bundle exec puma -C $PUMA_CONFIG_FILE"
else
echo "No config file found"
/bin/su - $USER -c "cd $APP_DIR && RAILS_ENV=$RAILS_ENV bundle exec puma --daemon --bind unix://$PUMA_SOCKET --pidfile $PUMA_PID_FILE"
fi
echo "done"
;;
stop)
echo "Stopping puma..."
kill -s SIGTERM `cat $PUMA_PID_FILE`
rm -f $PUMA_PID_FILE
rm -f $PUMA_SOCKET
echo "done"
;;
restart)
if puma_is_running ; then
echo "Hot-restarting puma..."
kill -s SIGUSR2 `cat $PUMA_PID_FILE`
echo "Doublechecking the process restart..."
sleep 15
if puma_is_running ; then
echo "done"
exit 0
else
echo "Puma restart failed :/"
fi
fi
;;
phased_restart)
if puma_is_running ; then
echo "Phased-restarting puma..."
kill -s SIGUSR1 `cat $PUMA_PID_FILE`
echo "Doublechecking the process restart..."
sleep 10
if puma_is_running ; then
echo "done"
exit 0
else
echo "Puma restart failed :/"
fi
fi
;;
kill_worker*)
if [ -z "$2" ];then
logger -t "unicorn_${APP}" -s "kill_worker called with no worker identifier"
exit 1
fi
PID_DIR=`dirname $PUMA_PID_FILE`
kill -s QUIT `cat ${PID_DIR}/puma_worker_$2.pid`
STATUS=$?
exit $STATUS
;;
*)
echo "Usage: puma {start|stop|restart|kill_worker 0,1,2,etc}" >&2
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment