Class: AppMap::Event::MethodEvent
- Inherits:
-
MethodEventStruct
- Object
- Struct
- MethodEventStruct
- AppMap::Event::MethodEvent
- Defined in:
- lib/appmap/event.rb
Direct Known Subclasses
MethodCall, MethodReturnIgnoreValue, Handler::HTTPClientRequest, Handler::Rails::RequestHandler::HTTPServerRequest, Handler::Rails::Template::TemplateCall
Constant Summary collapse
- MAX_ARRAY_ENUMERATION =
10
- MAX_HASH_ENUMERATION =
10
- MAX_STRING_LENGTH =
100
Instance Attribute Summary
Attributes inherited from MethodEventStruct
Class Method Summary collapse
- .add_schema(param, value) ⇒ Object
- .add_size(param, value) ⇒ Object
-
.best_class_name(value) ⇒ Object
Heuristic for dynamically defined class whose name can be nil.
- .build_from_invocation(event_type, event:) ⇒ Object
- .custom_display_string(value) ⇒ Object
- .default_display_string(value) ⇒ Object
-
.display_string(value) ⇒ Object
Gets a display string for a value.
- .encode_display_string(value) ⇒ Object
Instance Method Summary collapse
-
#ready? ⇒ Boolean
An event may be partially constructed, and then completed at a later time.
Class Method Details
.add_schema(param, value) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/appmap/event.rb', line 70 def add_schema(param, value) begin if value.respond_to?(:keys) param[:properties] = value.keys.map { |key| { name: key, class: best_class_name(value[key]) } } elsif value.respond_to?(:first) && value.first if value.first != value add_schema param, value.first end end rescue warn "Error in add_schema(#{value.class})", $! end end |
.add_size(param, value) ⇒ Object
63 64 65 66 67 68 |
# File 'lib/appmap/event.rb', line 63 def add_size(param, value) # Don't risk calling #size on things like data-access objects, which can and will issue queries for this information. if value.is_a?(Array) || value.is_a?(Hash) param[:size] = value.size end end |
.best_class_name(value) ⇒ Object
Heuristic for dynamically defined class whose name can be nil
85 86 87 88 89 90 91 |
# File 'lib/appmap/event.rb', line 85 def best_class_name(value) value_cls = value.class while value_cls && value_cls.name.nil? value_cls = value_cls.superclass end value_cls&.name || 'unknown' end |
.build_from_invocation(event_type, event:) ⇒ Object
28 29 30 31 32 |
# File 'lib/appmap/event.rb', line 28 def build_from_invocation(event_type, event:) event.id = AppMap::Event.next_id_counter event.event = event_type event.thread_id = Thread.current.object_id end |
.custom_display_string(value) ⇒ Object
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 |
# File 'lib/appmap/event.rb', line 97 def custom_display_string(value) case value when NilClass, TrueClass, FalseClass, Numeric, Time, Date [ value.to_s, true ] when Symbol [ ":#{value}", true ] when String result = value[0...MAX_STRING_LENGTH].encode('utf-8', invalid: :replace, undef: :replace, replace: '_') result << " (...#{value.length - MAX_STRING_LENGTH} more characters)" if value.length > MAX_STRING_LENGTH [ result, true ] when Array result = value[0...MAX_ARRAY_ENUMERATION].map{|v| display_string(v)}.join(', ') result << " (...#{value.length - MAX_ARRAY_ENUMERATION} more items)" if value.length > MAX_ARRAY_ENUMERATION [ [ '[', result, ']' ].join, true ] when Hash result = value.keys[0...MAX_HASH_ENUMERATION].map{|key| "#{display_string(key)}=>#{display_string(value[key])}"}.join(', ') result << " (...#{value.size - MAX_HASH_ENUMERATION} more entries)" if value.size > MAX_HASH_ENUMERATION [ [ '{', result, '}' ].join, true ] when File [ "#{value.class}[path=#{value.path}]", true ] when Net::HTTP [ "#{value.class}[#{value.address}:#{value.port}]", true ] when Net::HTTPGenericRequest [ "#{value.class}[#{value.method} #{value.path}]", true ] end rescue StandardError nil end |
.default_display_string(value) ⇒ Object
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/appmap/event.rb', line 126 def default_display_string(value) return nil if ENV['APPMAP_OBJECT_STRING'] == 'false' last_resort_string = lambda do warn "AppMap encountered an error inspecting a #{value.class.name}: #{$!.}" '*Error inspecting variable*' end begin value.to_s rescue NoMethodError begin value.inspect rescue last_resort_string.call end rescue WeakRef::RefError nil rescue last_resort_string.call end end |
.display_string(value) ⇒ Object
Gets a display string for a value. This is not meant to be a machine deserializable value.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/appmap/event.rb', line 35 def display_string(value) return nil if value.equal?(nil) # With setting APPMAP_PROFILE_DISPLAY_STRING, stringifying this class is shown to take 9 seconds(!) of a 17 second test run. return nil if best_class_name(value) == 'ActiveSupport::Callbacks::Filters::Environment' if @times.nil? && ENV['APPMAP_PROFILE_DISPLAY_STRING'] == 'true' @times = Hash.new {|memo,key| memo[key] = 0} Thread.new do sleep 0.5 while true warn @times.to_a.sort{|a,b| b[1] <=> a[1]}[0..9].join("\n") sleep 3 end end end start = Time.now value_string, final = custom_display_string(value) || default_display_string(value) if @times elapsed = Time.now - start @times[best_class_name(value)] += elapsed end final ? value_string : encode_display_string(value_string) end |
.encode_display_string(value) ⇒ Object
93 94 95 |
# File 'lib/appmap/event.rb', line 93 def encode_display_string(value) (value||'')[0...MAX_STRING_LENGTH].encode('utf-8', invalid: :replace, undef: :replace, replace: '_') end |
Instance Method Details
#ready? ⇒ Boolean
An event may be partially constructed, and then completed at a later time. When the event is only partially constructed, it’s not ready for serialization to the AppMap file.
154 155 156 |
# File 'lib/appmap/event.rb', line 154 def ready? true end |