Skip to content

Instantly share code, notes, and snippets.

@a-chernykh
Created September 5, 2014 11:31
Show Gist options
  • Save a-chernykh/c47a36d0e149f53d7a01 to your computer and use it in GitHub Desktop.
Save a-chernykh/c47a36d0e149f53d7a01 to your computer and use it in GitHub Desktop.
Monitor unicorn workers with monit
#!/bin/bash
export RAILS_ENV=<%= node[:application][:environment] %>
export PATH=$PATH:/usr/local/bin
APP_ROOT=<%= node[:application][:path] %>/current
PID=<%= node[:application][:path] %>/current/tmp/pids/unicorn.pid
old_pid="$PID.oldbin"
cd $APP_ROOT || exit 1
. ${APP_ROOT}/.envrc
if [[ -s "/usr/local/rvm/scripts/rvm" ]]; then
source "/usr/local/rvm/scripts/rvm"
else
printf "ERROR: An RVM installation was not found.\n"
fi
runUnicorn() {
CMD="cd $APP_ROOT && source .envrc && bundle exec unicorn -c <%= node[:application][:path] %>/current/config/unicorn.rb -E <%= node[:application][:environment] %> -D"
USER="$(id -u -n)"
if [ $USER != "<%= node[:application][:user][:name] %>" ]; then
sudo -i -u <%= node[:application][:user][:name] %> -E /bin/bash -c "$CMD"
else
/bin/bash -c "$CMD"
fi
}
sig() {
test -s "$PID" && kill -$1 `cat $PID`
}
case $1 in
start)
sig 0 && echo >&2 "Already running" && exit 0
runUnicorn
;;
stop)
sig QUIT && exit 0
echo >&2 "Not running"
;;
force-stop)
sig TERM && exit 0
echo >&2 "Not running"
;;
restart|reload)
sig HUP && echo reloaded OK && exit 0
echo >&2 "Couldn't reload, starting '$CMD' instead"
runUnicorn
;;
upgrade)
sig USR2 && exit 0
echo >&2 "Couldn't upgrade, starting '$CMD' instead"
runUnicorn
;;
rotate)
sig USR1 && echo rotated logs OK && exit 0
echo >&2 "Couldn't rotate logs" && exit 1
;;
kill-worker)
PID="<%= node[:application][:path] %>/current/tmp/pids/unicorn.$2.pid"
test -s "$PID" && kill -9 `cat $PID`
;;
*)
echo >&2 "Usage: $0 <start|stop|restart|upgrade|rotate|force-stop|kill-worker>"
exit 1
;;
esac
check process <%= @name %>
with pidfile <%= @path %>/current/tmp/pids/unicorn.pid
start program = "/etc/init.d/<%= @name %> start" as uid <%= @user %> and gid <%= @user %>
stop program = "/etc/init.d/<%= @name %> stop" as uid <%= @user %> and gid <%= @user %>
<% @workers.each do |worker| %>
check process <%= worker[:name] %>
with pidfile <%= worker[:pidfile] %>
start program = "/bin/cat /dev/null"
stop program = "/etc/init.d/<%= @name %> kill-worker <%= worker[:id] %>" as uid <%= @user %> and gid <%= @user %>
if mem is greater than 700 MB for 1 cycles then restart
<% end %>
rails_root = ENV['RAILS_ROOT'] || File.dirname(__FILE__) + '/..'
rails_env = ENV['RAILS_ENV'] || '<%= node[:application][:environment] %>'
worker_processes <%= node[:application][:workers] %>
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
GC.copy_on_write_friendly = true
timeout 25
listen '<%= node[:application][:socket] %>'
pid '<%= node[:application][:current_path] %>/tmp/pids/unicorn.pid'
stderr_path '<%= node[:application][:shared_path] %>/log/unicorn.stderr.log'
stdout_path '<%= node[:application][:shared_path] %>/log/unicorn.stdout.log'
working_directory '<%= node[:application][:current_path] %>'
before_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
old_pid = rails_root + '/tmp/pids/unicorn.pid.oldbin'
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
after_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
child_pid = server.config[:pid].sub('.pid', ".#{worker.nr}.pid")
system("echo #{Process.pid} > #{child_pid}")
end
before_exec do |server|
ENV["BUNDLE_GEMFILE"] = "#{rails_root}/Gemfile"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment