lumitrace 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/docs/spec.md +79 -1
- data/docs/tutorial.ja.md +4 -0
- data/docs/tutorial.md +4 -0
- data/lib/lumitrace/generate_resulted_html.rb +323 -391
- data/lib/lumitrace/generate_resulted_html_renderer.js +774 -0
- data/lib/lumitrace/record_instrument.rb +79 -22
- data/lib/lumitrace/version.rb +1 -1
- data/lib/lumitrace.rb +31 -4
- data/runv/index.html +1182 -420
- data/runv/sync_inline.rb +13 -1
- data/test/test_lumitrace.rb +137 -0
- metadata +2 -1
|
@@ -7,6 +7,8 @@ module Lumitrace
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
module RecordInstrument
|
|
10
|
+
IDENTIFIER_METHOD_NAME_RE = /\A[a-z_]\w*[!?=]?\z/.freeze
|
|
11
|
+
|
|
10
12
|
SKIP_NODE_CLASSES = [
|
|
11
13
|
Prism::DefNode,
|
|
12
14
|
Prism::ClassNode,
|
|
@@ -99,7 +101,7 @@ module RecordInstrument
|
|
|
99
101
|
end
|
|
100
102
|
end
|
|
101
103
|
|
|
102
|
-
node.
|
|
104
|
+
instrumentable_child_nodes(node).each { |child| stack << [child, node] }
|
|
103
105
|
end
|
|
104
106
|
locs
|
|
105
107
|
end
|
|
@@ -136,7 +138,7 @@ module RecordInstrument
|
|
|
136
138
|
end
|
|
137
139
|
end
|
|
138
140
|
|
|
139
|
-
node.
|
|
141
|
+
instrumentable_child_nodes(node).each { |child| stack << [child, node] }
|
|
140
142
|
end
|
|
141
143
|
|
|
142
144
|
inserts
|
|
@@ -177,6 +179,8 @@ module RecordInstrument
|
|
|
177
179
|
def self.wrap_expr?(node, parent = nil)
|
|
178
180
|
return false unless node.respond_to?(:location)
|
|
179
181
|
return false if literal_value_node?(node)
|
|
182
|
+
return false if command_style_call_node?(node)
|
|
183
|
+
return false if parent.is_a?(Prism::DefinedNode)
|
|
180
184
|
if parent.is_a?(Prism::AliasGlobalVariableNode) || parent.is_a?(Prism::AliasMethodNode)
|
|
181
185
|
return false
|
|
182
186
|
end
|
|
@@ -196,6 +200,27 @@ module RecordInstrument
|
|
|
196
200
|
WRAP_NODE_CLASSES.include?(node.class)
|
|
197
201
|
end
|
|
198
202
|
|
|
203
|
+
def self.command_style_call_node?(node)
|
|
204
|
+
return false unless node.is_a?(Prism::CallNode)
|
|
205
|
+
return false unless node.respond_to?(:arguments) && node.arguments
|
|
206
|
+
return false if node.respond_to?(:opening_loc) && node.opening_loc
|
|
207
|
+
|
|
208
|
+
name = node.respond_to?(:name) ? node.name : nil
|
|
209
|
+
return false unless name
|
|
210
|
+
|
|
211
|
+
IDENTIFIER_METHOD_NAME_RE.match?(name.to_s)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def self.instrumentable_child_nodes(node)
|
|
215
|
+
return [] unless node
|
|
216
|
+
return [] if node.is_a?(Prism::DefinedNode)
|
|
217
|
+
if command_style_call_node?(node) && node.respond_to?(:block) && node.block
|
|
218
|
+
[node.block]
|
|
219
|
+
else
|
|
220
|
+
node.child_nodes
|
|
221
|
+
end
|
|
222
|
+
end
|
|
223
|
+
|
|
199
224
|
def self.expr_location(node)
|
|
200
225
|
loc = node.location
|
|
201
226
|
return {
|
|
@@ -341,22 +366,31 @@ module RecordInstrument
|
|
|
341
366
|
|
|
342
367
|
def self.events_from_ids
|
|
343
368
|
out = []
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
loc = @loc_by_id[id]
|
|
369
|
+
summary_cache = {}
|
|
370
|
+
@loc_by_id.each_with_index do |loc, id|
|
|
347
371
|
next unless loc
|
|
372
|
+
|
|
373
|
+
e = @events_by_id[id]
|
|
348
374
|
case collect_mode
|
|
349
375
|
when :history
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
all_types
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
376
|
+
if e
|
|
377
|
+
raw_values = values_from_ring(e)
|
|
378
|
+
all_types = history_type_set(e)
|
|
379
|
+
if all_types.nil? || all_types.empty?
|
|
380
|
+
all_types = {}
|
|
381
|
+
raw_values.each do |v|
|
|
382
|
+
t = value_type_name(v)
|
|
383
|
+
all_types[t] = (all_types[t] || 0) + 1
|
|
384
|
+
end
|
|
357
385
|
end
|
|
386
|
+
max = history_ring_size(e)
|
|
387
|
+
total = e[max + 1]
|
|
388
|
+
else
|
|
389
|
+
raw_values = []
|
|
390
|
+
all_types = {}
|
|
391
|
+
total = 0
|
|
358
392
|
end
|
|
359
|
-
|
|
393
|
+
|
|
360
394
|
out << {
|
|
361
395
|
file: loc[:file],
|
|
362
396
|
start_line: loc[:start_line],
|
|
@@ -365,9 +399,20 @@ module RecordInstrument
|
|
|
365
399
|
end_col: loc[:end_col],
|
|
366
400
|
kind: loc[:kind].to_s,
|
|
367
401
|
name: loc[:name],
|
|
368
|
-
sampled_values: raw_values.map
|
|
402
|
+
sampled_values: raw_values.map do |v|
|
|
403
|
+
key = v.__id__
|
|
404
|
+
cached = summary_cache[key]
|
|
405
|
+
if cached
|
|
406
|
+
cached.dup
|
|
407
|
+
else
|
|
408
|
+
type = value_type_name(v)
|
|
409
|
+
summary = summarize_value(v, type: type)
|
|
410
|
+
summary_cache[key] = summary
|
|
411
|
+
summary.dup
|
|
412
|
+
end
|
|
413
|
+
end,
|
|
369
414
|
types: sorted_type_counts(all_types),
|
|
370
|
-
total:
|
|
415
|
+
total: total
|
|
371
416
|
}
|
|
372
417
|
when :types
|
|
373
418
|
out << {
|
|
@@ -378,12 +423,12 @@ module RecordInstrument
|
|
|
378
423
|
end_col: loc[:end_col],
|
|
379
424
|
kind: loc[:kind].to_s,
|
|
380
425
|
name: loc[:name],
|
|
381
|
-
types: sorted_type_counts(e[:types]),
|
|
382
|
-
total: e[:total]
|
|
426
|
+
types: sorted_type_counts(e ? e[:types] : nil),
|
|
427
|
+
total: e ? e[:total] : 0
|
|
383
428
|
}
|
|
384
429
|
else # :last
|
|
385
|
-
last_raw = e[:last_value]
|
|
386
|
-
last_type = value_type_name(last_raw)
|
|
430
|
+
last_raw = e && e[:last_value]
|
|
431
|
+
last_type = value_type_name(last_raw) if e
|
|
387
432
|
out << {
|
|
388
433
|
file: loc[:file],
|
|
389
434
|
start_line: loc[:start_line],
|
|
@@ -392,9 +437,21 @@ module RecordInstrument
|
|
|
392
437
|
end_col: loc[:end_col],
|
|
393
438
|
kind: loc[:kind].to_s,
|
|
394
439
|
name: loc[:name],
|
|
395
|
-
last_value:
|
|
396
|
-
|
|
397
|
-
|
|
440
|
+
last_value: if e
|
|
441
|
+
key = last_raw.__id__
|
|
442
|
+
cached = summary_cache[key]
|
|
443
|
+
if cached
|
|
444
|
+
cached.dup
|
|
445
|
+
else
|
|
446
|
+
summary = summarize_value(last_raw, type: last_type)
|
|
447
|
+
summary_cache[key] = summary
|
|
448
|
+
summary.dup
|
|
449
|
+
end
|
|
450
|
+
else
|
|
451
|
+
nil
|
|
452
|
+
end,
|
|
453
|
+
types: sorted_type_counts(e ? e[:types] : nil),
|
|
454
|
+
total: e ? e[:total] : 0
|
|
398
455
|
}
|
|
399
456
|
end
|
|
400
457
|
end
|
data/lib/lumitrace/version.rb
CHANGED
data/lib/lumitrace.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "json"
|
|
4
|
+
require "shellwords"
|
|
4
5
|
require "tmpdir"
|
|
5
6
|
require_relative "lumitrace/version"
|
|
6
7
|
require_relative "lumitrace/record_instrument"
|
|
@@ -34,6 +35,16 @@ module Lumitrace
|
|
|
34
35
|
$stderr.puts("[lumitrace] #{message}")
|
|
35
36
|
end
|
|
36
37
|
|
|
38
|
+
def self.current_command_text
|
|
39
|
+
argv0 = $0.to_s
|
|
40
|
+
args = Array(ARGV).map(&:to_s)
|
|
41
|
+
parts = []
|
|
42
|
+
parts << argv0 unless argv0.empty?
|
|
43
|
+
parts.concat(args)
|
|
44
|
+
return nil if parts.empty?
|
|
45
|
+
Shellwords.join(parts)
|
|
46
|
+
end
|
|
47
|
+
|
|
37
48
|
def self.normalize_collect_mode(mode)
|
|
38
49
|
m = mode.to_s.strip
|
|
39
50
|
m = "last" if m.empty?
|
|
@@ -459,13 +470,22 @@ module Lumitrace
|
|
|
459
470
|
next
|
|
460
471
|
end
|
|
461
472
|
|
|
473
|
+
events_collect_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
462
474
|
events = RecordInstrument.events
|
|
475
|
+
events_collect_ms = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - events_collect_start) * 1000.0
|
|
476
|
+
verbose_log(format("events: collect %.1fms count=%d", events_collect_ms, events.length)) if @verbose_level.to_i > 0
|
|
477
|
+
|
|
478
|
+
detail_logger = (@verbose_level.to_i > 1 ? method(:verbose_log) : nil)
|
|
479
|
+
|
|
480
|
+
events_merge_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
463
481
|
events = RecordInstrument.merge_child_events(
|
|
464
482
|
events,
|
|
465
483
|
@results_dir,
|
|
466
484
|
max_samples: @atexit_max_samples,
|
|
467
|
-
logger:
|
|
485
|
+
logger: detail_logger
|
|
468
486
|
)
|
|
487
|
+
events_merge_ms = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - events_merge_start) * 1000.0
|
|
488
|
+
verbose_log(format("events: merge_children %.1fms count=%d", events_merge_ms, events.length)) if @verbose_level.to_i > 0
|
|
469
489
|
|
|
470
490
|
if @atexit_json
|
|
471
491
|
json_path = @atexit_json == true ? "lumitrace_recorded.json" : @atexit_json
|
|
@@ -476,7 +496,7 @@ module Lumitrace
|
|
|
476
496
|
end
|
|
477
497
|
if @atexit_text
|
|
478
498
|
tty = @atexit_text == true ? $stdout.tty? : false
|
|
479
|
-
text = GenerateResultedHtml.
|
|
499
|
+
text = GenerateResultedHtml.render_text_all_from_normalized_events(
|
|
480
500
|
events,
|
|
481
501
|
root: @atexit_output_root,
|
|
482
502
|
ranges_by_file: @atexit_ranges_by_file,
|
|
@@ -493,16 +513,23 @@ module Lumitrace
|
|
|
493
513
|
end
|
|
494
514
|
end
|
|
495
515
|
if @atexit_html
|
|
496
|
-
|
|
516
|
+
html_render_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
517
|
+
html = GenerateResultedHtml.render_all_from_normalized_events(
|
|
497
518
|
events,
|
|
498
519
|
root: @atexit_output_root,
|
|
499
520
|
ranges_by_file: @atexit_ranges_by_file,
|
|
500
521
|
collect_mode: @atexit_collect_mode,
|
|
501
|
-
max_samples: @atexit_max_samples
|
|
522
|
+
max_samples: @atexit_max_samples,
|
|
523
|
+
logger: detail_logger,
|
|
524
|
+
command_text: current_command_text
|
|
502
525
|
)
|
|
526
|
+
html_render_ms = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - html_render_start) * 1000.0
|
|
503
527
|
out_path = @atexit_html == true ? "lumitrace_recorded.html" : @atexit_html
|
|
504
528
|
out_path = File.expand_path(out_path, @atexit_output_root)
|
|
529
|
+
html_write_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
505
530
|
File.write(out_path, html)
|
|
531
|
+
html_write_ms = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - html_write_start) * 1000.0
|
|
532
|
+
verbose_log(format("html: render %.1fms write %.1fms bytes=%d", html_render_ms, html_write_ms, html.bytesize)) if @verbose_level.to_i > 0
|
|
506
533
|
verbose_log("html: #{out_path}")
|
|
507
534
|
notify_output_path("html", out_path)
|
|
508
535
|
end
|