diff options
author | Lamont Granquist <lamont@scriptkiddie.org> | 2015-10-05 17:22:09 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@scriptkiddie.org> | 2015-10-05 17:22:09 -0700 |
commit | 130a94291555c03ca4775596ac940bac433b9174 (patch) | |
tree | f5051bfa89a8c6899ce9fdfa9ba3e56168277476 | |
parent | 69cf21c8b35d7fb94775db377e810908e5fad54a (diff) | |
download | chef-130a94291555c03ca4775596ac940bac433b9174.tar.gz |
add optional ruby-profiling with --profile-ruby
dumps a large call graph into /var/chef/cache/graph_profile.out
-rw-r--r-- | Gemfile | 2 | ||||
-rw-r--r-- | lib/chef/application/apply.rb | 6 | ||||
-rw-r--r-- | lib/chef/application/client.rb | 8 | ||||
-rw-r--r-- | lib/chef/application/solo.rb | 8 | ||||
-rw-r--r-- | lib/chef/client.rb | 32 | ||||
-rw-r--r-- | spec/integration/client/client_spec.rb | 17 |
6 files changed, 71 insertions, 2 deletions
@@ -18,6 +18,8 @@ group(:maintenance) do end group(:development, :test) do + # for profiling + gem "ruby-prof" gem "simplecov" gem 'rack', "~> 1.5.1" diff --git a/lib/chef/application/apply.rb b/lib/chef/application/apply.rb index 243b441119..69129a4691 100644 --- a/lib/chef/application/apply.rb +++ b/lib/chef/application/apply.rb @@ -97,6 +97,12 @@ class Chef::Application::Apply < Chef::Application :description => 'Enable whyrun mode', :boolean => true + option :profile_ruby, + :long => "--[no-]profile-ruby", + :description => "Output ruby execution profile graph", + :boolean => true, + :default => false + option :color, :long => '--[no-]color', :boolean => true, diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb index 148257ab89..690340ca43 100644 --- a/lib/chef/application/client.rb +++ b/lib/chef/application/client.rb @@ -2,7 +2,7 @@ # Author:: AJ Christensen (<aj@opscode.com) # Author:: Christopher Brown (<cb@opscode.com>) # Author:: Mark Mzyk (mmzyk@opscode.com) -# Copyright:: Copyright (c) 2008 Opscode, Inc. +# Copyright:: Copyright (c) 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -55,6 +55,12 @@ class Chef::Application::Client < Chef::Application :boolean => true, :default => false + option :profile_ruby, + :long => "--[no-]profile-ruby", + :description => "Output ruby execution profile graph", + :boolean => true, + :default => false + option :color, :long => '--[no-]color', :boolean => true, diff --git a/lib/chef/application/solo.rb b/lib/chef/application/solo.rb index 5bb2a1ceb0..1fcc819068 100644 --- a/lib/chef/application/solo.rb +++ b/lib/chef/application/solo.rb @@ -1,7 +1,7 @@ # # Author:: AJ Christensen (<aj@opscode.com>) # Author:: Mark Mzyk (mmzyk@opscode.com) -# Copyright:: Copyright (c) 2008 Opscode, Inc. +# Copyright:: Copyright (c) 2008-2015 Chef Software, Inc. # License:: Apache License, Version 2.0 # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -52,6 +52,12 @@ class Chef::Application::Solo < Chef::Application :boolean => true, :default => false + option :profile_ruby, + :long => "--[no-]profile-ruby", + :description => "Output ruby execution profile graph", + :boolean => true, + :default => false + option :color, :long => '--[no-]color', :boolean => true, diff --git a/lib/chef/client.rb b/lib/chef/client.rb index 7d5d463242..3315ae03dd 100644 --- a/lib/chef/client.rb +++ b/lib/chef/client.rb @@ -53,6 +53,11 @@ require 'chef/platform/rebooter' require 'chef/mixin/deprecation' require 'ohai' require 'rbconfig' +begin + require 'ruby-prof' +rescue LoadError + # ruby-prof is optional. +end class Chef # == Chef::Client @@ -232,6 +237,8 @@ class Chef # @return Always returns true. # def run + start_profiling + run_error = nil runlock = RunLock.new(Chef::Config.lockfile) @@ -284,6 +291,9 @@ class Chef run_completed_successfully events.run_completed(node) + # keep this inside the main loop to get exception backtraces + end_profiling + # rebooting has to be the last thing we do, no exceptions. Chef::Platform::Rebooter.reboot_if_needed!(node) rescue Exception => run_error @@ -891,6 +901,28 @@ class Chef attr_reader :override_runlist attr_reader :specific_recipes + def profiling_prereqs! + if !defined? RubyProf + raise "You must have the ruby-prof gem installed in order to use --profile-ruby" + end + end + + def start_profiling + return unless Chef::Config[:profile_ruby] + profiling_prereqs! + RubyProf.start + end + + def end_profiling + return unless Chef::Config[:profile_ruby] + profiling_prereqs! + path = Chef::FileCache.create_cache_path("graph_profile.out", false) + File.open(path, "w+") do |file| + RubyProf::GraphPrinter.new(RubyProf.stop).print(file, {}) + end + Chef::Log.warn("Ruby execution profile dumped to #{path}") + end + def empty_directory?(path) !File.exists?(path) || (Dir.entries(path).size <= 2) end diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb index 5b235e2720..314a9310be 100644 --- a/spec/integration/client/client_spec.rb +++ b/spec/integration/client/client_spec.rb @@ -301,6 +301,23 @@ EOM result.error! end + it "should complete with success when using --profile-ruby and output a profile file" do + file 'config/client.rb', <<EOM +local_mode true +cookbook_path "#{path_to('cookbooks')}" +EOM + result = shell_out!("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'x::default' -z --profile-ruby", :cwd => chef_dir) + expect(File.exist?(path_to("config/local-mode-cache/cache/graph_profile.out"))).to be true + end + + it "doesn't produce a profile when --profile-ruby is not present" do + file 'config/client.rb', <<EOM +local_mode true +cookbook_path "#{path_to('cookbooks')}" +EOM + result = shell_out!("#{chef_client} -c \"#{path_to('config/client.rb')}\" -o 'x::default' -z", :cwd => chef_dir) + expect(File.exist?(path_to("config/local-mode-cache/cache/graph_profile.out"))).to be false + end end when_the_repository "has a cookbook that generates deprecation warnings" do |