summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLamont Granquist <lamont@scriptkiddie.org>2015-10-13 12:11:45 -0700
committerLamont Granquist <lamont@scriptkiddie.org>2015-10-13 12:11:45 -0700
commit92ba97d8af84822ebcda4f928cd82b001148c5b5 (patch)
treedf4de129895a2cc69abef5b121b998700cb42921
parent6d7adf9b39459541250049ae03d9e2c6abe94b90 (diff)
parent51c6ba84a3f189398b01de10d031dec5b16d9e8c (diff)
downloadchef-92ba97d8af84822ebcda4f928cd82b001148c5b5.tar.gz
Merge pull request #4034 from chef/lcg/ruby-profiling
add optional ruby-profiling with --profile-ruby
-rw-r--r--Gemfile2
-rw-r--r--lib/chef/application/apply.rb6
-rw-r--r--lib/chef/application/client.rb8
-rw-r--r--lib/chef/application/solo.rb8
-rw-r--r--lib/chef/client.rb27
-rw-r--r--spec/integration/client/client_spec.rb17
6 files changed, 66 insertions, 2 deletions
diff --git a/Gemfile b/Gemfile
index 8ace5e22be..1bc5c79675 100644
--- a/Gemfile
+++ b/Gemfile
@@ -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 c4f34911f4..15697f2955 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 => "Dump complete Ruby call graph stack of entire Chef run (expert only)",
+ :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 bf724d7522..5fac34196d 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 => "Dump complete Ruby call graph stack of entire Chef run (expert only)",
+ :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..4b472e9662 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 => "Dump complete Ruby call graph stack of entire Chef run (expert only)",
+ :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..e2d76092e2 100644
--- a/lib/chef/client.rb
+++ b/lib/chef/client.rb
@@ -232,6 +232,8 @@ class Chef
# @return Always returns true.
#
def run
+ start_profiling
+
run_error = nil
runlock = RunLock.new(Chef::Config.lockfile)
@@ -284,6 +286,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 +896,28 @@ class Chef
attr_reader :override_runlist
attr_reader :specific_recipes
+ def profiling_prereqs!
+ require 'ruby-prof'
+ rescue LoadError
+ raise "You must have the ruby-prof gem installed in order to use --profile-ruby"
+ 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