Skip to content

Instantly share code, notes, and snippets.

@ranjib
Last active February 14, 2023 01:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ranjib/5896602 to your computer and use it in GitHub Desktop.
Save ranjib/5896602 to your computer and use it in GitHub Desktop.
Chef profiling with ruby-prof

install KCacheGrind

apt-get install kcachegrind

Sandbox things

Create a sandbox folder and install Chef and rubyprof there with bundler

###Gemfile

source 'https://rubygems.org'
gem 'chef'
gem 'ruby-prof

install them

bundle install --path .bundle

Write a recipe

that contains the code you want to investigate

###sample_recipe.rb

bash "create_foo_at_#{Time.now}" do
  code "dd of=foo.random if=/dev/urandom bs=1M count=10"
end

Hack Chef internals

We need to patch chef-apply a bit for ruby-prof support (we can do the whole thing from irb/pry, without patching anything, but with low level chef api)

bin/chef-apply

edit the chef-apply binary (for me its in .bundle/ruby/1.9.1/gems/chef-11.4.4/bin/chef-apply)

require 'rubygems'
$:.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
require 'chef/application/apply'
require 'ruby-prof'
RubyProf.start

Chef::Application::Apply.new.run

result = RubyProf.stop
printer = RubyProf::CallTreePrinter.new(result)
fd = File.open('/tmp/foo.prof','w')
printer.print(fd)
fd.close

lib/chef/application/apply.rb

Edit the the main chef-apply class (this yak needs to shave because Chef::Application.exit! makes an explicit exit call) comment out the exit! call at line 145

     #Chef::Application.exit! "Exiting", 0

Run It

bundle exec chef-apply sample_recipe.rb

Analyze

This will create a foo.prof file in /tmp , open it in kcachegrind and grab a beer, do some analysis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment