Background: If you’re not running a Rails/Ruby based web-app with bundler and a non-root user (the most common bundler setup), this article is no help for you.
We’ve all been there. Suddenly, for no apparent reason, your web app is performing like shit, and you don’t know why. All your logging is for naught, and you need to profile your code. And for whatever reason, you have to do it in production.
You google, as we all would. You find rack-perftools_profiller. It sounds awesome, so you try it.
After 4 hours of trying to get bundler to install the damn thing, you give up and light your data center on fire.
TOO BAD YOU DIDN’T READ THIS FIRST.
You have to install the perftools.rb (which the rack-perftools_profiler gem users) gem as a system gem first.
sudo gem install perftools.rb
After this, your deploy and `bundle install` will go fine.
Why, you ask?
Well. You see, when bundler installs a gem that needs a C library compiled, it doesn’t provide the proper ruby env (the env that bundler makes for all the things run in it) to the building process.
That normally doesn’t matter, but in this case, it does. perftools.rb requires some ruby headers that are not installed with the normal “make install”. In order to install them, it usse another gem “ruby_core_source” to fetch and extract them.
Now, ruby_core_source is run from within the C extension building process, which, you’ll recall, doesn’t have the bundler evn setup, and so it doesn’t know where it really should pull the headers to, so it tries to write them to /usr/share/something/something_else. Which fails, and the process bombs.
Now, there’s a patch to ruby_core_source that fixes this. But it’s not released as a gem you. You may try to circumvent this (as I did) by installed it via bundler, using the :git => “” option. This also fails, as the building process doesn’t get the bundler env, and has no idea about the installed “good” version.
Installing perftools.rb as root fixes all that, as it lets ruby_core_source install the headers to the system, where perftools.rb can then find them. Even if you have bundler setup to ignore system gems, the header files are already there, so perftools.rb just builds.
I hope I saved you hours of digging.