Module: TraceView::API::Profiling
- Defined in:
- lib/traceview/api/profiling.rb
Overview
Module that provides profiling of arbitrary blocks of code
Instance Method Summary collapse
-
#profile(profile_name, report_kvs = {}, with_backtrace = false) ⇒ Object
Public: Profile a given block of code.
-
#profile_method(klass, method, opts = {}, extra_kvs = {}) ⇒ Object
Public: Profile a method on a class or module.
Instance Method Details
#profile(profile_name, report_kvs = {}, with_backtrace = false) ⇒ Object
Public: Profile a given block of code. Detect any exceptions thrown by the block and report errors.
profile_name - A name used to identify the block being profiled. report_kvs - A hash containing key/value pairs that will be reported along
with the event of this profile (optional).
with_backtrace - Boolean to indicate whether a backtrace should
be collected with this trace event.
Example
def computation(n)
TraceView::API.profile('fib', { :n => n }) do
fib(n)
end
end
Returns the result of the block.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/traceview/api/profiling.rb', line 28 def profile(profile_name, report_kvs = {}, with_backtrace = false) report_kvs[:Language] ||= :ruby report_kvs[:ProfileName] ||= profile_name report_kvs[:Backtrace] = TraceView::API.backtrace if with_backtrace TraceView::API.log(nil, :profile_entry, report_kvs) begin yield rescue => e log_exception(nil, e) raise ensure exit_kvs = {} exit_kvs[:Language] = :ruby exit_kvs[:ProfileName] = report_kvs[:ProfileName] TraceView::API.log(nil, :profile_exit, exit_kvs) end end |
#profile_method(klass, method, opts = {}, extra_kvs = {}) ⇒ Object
Public: Profile a method on a class or module. That method can be of any (accessible) type (instance, singleton, private, protected etc.).
klass - the class or module that has the method to profile method - the method to profile. Can be singleton, instance, private etc… opts - a hash specifying the one or more of the following options:
* :arguments - report the arguments passed to <tt>method</tt> on each profile (default: false)
* :result - report the return value of <tt>method</tt> on each profile (default: false)
* :backtrace - report the return value of <tt>method</tt> on each profile (default: false)
* :name - alternate name for the profile reported in the dashboard (default: method name)
extra_kvs - a hash containing any additional KVs you would like reported with the profile
Example
opts = {}
opts[:backtrace] = true
opts[:arguments] = false
opts[:name] = :array_sort
TraceView::API.profile_method(Array, :sort, opts)
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/traceview/api/profiling.rb', line 71 def profile_method(klass, method, opts = {}, extra_kvs = {}) # If we're on an unsupported platform (ahem Mac), just act # like we did something to nicely play the no-op part. return true unless TraceView.loaded if RUBY_VERSION < '1.9.3' TraceView.logger.warn '[traceview/error] profile_method: Use the legacy method profiling for Ruby versions before 1.9.3' return false elsif !klass.is_a?(Module) TraceView.logger.warn "[traceview/error] profile_method: Not sure what to do with #{klass}. Send a class or module." return false elsif !method.is_a?(Symbol) if method.is_a?(String) method = method.to_sym else TraceView.logger.warn "[traceview/error] profile_method: Not sure what to do with #{method}. Send a string or symbol for method." return false end end instance_method = klass.instance_methods.include?(method) || klass.private_instance_methods.include?(method) class_method = klass.singleton_methods.include?(method) # Make sure the request klass::method exists if !instance_method && !class_method TraceView.logger.warn "[traceview/error] profile_method: Can't instrument #{klass}.#{method} as it doesn't seem to exist." TraceView.logger.warn "[traceview/error] #{__FILE__}:#{__LINE__}" return false end # Strip '!' or '?' from method if present safe_method_name = method.to_s.chop if method.to_s =~ /\?$|\!$/ safe_method_name ||= method without_traceview = "#{safe_method_name}_without_traceview" with_traceview = "#{safe_method_name}_with_traceview" # Check if already profiled if klass.instance_methods.include?(with_traceview.to_sym) || klass.singleton_methods.include?(with_traceview.to_sym) TraceView.logger.warn "[traceview/error] profile_method: #{klass}::#{method} already profiled." TraceView.logger.warn "[traceview/error] profile_method: #{__FILE__}:#{__LINE__}" return false end source_location = [] if instance_method ::TraceView::Util.send_include(klass, ::TraceView::MethodProfiling) source_location = klass.instance_method(method).source_location elsif class_method ::TraceView::Util.send_extend(klass, ::TraceView::MethodProfiling) source_location = klass.method(method).source_location end report_kvs = collect_profile_kvs(klass, method, opts, extra_kvs, source_location) report_kvs[:MethodName] = safe_method_name if instance_method klass.class_eval do define_method(with_traceview) do |*args, &block| profile_wrapper(without_traceview, report_kvs, opts, *args, &block) end alias_method without_traceview, method.to_s alias_method method.to_s, with_traceview end elsif class_method klass.define_singleton_method(with_traceview) do |*args, &block| profile_wrapper(without_traceview, report_kvs, opts, *args, &block) end klass.singleton_class.class_eval do alias_method without_traceview, method.to_s alias_method method.to_s, with_traceview end end true end |