Tasty Recipes for Capistrano
Sean Cribbs
HALP!

a.k.a. "production mode"
HALP!

a.k.a. "this worked in development!! OMGWTFBBQ!!!11?!?!11"
Chicken Soup for
the Deployed Application
a.k.a. Log analysis
A pinch of tail
task :tail_log, :roles => :app do
sudo "tail -f #{shared_path}/log/#{rails_env}.log"
end
3T ground syslog
- Install gem:
$ sudo gem install -y production_log_analyzer
- Add to config/environments/production.rb:
require 'syslog_logger'
config.logger = SyslogLogger.new("my_app")
- Add to /etc/syslog.conf
!my_app *.* /path/to/your/app/shared/log/production.log
Don't grind it yourself!
task :install_syslog_gems, :roles => :app do
sudo 'gem install -y production_log_analyzer'
end
task :install_syslog_filter, :roles => :app do
sudo %{echo "!#{application} *.* #{shared_path}/log/#{rails_env}.log" \
>> /etc/syslog.conf}
sudo "/etc/init.d/sysklogd restart" # works for Ubuntu
end
Don't burn the toast!

a.k.a. "*headdesk* my production log iz 10MB!!!11!!11"
Stir frequently with logrotate
task :install_log_rotate_script, :roles => :app do
rotate_script = %Q{#{shared_path}/log/#{rails_env}.log {
daily
rotate 14
size 5M
compress
create 640 #{user} #{group}
missingok
}}
put rotate_script, "#{shared_path}/logrotate_script"
sudo "cp #{shared_path}/logrotate_script /etc/logrotate.d/#{application}"
delete "#{shared_path}/logrotate_script"
end
Taste, adjust seasonings

a.k.a. find out what needs more work
Rails tastebud:
pl_analyze
set :log_email_recipient, "you@example.com"
task :analyze_logs, :roles => :app do
sudo %Q{chmod a+r #{shared_path}/log/*.gz}
run %Q{for file in #{shared_path}/log/*.gz; \
do gzip -dc "$file" | \
pl_analyze /dev/stdin -e #{log_email_recipient}; \
done}
end
Log analysis du jour
Request Times Summary: Count Avg Std Dev Min Max
ALL REQUESTS: 466 1.381 6.364 0.002 106.764
SiteController#index: 39 0.738 1.457 0.019 6.330
ItemsController#index: 38 3.959 9.749 0.011 57.438
ProductsController#show: 37 0.620 0.639 0.065 2.900
[snip]
Slowest Request Times:
ProductsController#search took 106.764s
ItemsController#index took 57.438s
ProductsController#search took 39.031s
Take out the garbage

a.k.a. "who cares that ntp updated my system time?"
I can't believe it's not syslog
- Download Hodel3000CompliantLogger
- Save it to your lib/ directory.
- Change config/environments/production.rb:
require 'hodel_3000_compliant_logger'
config.logger = Hodel3000CompliantLogger.new(config.log_path)
- No more spurious system messages!
Wash the dishes

Keep your app squeaky clean
Rake: hard on dirt, soft on hands
set :rake_cmd, (ENV['RAKE_CMD'] || nil)
task :rake_exec do
if rake_cmd
run "cd #{current_path} && #{rake} #{rake_cmd} RAILS_ENV=#{rails_env}"
end
end
Rake: a streak-free shine
# Using database sessions?
task :clear_sessions do
set :rake_cmd, "db:sessions:clear"
rake_exec
end
# Clear file-based fragment and/or page cache
task :clear_cache do
# I usually make a custom Rake task for this
set :rake_cmd, "tmp:cache:clear"
rake_exec
end
Bite-sized desserts

Make the user's time a little sweeter...err shorter
Assets Lite, Slow-Churned Style
set :stylesheets, ['reset', 'shared', 'main']
set :javascripts, ['prototype', 'effects', 'application']
task :package_stylesheets, :roles => :web do
sudo %{rm -f #{current_path}/public/stylesheets/all.css}
stylesheets.each do |stylesheet|
run %{cat #{current_path}/public/stylesheets/#{stylesheet}.css >> \
#{current_path}/public/stylesheets/all.css}
end
end
task :package_javascripts, :roles => :web do
sudo %{rm -f #{current_path}/public/javascripts/all.js}
javascripts.each do |javascript|
run %{/usr/bin/ruby #{current_path}/lib/jsmin.rb < \
#{current_path}/public/javascripts/#{javascript}.js >> \
#{current_path}/public/javascripts/all.js}
end
end
Nouveau cuisine
- Automate your web server config
- Restart the whole server or individual services
- Dump/backup your database
- Move your assets to S3
Buon appetit!
No more puns. I promise.