Bugsnag has been using pry as a replacement for ruby’s irb console since before I joined (disclaimer: I’m one of the pry core team). It’s better than irb for a number of reasons, but chief among them are that it syntax highlights input and output, and it crashes less often.
This is most useful in development, when you spend a considerable amount of time in the console, but it’s also useful in production when you need to analyze (or even fix) production data. Here are some simple instructions to get you started.
Making pry work in production is easy, you just add it to the production part of the Gemfile
. We also use pry-plus
, but we restrict that to development because it’s less useful in production and some of the plugins are less well tested than pry itself.
# Gemfile
gem 'pry-rails'
gem 'pry-plus', group: :development
Once you’ve changed the Gemfile, run bundle
and then deploy. Pry will be available in production.
Using the same console in development as production had an unforeseen problem. The prompt looked the same wherever you were. This led to code being run in production that was intended for development.
No permanent damage was done, but we decided that we should make it really really obvious which environment you’re running in. To this end, we added a rails initializer that sets the prompt to something scary in production.
# config/initializers/pry.rb
# Show red environment name in pry prompt for non development environments
unless Rails.env.development?
old_prompt = Pry.config.prompt
env = Pry::Helpers::Text.red(Rails.env.upcase)
Pry.config.prompt = [
proc {|*a| "#{env} #{old_prompt.first.call(*a)}"},
proc {|*a| "#{env} #{old_prompt.second.call(*a)}"},
]
end
Now it’s obvious when you’re in production :).
Running pry in production is surprisingly fiddly, particularly if you’re trying to do it to answer an urgent question. You need to remember which directory to run it from, to use bundle exec
, and to pass production as an argument.
To make this easier to do we added a production-console
command to our chef recipes. All it does is open pry with all the options set.
#/usr/local/bin/production-console
cd /apps/bugsnag-website/current
bundle exec rails console production
This solved most of our problems, until one afternoon we noticed that one of our web servers was performing significantly less well than the others. I logged into the machine to have a look around, and I found that a large portion of its CPU and RAM were being used by a pry session someone had left in a screen.
Now we only ever use pry on our monitor machine. The monitor
machine usually spends its time doing non-critical things, like running monit, graphite, and cron. As some of the cron jobs we do require our rails codebase, production-console
already worked on that machine, so it was the obvious choice.
To ensure that I don’t forget which machine to ssh into, I have an alias defined in my ~/.zshr
c that lets me run production-console
on my laptop.
# ~/.zshrc
alias production-console='ssh -t monitor zsh -l -c production-console'
I hope that makes your console better in production. If you have other tips on improving pry in production, let us know @bugsnag.