Skip to content

Commit c9b6cdb

Browse files
committed
fix: Optimize/improve string-ification of values
1 parent a6ff7ee commit c9b6cdb

File tree

5 files changed

+66
-12
lines changed

5 files changed

+66
-12
lines changed

lib/appmap/event.rb

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ def next_id_counter
2020
MethodEventStruct = Struct.new(:id, :event, :thread_id)
2121

2222
class MethodEvent < MethodEventStruct
23-
LIMIT = 100
23+
MAX_ARRAY_ENUMERATION = 10
24+
MAX_HASH_ENUMERATION = 10
25+
MAX_STRING_LENGTH = 100
2426

2527
class << self
2628
def build_from_invocation(event_type, event:)
@@ -48,14 +50,14 @@ def display_string(value)
4850
end
4951

5052
start = Time.now
51-
value_string = custom_display_string(value) || default_display_string(value)
53+
value_string, final = custom_display_string(value) || default_display_string(value)
5254

5355
if @times
5456
elapsed = Time.now - start
5557
@times[best_class_name(value)] += elapsed
5658
end
5759

58-
encode_display_string(value_string)
60+
final ? value_string : encode_display_string(value_string)
5961
end
6062

6163
def object_properties(hash_like)
@@ -80,21 +82,33 @@ def best_class_name(value)
8082
end
8183

8284
def encode_display_string(value)
83-
(value||'')[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
85+
(value||'')[0...MAX_STRING_LENGTH].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
8486
end
8587

8688
def custom_display_string(value)
8789
case value
8890
when NilClass, TrueClass, FalseClass, Numeric, Time, Date
89-
value.to_s
91+
[ value.to_s, true ]
92+
when Symbol
93+
[ ":#{value}", true ]
9094
when String
91-
value[0...LIMIT].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
95+
result = value[0...MAX_STRING_LENGTH].encode('utf-8', invalid: :replace, undef: :replace, replace: '_')
96+
result << " (...#{value.length - MAX_STRING_LENGTH} more characters)" if value.length > MAX_STRING_LENGTH
97+
[ result, true ]
98+
when Array
99+
result = value[0...MAX_ARRAY_ENUMERATION].map{|v| display_string(v)}.join(', ')
100+
result << " (...#{value.length - MAX_ARRAY_ENUMERATION} more items)" if value.length > MAX_ARRAY_ENUMERATION
101+
[ [ '[', result, ']' ].join, true ]
102+
when Hash
103+
result = value.keys[0...MAX_HASH_ENUMERATION].map{|key| "#{display_string(key)}=>#{display_string(value[key])}"}.join(', ')
104+
result << " (...#{value.size - MAX_HASH_ENUMERATION} more entries)" if value.size > MAX_HASH_ENUMERATION
105+
[ [ '{', result, '}' ].join, true ]
92106
when File
93-
"#{value.class}[path=#{value.path}]"
107+
[ "#{value.class}[path=#{value.path}]", true ]
94108
when Net::HTTP
95-
"#{value.class}[#{value.address}:#{value.port}]"
109+
[ "#{value.class}[#{value.address}:#{value.port}]", true ]
96110
when Net::HTTPGenericRequest
97-
"#{value.class}[#{value.method} #{value.path}]"
111+
[ "#{value.class}[#{value.method} #{value.path}]", true ]
98112
end
99113
rescue StandardError
100114
nil

spec/display_string_spec.rb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
require 'spec_helper'
4+
require 'appmap/event'
5+
6+
include AppMap
7+
8+
describe 'display_string' do
9+
def display_string(value)
10+
Event::MethodEvent.display_string value
11+
end
12+
13+
def compare_display_string(value, expected)
14+
expect(display_string(value)).to eq(expected)
15+
end
16+
17+
context 'for a' do
18+
it 'String' do
19+
compare_display_string 'foo', 'foo'
20+
end
21+
it 'long String' do
22+
compare_display_string 'foo' * 100, 'foo' * 33 + 'f (...200 more characters)'
23+
end
24+
it 'Array' do
25+
compare_display_string([ 1, 'my', :bar, [ 2, 3 ], { 4 => 5 } ], '[1, my, :bar, [2, 3], {4=>5}]')
26+
end
27+
it 'large Array' do
28+
compare_display_string 50.times.map { |i| i }, '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9 (...40 more items)]'
29+
end
30+
it 'large Hash' do
31+
compare_display_string(50.times.map { |i| [ i*2, i*2+1] }.to_h, '{0=>1, 2=>3, 4=>5, 6=>7, 8=>9, 10=>11, 12=>13, 14=>15, 16=>17, 18=>19 (...40 more entries)}')
32+
end
33+
it 'Hash' do
34+
compare_display_string({ 1 => 2, 'my' => 'neighbor', bar: :baz, ary: [ 1, 2 ]}, '{1=>2, my=>neighbor, :bar=>:baz, :ary=>[1, 2]}')
35+
end
36+
it 'big Hash' do
37+
compare_display_string(50.times.map { |i| [ i*2, i*2+1] }.to_h, '{0=>1, 2=>3, 4=>5, 6=>7, 8=>9, 10=>11, 12=>13, 14=>15, 16=>17, 18=>19 (...40 more entries)}')
38+
end
39+
end
40+
end

spec/hook_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1136,7 +1136,7 @@ def secure_compare(a, b)
11361136
:parameters:
11371137
- :name: :args
11381138
:class: Array
1139-
:value: '["foo"]'
1139+
:value: "[foo]"
11401140
:kind: :rest
11411141
- :name: :kw1
11421142
:class: String

spec/rails_recording_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def run_spec(spec_name)
7878
'name' => 'params',
7979
'class' => 'ActiveSupport::HashWithIndifferentAccess',
8080
'object_id' => Integer,
81-
'value' => '{"login"=>"alice"}',
81+
'value' => '{login=>alice}',
8282
'kind' => 'req'
8383
),
8484
'receiver' => anything

spec/record_net_http_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def stop_recording
127127
:message:
128128
- :name: ary
129129
:class: Array
130-
:value: '["1", "2"]'
130+
:value: "[1, 2]"
131131
EVENT
132132
end
133133

0 commit comments

Comments
 (0)