summaryrefslogtreecommitdiff
path: root/lib/chef
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chef')
-rw-r--r--lib/chef/application.rb3
-rw-r--r--lib/chef/application/client.rb5
-rw-r--r--lib/chef/ruby_profiler.rb47
3 files changed, 54 insertions, 1 deletions
diff --git a/lib/chef/application.rb b/lib/chef/application.rb
index 297e46ef3c..69cb4678f4 100644
--- a/lib/chef/application.rb
+++ b/lib/chef/application.rb
@@ -28,6 +28,7 @@ require 'chef/platform'
require 'mixlib/cli'
require 'tmpdir'
require 'rbconfig'
+require 'chef/ruby_profiler'
class Chef
class Application
@@ -57,7 +58,7 @@ class Chef
setup_signal_handlers
reconfigure
setup_application
- run_application
+ Chef::RubyProfiler.profile(config) { run_application }
end
def setup_signal_handlers
diff --git a/lib/chef/application/client.rb b/lib/chef/application/client.rb
index 551e26e303..50323e981b 100644
--- a/lib/chef/application/client.rb
+++ b/lib/chef/application/client.rb
@@ -263,6 +263,11 @@ class Chef::Application::Client < Chef::Application
:description => "Whether a local mode (-z) server binds to a port",
:boolean => true
+ option :ruby_profile,
+ :long => "--ruby-profile",
+ :description => "Whether or not to enable Ruby profiling during the client application run",
+ :boolean => false
+
IMMEDIATE_RUN_SIGNAL = "1".freeze
attr_reader :chef_client_json
diff --git a/lib/chef/ruby_profiler.rb b/lib/chef/ruby_profiler.rb
new file mode 100644
index 0000000000..b1554fa0a3
--- /dev/null
+++ b/lib/chef/ruby_profiler.rb
@@ -0,0 +1,47 @@
+#
+# Author:: Ryan Cragun (<ryan@chef.io>)
+# Copyright:: Copyright (c) 2015 Chef, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'ruby-prof'
+
+class Chef
+ module RubyProfiler
+ def self.profile(config = {}, &block)
+ if config[:ruby_profile] || Chef::Config[:ruby_profile]
+ measure_mode = config[:ruby_profile_measure_mode] || Chef::Config[:ruby_profile_measure_mode]
+ measure_mode = RubyProf.const_get("RubyProf::#{measure_mode.upcase}")
+
+ profile_printer = config[:ruby_profile_printer] || Chef::Config[:ruby_profile_printer]
+ profile_printer = profile_printer.split('_').map { |c| c.capitalize }.join
+ profile_printer = RubyProf.const_get("RubyProf::#{profile_printer}")
+
+ if file = config[:ruby_profile_outfile] || Chef::Config[:ruby_profile_outfile]
+ profile_out = File.open(file, 'w+')
+ end
+ profile_out ||= $stdout
+
+ RubyProf.measure_mode = measure_mode
+
+ res = RubyProf.profile { block.call }
+ printer = profile_printer.new(res)
+ printer.print(profile_out)
+ else
+ block.call
+ end
+ end
+ end
+end