@@ -9,6 +9,7 @@ class Hook
9
9
10
10
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
11
11
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
12
13
13
14
@unbound_method_arity = ::UnboundMethod . instance_method ( :arity )
14
15
@method_arity = ::Method . instance_method ( :arity )
@@ -49,6 +50,27 @@ def enable(&block)
49
50
@notrace_paths = Set . new
50
51
# Locations that have already been visited.
51
52
@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
52
74
53
75
@trace_end = TracePoint . new ( :end , &method ( :trace_end ) )
54
76
@trace_end . enable ( &block )
@@ -157,6 +179,7 @@ def trace_end(trace_point)
157
179
end
158
180
end
159
181
182
+ start = Time . now
160
183
instance_methods . each ( &hook . ( cls ) )
161
184
begin
162
185
# NoMethodError: private method `singleton_class' called for Rack::MiniProfiler:Class
@@ -166,6 +189,11 @@ def trace_end(trace_point)
166
189
# uninitialized constant Faraday::Connection
167
190
warn "NameError in #{ __FILE__ } : #{ $!. message } "
168
191
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
169
197
end
170
198
end
171
199
end
0 commit comments