@@ -9,6 +9,7 @@ class Hook
99
1010 OBJECT_INSTANCE_METHODS = %i[ ! != !~ <=> == === =~ __id__ __send__ class clone define_singleton_method display dup enum_for eql? equal? extend freeze frozen? hash inspect instance_eval instance_exec instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself kind_of? method methods nil? object_id private_methods protected_methods public_method public_methods public_send remove_instance_variable respond_to? send singleton_class singleton_method singleton_methods taint tainted? tap then to_enum to_s to_h to_a trust untaint untrust untrusted? yield_self ] . freeze
1111 OBJECT_STATIC_METHODS = %i[ ! != !~ < <= <=> == === =~ > >= __id__ __send__ alias_method allocate ancestors attr attr_accessor attr_reader attr_writer autoload autoload? class class_eval class_exec class_variable_defined? class_variable_get class_variable_set class_variables clone const_defined? const_get const_missing const_set constants define_method define_singleton_method deprecate_constant display dup enum_for eql? equal? extend freeze frozen? hash include include? included_modules inspect instance_eval instance_exec instance_method instance_methods instance_of? instance_variable_defined? instance_variable_get instance_variable_set instance_variables is_a? itself kind_of? method method_defined? methods module_eval module_exec name new nil? object_id prepend private_class_method private_constant private_instance_methods private_method_defined? private_methods protected_instance_methods protected_method_defined? protected_methods public_class_method public_constant public_instance_method public_instance_methods public_method public_method_defined? public_methods public_send remove_class_variable remove_instance_variable remove_method respond_to? send singleton_class singleton_class? singleton_method singleton_methods superclass taint tainted? tap then to_enum to_s trust undef_method untaint untrust untrusted? yield_self ] . freeze
12+ SLOW_PACKAGE_THRESHOLD = 0.05
1213
1314 @unbound_method_arity = ::UnboundMethod . instance_method ( :arity )
1415 @method_arity = ::Method . instance_method ( :arity )
@@ -49,6 +50,27 @@ def enable(&block)
4950 @notrace_paths = Set . new
5051 # Locations that have already been visited.
5152 @trace_locations = Set . new
53+ @module_load_times = Hash . new { |memo , k | memo [ k ] = 0 }
54+ @slow_packages = Set . new
55+
56+ if ENV [ 'APPMAP_PROFILE_HOOK' ] == 'true'
57+ Thread . new do
58+ sleep 1
59+ while true
60+ @module_load_times
61+ . keys
62+ . select { |key | !@slow_packages . member? ( key ) }
63+ . each do |key |
64+ elapsed = @module_load_times [ key ]
65+ if elapsed >= SLOW_PACKAGE_THRESHOLD
66+ @slow_packages . add ( key )
67+ warn "AppMap: Package #{ key } took #{ @module_load_times [ key ] } seconds to hook"
68+ end
69+ end
70+ sleep 5
71+ end
72+ end
73+ end
5274
5375 @trace_end = TracePoint . new ( :end , &method ( :trace_end ) )
5476 @trace_end . enable ( &block )
@@ -157,6 +179,7 @@ def trace_end(trace_point)
157179 end
158180 end
159181
182+ start = Time . now
160183 instance_methods . each ( &hook . ( cls ) )
161184 begin
162185 # NoMethodError: private method `singleton_class' called for Rack::MiniProfiler:Class
@@ -166,6 +189,11 @@ def trace_end(trace_point)
166189 # uninitialized constant Faraday::Connection
167190 warn "NameError in #{ __FILE__ } : #{ $!. message } "
168191 end
192+ elapsed = Time . now - start
193+ if location . index ( Bundler . bundle_path . to_s ) == 0
194+ package_tokens = location [ Bundler . bundle_path . to_s . length + 1 ..-1 ] . split ( '/' )
195+ @module_load_times [ package_tokens [ 1 ] ] += elapsed
196+ end
169197 end
170198 end
171199end
0 commit comments