diff options
| author | Jesse Wolfe <jes5199@gmail.com> | 2011-02-25 15:17:39 -0800 |
|---|---|---|
| committer | Jesse Wolfe <jes5199@gmail.com> | 2011-02-25 15:17:39 -0800 |
| commit | 448a439f5abc3d51accececb678e9c5f547f7615 (patch) | |
| tree | 1dd9181f46e01f121bb0d0b1af1029cd36ff772a /lib | |
| parent | 06939c51a3f675137b53fac8a521132a4c9cfcbe (diff) | |
| parent | e27d208db86ae0825afbc6fb34d39e7c047a1bf4 (diff) | |
| download | puppet-448a439f5abc3d51accececb678e9c5f547f7615.tar.gz puppet-448a439f5abc3d51accececb678e9c5f547f7615.tar.xz puppet-448a439f5abc3d51accececb678e9c5f547f7615.zip | |
Merge remote branch 'brice/feature/process-instrumentation' into next
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/puppet/configurer.rb | 25 | ||||
| -rw-r--r-- | lib/puppet/network/http/handler.rb | 6 | ||||
| -rw-r--r-- | lib/puppet/parser/compiler.rb | 6 | ||||
| -rw-r--r-- | lib/puppet/transaction.rb | 9 | ||||
| -rw-r--r-- | lib/puppet/util/instrumentation.rb | 12 | ||||
| -rw-r--r-- | lib/puppet/util/instrumentation/process_name.rb | 129 |
6 files changed, 177 insertions, 10 deletions
diff --git a/lib/puppet/configurer.rb b/lib/puppet/configurer.rb index 72e387c64..a39f9cda8 100644 --- a/lib/puppet/configurer.rb +++ b/lib/puppet/configurer.rb @@ -3,6 +3,7 @@ require 'sync' require 'timeout' require 'puppet/network/http_pool' require 'puppet/util' +require 'puppet/util/instrumentation' class Puppet::Configurer class CommandHookError < RuntimeError; end @@ -12,6 +13,7 @@ class Puppet::Configurer include Puppet::Configurer::FactHandler include Puppet::Configurer::PluginHandler + include Puppet::Util::Instrumentation # For benchmarking include Puppet::Util @@ -76,11 +78,17 @@ class Puppet::Configurer def prepare(options) dostorage - download_plugins unless options[:skip_plugin_download] + instrument("downloading plugins") do + download_plugins unless options[:skip_plugin_download] + end - download_fact_plugins unless options[:skip_plugin_download] + instrument("downloading facts plugins") do + download_fact_plugins unless options[:skip_plugin_download] + end - execute_prerun_command + instrument("executing prerun command") do + execute_prerun_command + end end # Get the remote catalog, yo. Returns nil if no catalog can be found. @@ -146,8 +154,10 @@ class Puppet::Configurer transaction = nil begin - benchmark(:notice, "Finished catalog run") do - transaction = catalog.apply(options) + instrument("applying catalog") do + benchmark(:notice, "Finished catalog run") do + transaction = catalog.apply(options) + end end report rescue => detail @@ -166,7 +176,10 @@ class Puppet::Configurer execute_postrun_command Puppet::Util::Log.close(report) - send_report(report, transaction) + + instrument("sending report") do + send_report(report, transaction) + end end def send_report(report, trans) diff --git a/lib/puppet/network/http/handler.rb b/lib/puppet/network/http/handler.rb index 2b9e81b61..aa33f82f7 100644 --- a/lib/puppet/network/http/handler.rb +++ b/lib/puppet/network/http/handler.rb @@ -5,10 +5,12 @@ require 'puppet/network/http/api/v1' require 'puppet/network/rest_authorization' require 'puppet/network/rights' require 'resolv' +require 'puppet/util/instrumentation' module Puppet::Network::HTTP::Handler include Puppet::Network::HTTP::API::V1 include Puppet::Network::RestAuthorization + include Puppet::Util::Instrumentation attr_reader :server, :handler @@ -65,7 +67,9 @@ module Puppet::Network::HTTP::Handler check_authorization(indirection, method, key, params) - send("do_#{method}", indirection, key, params, request, response) + instrument("processing #{indirection} #{key}") do + send("do_#{method}", indirection, key, params, request, response) + end rescue SystemExit,NoMemoryError raise rescue Exception => e diff --git a/lib/puppet/parser/compiler.rb b/lib/puppet/parser/compiler.rb index fdabd05c9..4301e8c0f 100644 --- a/lib/puppet/parser/compiler.rb +++ b/lib/puppet/parser/compiler.rb @@ -4,6 +4,7 @@ require 'puppet/node' require 'puppet/resource/catalog' require 'puppet/util/errors' +require 'puppet/util/instrumentation' require 'puppet/resource/type_collection_helper' @@ -13,9 +14,12 @@ class Puppet::Parser::Compiler include Puppet::Util include Puppet::Util::Errors include Puppet::Resource::TypeCollectionHelper + extend Puppet::Util::Instrumentation def self.compile(node) - new(node).compile.to_resource + instrument("compiling #{node.name}") do + new(node).compile.to_resource + end rescue => detail puts detail.backtrace if Puppet[:trace] raise Puppet::Error, "#{detail} on node #{node.name}" diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb index eba601cfe..df4c8b27d 100644 --- a/lib/puppet/transaction.rb +++ b/lib/puppet/transaction.rb @@ -4,8 +4,11 @@ require 'puppet' require 'puppet/util/tagging' require 'puppet/application' +require 'puppet/util/instrumentation' class Puppet::Transaction + include Puppet::Util::Instrumentation + require 'puppet/transaction/event' require 'puppet/transaction/event_manager' require 'puppet/transaction/resource_harness' @@ -138,8 +141,10 @@ class Puppet::Transaction next end ret = nil - seconds = thinmark do - ret = eval_resource(resource) + instrument("evaluating #{resource}") do + seconds = thinmark do + ret = eval_resource(resource) + end end resource.info "Evaluated in %0.2f seconds" % seconds if Puppet[:evaltrace] and @catalog.host_config? diff --git a/lib/puppet/util/instrumentation.rb b/lib/puppet/util/instrumentation.rb new file mode 100644 index 000000000..5981bea59 --- /dev/null +++ b/lib/puppet/util/instrumentation.rb @@ -0,0 +1,12 @@ +require 'puppet/util/instrumentation/process_name' + +module Puppet::Util::Instrumentation + + def instrument(title) + Puppet::Util::Instrumentation::ProcessName.instrument(title) do + yield + end + end + module_function :instrument + +end
\ No newline at end of file diff --git a/lib/puppet/util/instrumentation/process_name.rb b/lib/puppet/util/instrumentation/process_name.rb new file mode 100644 index 000000000..370d29e2e --- /dev/null +++ b/lib/puppet/util/instrumentation/process_name.rb @@ -0,0 +1,129 @@ +require 'puppet' +require 'puppet/util/instrumentation' + +module Puppet::Util::Instrumentation + class ProcessName + + # start scrolling when process name is longer than + SCROLL_LENGTH = 50 + + @active = false + class << self + attr_accessor :active, :reason + end + + trap(:QUIT) do + active? ? disable : enable + end + + def self.active? + !! @active + end + + def self.enable + mutex.synchronize do + Puppet.info("Process Name instrumentation is enabled") + @active = true + @x = 0 + setproctitle + end + end + + def self.disable + mutex.synchronize do + Puppet.info("Process Name instrumentation is disabled") + @active = false + $0 = @oldname + end + end + + def self.instrument(activity) + # inconditionnally start the scroller thread here + # because it doesn't seem possible to start a new thrad + # from the USR2 signal handler + @scroller ||= Thread.new do + loop do + scroll if active? + sleep 1 + end + end + + push_activity(Thread.current, activity) + yield + ensure + pop_activity(Thread.current) + end + + def self.setproctitle + @oldname ||= $0 + $0 = "#{base}: " + rotate(process_name,@x) if active? + end + + def self.push_activity(thread, activity) + mutex.synchronize do + @reason ||= {} + @reason[thread] ||= [] + @reason[thread].push(activity) + setproctitle + end + end + + def self.pop_activity(thread) + mutex.synchronize do + @reason[thread].pop + if @reason[thread].empty? + @reason.delete(thread) + end + setproctitle + end + end + + def self.process_name + out = (@reason || {}).inject([]) do |out, reason| + out << "#{thread_id(reason[0])} #{reason[1].join(',')}" + end + out.join(' | ') + end + + # certainly non-portable + def self.thread_id(thread) + thread.inspect.gsub(/^#<.*:0x([a-f0-9]+) .*>$/, '\1') + end + + def self.rotate(string, steps) + steps ||= 0 + if string.length > 0 && steps > 0 + steps = steps % string.length + return string[steps..string.length].concat " -- #{string[0..(steps-1)]}" + end + string + end + + def self.base + basename = case Puppet.run_mode.name + when :master + "master" + when :agent + "agent" + else + "puppet" + end + end + + def self.mutex + #Thread.exclusive { + @mutex ||= Sync.new + #} + @mutex + end + + def self.scroll + return if process_name.length < SCROLL_LENGTH + mutex.synchronize do + setproctitle + @x += 1 + end + end + + end +end
\ No newline at end of file |
