Executing ruby script before rails gets loaded

I have a ruby script which instruments Net::HTTP requests in Rails applications. This works as follows: When Ruby loads the Net::HTTP class, I alias the request method. At every http request, my instrumented method gets executed. So that this works, I need to execute my script BEFORE ruby loads the standard library and BEFORE Rails gets loaded. So I need the earliest possible point in Rails where I can require my instrumentation script.

I tried the following locations:

  • config/preinitializer.rb → too late because Net::HTTP got already loaded
  • config/application.rb → also too late for the same reason
  • I put my instrumentation script at the top of the Gemfile. So that my Gemfile looks like this:

require “myinstrumentationscript” source ‘https://rubygems.org

Bundle edge Rails instead: gem ‘rails’, github: ‘rails/rails’

gem ‘rails’, ‘4.1.1’

Use sqlite3 as the database for Active Record

gem ‘sqlite3’

Use SCSS for stylesheets

gem ‘sass-rails’, ‘~> 4.0.3’

Use Uglifier as compressor for JavaScript assets

gem ‘uglifier’, ‘>= 1.3.0’

Use CoffeeScript for .js.coffee assets and views

gem ‘coffee-rails’, ‘~> 4.0.0’

This solution works not bad, but has some drawbacks:

  • When I do “bundle install” or “bundle update” my script gets executed. But I want my script only run before Rails gets initialized.
  • The bigger problem: This solution seems only to work in Rails 4. I get at least a Gemfile error in Rails 2. So I need another location where I can load my instrumentation script.

Any help is very appreciated.

Martin Ennemoser wrote in post #1154169:

I have a ruby script which instruments Net::HTTP requests in Rails applications. This works as follows: When Ruby loads the Net::HTTP class, I alias the request method. At every http request, my instrumented method gets executed. So that this works, I need to execute my script BEFORE ruby loads the standard library and BEFORE Rails gets loaded. So I need the earliest possible point in Rails where I can require my instrumentation script.

Sound to me like you need to make your own Rack middleware and insert it into the stack in the appropriate place.

Why do you need to load before Net::HTTP? If you use something like alias_method_chain, you can inject your wrapper after-the-fact.

Hard to troubleshoot much farther without seeing how you’re hooking into Net::HTTP.

–Matt Jones

alias_method_chain seems very interesting. I will have a look at it, thanks.