trace_viz 1.0.0 → 1.0.1
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/README.md +63 -41
- data/lib/trace_viz/builders/base_builder.rb +11 -0
- data/lib/trace_viz/builders/diagram/base_builder.rb +10 -0
- data/lib/trace_viz/builders/diagram/message_builder.rb +96 -0
- data/lib/trace_viz/builders/diagram/sequence_builder.rb +50 -0
- data/lib/trace_viz/collectors/filters/base_class_filter.rb +3 -1
- data/lib/trace_viz/config/validator.rb +1 -1
- data/lib/trace_viz/defaults/config.rb +4 -2
- data/lib/trace_viz/exporters/base_exporter.rb +26 -5
- data/lib/trace_viz/exporters/mermaid_exporter.rb +17 -0
- data/lib/trace_viz/exporters/registry.rb +2 -0
- data/lib/trace_viz/exporters/text_exporter.rb +2 -24
- data/lib/trace_viz/extractors/base_extractor.rb +17 -0
- data/lib/trace_viz/extractors/diagram/base_extractor.rb +18 -0
- data/lib/trace_viz/extractors/diagram/box_extractor.rb +50 -0
- data/lib/trace_viz/extractors/diagram/message_extractor.rb +23 -0
- data/lib/trace_viz/extractors/diagram/participant_extractor.rb +37 -0
- data/lib/trace_viz/extractors/diagram/processors/message_processor.rb +93 -0
- data/lib/trace_viz/formatters/base_formatter.rb +1 -0
- data/lib/trace_viz/formatters/base_formatter_factory.rb +23 -0
- data/lib/trace_viz/formatters/diagram/sequence/base_formatter.rb +14 -0
- data/lib/trace_viz/formatters/diagram/sequence/message_formatter.rb +37 -0
- data/lib/trace_viz/formatters/diagram_formatter.rb +10 -0
- data/lib/trace_viz/formatters/export/formatter_factory.rb +8 -13
- data/lib/trace_viz/formatters/export/summary_group_formatter.rb +1 -1
- data/lib/trace_viz/formatters/helpers/digram/action_helper.rb +17 -0
- data/lib/trace_viz/formatters/helpers/digram/result_helper.rb +39 -0
- data/lib/trace_viz/formatters/helpers/log/params_helper.rb +8 -4
- data/lib/trace_viz/formatters/helpers/log/result_helper.rb +3 -3
- data/lib/trace_viz/formatters/helpers/log/summary/params_helper.rb +8 -4
- data/lib/trace_viz/formatters/helpers/params_helper.rb +8 -4
- data/lib/trace_viz/formatters/helpers/result_helper.rb +4 -3
- data/lib/trace_viz/formatters/helpers/source_helper.rb +4 -3
- data/lib/trace_viz/formatters/helpers/summary/params_helper.rb +7 -3
- data/lib/trace_viz/formatters/helpers/summary/source_helper.rb +3 -3
- data/lib/trace_viz/formatters/log/formatter_factory.rb +8 -13
- data/lib/trace_viz/formatters/log/summary_group_formatter.rb +1 -1
- data/lib/trace_viz/helpers/config_helper.rb +4 -0
- data/lib/trace_viz/loggers/post_collection_logger.rb +9 -4
- data/lib/trace_viz/loggers/trace_logger.rb +3 -6
- data/lib/trace_viz/managers/diagram/participant_manager.rb +23 -0
- data/lib/trace_viz/models/box.rb +19 -0
- data/lib/trace_viz/models/diagram.rb +27 -0
- data/lib/trace_viz/models/message.rb +16 -0
- data/lib/trace_viz/models/participant.rb +18 -0
- data/lib/trace_viz/models.rb +8 -0
- data/lib/trace_viz/renderers/base_renderer.rb +6 -3
- data/lib/trace_viz/renderers/diagram/sequence_renderer.rb +59 -0
- data/lib/trace_viz/renderers/render_context.rb +2 -3
- data/lib/trace_viz/renderers/renderer_builder.rb +20 -0
- data/lib/trace_viz/renderers/renderer_factory.rb +10 -22
- data/lib/trace_viz/renderers/summary_renderer.rb +18 -6
- data/lib/trace_viz/renderers/verbose_renderer.rb +6 -6
- data/lib/trace_viz/shared/renderer_helper.rb +4 -25
- data/lib/trace_viz/syntax/mermaid/sequence_syntax.rb +99 -0
- data/lib/trace_viz/trace_data/base.rb +7 -0
- data/lib/trace_viz/trace_data/node.rb +9 -3
- data/lib/trace_viz/trace_data/root_node.rb +4 -0
- data/lib/trace_viz/trace_data/summary_node.rb +5 -9
- data/lib/trace_viz/trace_data/trace_point/base.rb +4 -0
- data/lib/trace_viz/trace_data/trace_point/method_call.rb +4 -0
- data/lib/trace_viz/transformers/base_transformer.rb +29 -0
- data/lib/trace_viz/transformers/summary_transformer.rb +70 -0
- data/lib/trace_viz/utils/alias_generator.rb +58 -0
- data/lib/trace_viz/utils/format/key_value_formatter.rb +42 -0
- data/lib/trace_viz/utils/format/value_truncator.rb +123 -0
- data/lib/trace_viz/utils.rb +8 -0
- data/lib/trace_viz/version.rb +1 -1
- metadata +38 -11
- data/lib/trace_viz/renderers/summary/node_processor.rb +0 -82
- data/lib/trace_viz/utils/format_utils/key_value_formatter.rb +0 -37
- data/lib/trace_viz/utils/format_utils/value_truncator.rb +0 -74
- data/lib/trace_viz/utils/format_utils.rb +0 -24
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TraceViz
|
4
|
+
module Models
|
5
|
+
class Box
|
6
|
+
attr_reader :participants, :color, :description
|
7
|
+
|
8
|
+
def initialize(color:, description:)
|
9
|
+
@color = color
|
10
|
+
@description = description
|
11
|
+
@participants = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_participant(participant)
|
15
|
+
@participants << participant
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TraceViz
|
4
|
+
module Models
|
5
|
+
class Diagram
|
6
|
+
attr_reader :boxes, :participants, :messages
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@boxes = []
|
10
|
+
@participants = []
|
11
|
+
@messages = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_box(box)
|
15
|
+
@boxes << box unless @boxes.include?(box)
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_participant(participant)
|
19
|
+
@participants << participant unless @participants.include?(participant)
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_message(message)
|
23
|
+
@messages << message
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TraceViz
|
4
|
+
module Models
|
5
|
+
class Message
|
6
|
+
attr_reader :type, :from, :to, :content
|
7
|
+
|
8
|
+
def initialize(type:, from:, to:, content:)
|
9
|
+
@type = type
|
10
|
+
@from = from
|
11
|
+
@to = to
|
12
|
+
@content = content
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TraceViz
|
4
|
+
module Models
|
5
|
+
class Participant
|
6
|
+
attr_accessor :name, :alias_name
|
7
|
+
|
8
|
+
def initialize(name:, alias_name: nil)
|
9
|
+
@name = name
|
10
|
+
@alias_name = alias_name
|
11
|
+
end
|
12
|
+
|
13
|
+
def ==(other)
|
14
|
+
name == other.name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -3,8 +3,10 @@
|
|
3
3
|
module TraceViz
|
4
4
|
module Renderers
|
5
5
|
class BaseRenderer
|
6
|
-
|
7
|
-
|
6
|
+
NodeLine = Struct.new(:data, :line)
|
7
|
+
|
8
|
+
def initialize(collector, context)
|
9
|
+
@collector = collector
|
8
10
|
@context = context
|
9
11
|
end
|
10
12
|
|
@@ -12,13 +14,14 @@ module TraceViz
|
|
12
14
|
to_lines.map { |line| line[:line] }.join("\n")
|
13
15
|
end
|
14
16
|
|
17
|
+
# [ { line: 'line1' }, { line: 'line2' } ]
|
15
18
|
def to_lines
|
16
19
|
[]
|
17
20
|
end
|
18
21
|
|
19
22
|
private
|
20
23
|
|
21
|
-
attr_reader :
|
24
|
+
attr_reader :collector, :context
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "../base_renderer"
|
4
|
+
require "trace_viz/builders/diagram/sequence_builder"
|
5
|
+
require "trace_viz/syntax/mermaid/sequence_syntax"
|
6
|
+
|
7
|
+
module TraceViz
|
8
|
+
module Renderers
|
9
|
+
module Diagram
|
10
|
+
class SequenceRenderer < BaseRenderer
|
11
|
+
def initialize(collector, context)
|
12
|
+
super(collector, context)
|
13
|
+
|
14
|
+
@builder = Builders::Diagram::SequenceBuilder.new(collector)
|
15
|
+
@syntax = Syntax::Mermaid::SequenceSyntax.new
|
16
|
+
@diagram = builder.build
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_lines
|
20
|
+
[
|
21
|
+
header_line,
|
22
|
+
*render_boxes,
|
23
|
+
*render_messages,
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :builder, :diagram, :syntax
|
30
|
+
|
31
|
+
def header_line
|
32
|
+
NodeLine.new(nil, syntax.header)
|
33
|
+
end
|
34
|
+
|
35
|
+
def render_boxes
|
36
|
+
diagram.boxes.flat_map { |box| render_box(box) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def render_messages
|
40
|
+
diagram.messages.map { |message| NodeLine.new(nil, syntax.message(message)) }
|
41
|
+
end
|
42
|
+
|
43
|
+
def render_box(box)
|
44
|
+
[
|
45
|
+
NodeLine.new(nil, syntax.box_start(box)),
|
46
|
+
*render_participants(box),
|
47
|
+
NodeLine.new(nil, syntax.box_end(box)),
|
48
|
+
]
|
49
|
+
end
|
50
|
+
|
51
|
+
def render_participants(box)
|
52
|
+
box.participants.map do |participant|
|
53
|
+
NodeLine.new(nil, syntax.participant(participant))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -3,11 +3,10 @@
|
|
3
3
|
module TraceViz
|
4
4
|
module Renderers
|
5
5
|
class RenderContext
|
6
|
-
attr_reader :formatter_factory
|
6
|
+
attr_reader :formatter_factory
|
7
7
|
|
8
|
-
def initialize(formatter_factory
|
8
|
+
def initialize(formatter_factory:)
|
9
9
|
@formatter_factory = formatter_factory
|
10
|
-
@group_keys = group_keys
|
11
10
|
end
|
12
11
|
|
13
12
|
def fetch_formatter(key)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "render_context"
|
4
|
+
require_relative "renderer_factory"
|
5
|
+
|
6
|
+
module TraceViz
|
7
|
+
module Renderers
|
8
|
+
class RendererBuilder
|
9
|
+
class << self
|
10
|
+
def build(collector, key:, formatter_factory:)
|
11
|
+
raise ArgumentError, "Renderer key must be provided" if key.nil?
|
12
|
+
|
13
|
+
render_context = RenderContext.new(formatter_factory: formatter_factory)
|
14
|
+
renderer_factory = RendererFactory.new(collector, render_context)
|
15
|
+
renderer_factory.build(key)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "verbose_renderer"
|
4
4
|
require_relative "summary_renderer"
|
5
|
+
require_relative "diagram/sequence_renderer"
|
5
6
|
|
6
7
|
module TraceViz
|
7
8
|
module Renderers
|
@@ -9,32 +10,19 @@ module TraceViz
|
|
9
10
|
RENDERERS = {
|
10
11
|
verbose: VerboseRenderer,
|
11
12
|
summary: SummaryRenderer,
|
13
|
+
sequence_diagram: Diagram::SequenceRenderer,
|
12
14
|
}.freeze
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
16
|
+
def initialize(collector, context)
|
17
|
+
@collector = collector
|
18
|
+
@context = context
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
21
|
+
def build(key)
|
22
|
+
renderer_class = RENDERERS[key]
|
23
|
+
raise ArgumentError, "Invalid renderer key: #{key}" unless renderer_class
|
27
24
|
|
28
|
-
|
29
|
-
case mode
|
30
|
-
when :verbose
|
31
|
-
collector.collection
|
32
|
-
when :summary
|
33
|
-
collector.hierarchy.root
|
34
|
-
else
|
35
|
-
raise ArgumentError, "Invalid mode for input determination: #{mode}"
|
36
|
-
end
|
37
|
-
end
|
25
|
+
renderer_class.new(@collector, @context)
|
38
26
|
end
|
39
27
|
end
|
40
28
|
end
|
@@ -1,21 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "base_renderer"
|
4
|
-
|
4
|
+
require "trace_viz/transformers/summary_transformer"
|
5
5
|
|
6
6
|
module TraceViz
|
7
7
|
module Renderers
|
8
8
|
class SummaryRenderer < BaseRenderer
|
9
9
|
def to_lines
|
10
|
-
|
11
|
-
|
12
|
-
NodeProcessor.new(data.children, context).process
|
10
|
+
render_nodes(data.children)
|
13
11
|
end
|
14
12
|
|
15
13
|
private
|
16
14
|
|
17
|
-
def
|
18
|
-
|
15
|
+
def data
|
16
|
+
Transformers::SummaryTransformer.new(collector).transform
|
17
|
+
end
|
18
|
+
|
19
|
+
def render_nodes(nodes)
|
20
|
+
nodes.flat_map { |node| render_node(node) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def render_node(node)
|
24
|
+
node_line = NodeLine.new(node.data, format_node(node.data))
|
25
|
+
|
26
|
+
[node_line] + render_nodes(node.children)
|
27
|
+
end
|
28
|
+
|
29
|
+
def format_node(data)
|
30
|
+
context.fetch_formatter(data.key).call(data)
|
19
31
|
end
|
20
32
|
end
|
21
33
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "base_renderer"
|
4
|
-
require "trace_viz/formatters/log/formatter_factory"
|
5
4
|
|
6
5
|
module TraceViz
|
7
6
|
module Renderers
|
@@ -12,17 +11,18 @@ module TraceViz
|
|
12
11
|
|
13
12
|
private
|
14
13
|
|
14
|
+
def data
|
15
|
+
collector.collection
|
16
|
+
end
|
17
|
+
|
15
18
|
def traverse_data(data)
|
16
19
|
data.map do |trace_data|
|
17
|
-
|
18
|
-
line: format_for(trace_data),
|
19
|
-
trace_data: trace_data,
|
20
|
-
}
|
20
|
+
NodeLine.new(trace_data, format_for(trace_data))
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
def format_for(trace_data)
|
25
|
-
context.fetch_formatter(trace_data.
|
25
|
+
context.fetch_formatter(trace_data.key).call(trace_data)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -1,27 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "trace_viz/renderers/renderer_factory"
|
4
|
-
require "trace_viz/renderers/render_context"
|
5
|
-
require "trace_viz/formatters/export/formatter_factory"
|
6
|
-
require "trace_viz/formatters/log/formatter_factory"
|
7
|
-
|
8
3
|
module TraceViz
|
9
4
|
module Shared
|
10
5
|
module RendererHelper
|
11
|
-
def build_renderer(collector, formatter_factory)
|
12
|
-
raise ArgumentError, "Collector cannot be nil" unless collector
|
13
|
-
raise ArgumentError, "FormatterFactory cannot be nil" unless formatter_factory
|
14
|
-
|
15
|
-
mode = fetch_config(collector, :mode)
|
16
|
-
group_keys = fetch_config(collector, :group_keys)
|
17
|
-
|
18
|
-
context = Renderers::RenderContext.new(
|
19
|
-
formatter_factory: formatter_factory,
|
20
|
-
group_keys: group_keys,
|
21
|
-
)
|
22
|
-
Renderers::RendererFactory.build(mode, collector, context: context)
|
23
|
-
end
|
24
|
-
|
25
6
|
def process_lines(lines, &block)
|
26
7
|
return [] unless lines.is_a?(Array)
|
27
8
|
|
@@ -33,13 +14,11 @@ module TraceViz
|
|
33
14
|
|
34
15
|
private
|
35
16
|
|
36
|
-
def fetch_config(collector, key)
|
37
|
-
collector.config.general[key]
|
38
|
-
end
|
39
|
-
|
40
17
|
def validate_line_structure!(line)
|
41
|
-
|
42
|
-
|
18
|
+
unless line.respond_to?(:line) && line.respond_to?(:data)
|
19
|
+
raise ArgumentError,
|
20
|
+
"Invalid line structure: #{line.inspect}. Expected an object with :line and :data attributes."
|
21
|
+
end
|
43
22
|
end
|
44
23
|
end
|
45
24
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "trace_viz/helpers"
|
4
|
+
|
5
|
+
module TraceViz
|
6
|
+
module Syntax
|
7
|
+
module Mermaid
|
8
|
+
class SequenceSyntax
|
9
|
+
include Helpers::ConfigHelper
|
10
|
+
|
11
|
+
def header
|
12
|
+
"sequenceDiagram"
|
13
|
+
end
|
14
|
+
|
15
|
+
def box_start(box)
|
16
|
+
"#{indent}box #{sanitize_name(box.color)} #{sanitize_name(box.description)}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def box_end(_box)
|
20
|
+
"#{indent}end"
|
21
|
+
end
|
22
|
+
|
23
|
+
def participant(participant)
|
24
|
+
alias_name = sanitize_name(participant.alias_name)
|
25
|
+
name = sanitize_name(participant.name)
|
26
|
+
"#{indent}participant #{alias_name} as #{name}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def message(message)
|
30
|
+
from = sanitize_name(message.from&.alias_name)
|
31
|
+
to = sanitize_name(message.to&.alias_name)
|
32
|
+
content = sanitize_name(message.content)
|
33
|
+
|
34
|
+
message_syntax(message.type, from, to, content)
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def message_syntax(type, from, to, content)
|
40
|
+
case type
|
41
|
+
when :call
|
42
|
+
"#{indent}#{from} ->> #{to}: #{content}"
|
43
|
+
when :return
|
44
|
+
"#{indent}#{from} -->> #{to}: #{content}"
|
45
|
+
when :activate
|
46
|
+
"#{indent}activate #{to}"
|
47
|
+
when :deactivate
|
48
|
+
"#{indent}deactivate #{to}"
|
49
|
+
when :loop_start
|
50
|
+
"#{indent}loop #{content}"
|
51
|
+
when :loop_end
|
52
|
+
"#{indent}end"
|
53
|
+
when :note
|
54
|
+
"#{indent}Note over #{to}: #{content}"
|
55
|
+
else
|
56
|
+
raise ArgumentError, "Unsupported message type: #{type}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def indent
|
61
|
+
" " * fetch_general_config(:tab_size)
|
62
|
+
end
|
63
|
+
|
64
|
+
def sanitize_name(name)
|
65
|
+
return "" if name.nil?
|
66
|
+
|
67
|
+
# Convert Symbols to Strings and handle string sanitization
|
68
|
+
name = name.to_s.dup
|
69
|
+
|
70
|
+
# Handle class name pattern
|
71
|
+
name.sub!(/^#<Class:/, "[Class]")
|
72
|
+
name.sub!(/>$/, "")
|
73
|
+
|
74
|
+
# Replace unconventional method names with readable alternatives
|
75
|
+
name.gsub!("[]=", "set_value")
|
76
|
+
name.gsub!(/<<\z/, "append")
|
77
|
+
name.gsub!("[]", "get_value")
|
78
|
+
name.gsub!(/\A=/, "assign")
|
79
|
+
|
80
|
+
# Escape specific HTML characters in one pass
|
81
|
+
name.gsub!(/[<>:]/) do |char|
|
82
|
+
case char
|
83
|
+
when "<"
|
84
|
+
"<"
|
85
|
+
when ">"
|
86
|
+
">"
|
87
|
+
# when ":"
|
88
|
+
# ":"
|
89
|
+
else
|
90
|
+
char
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
name
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -15,9 +15,15 @@ module TraceViz
|
|
15
15
|
@children = []
|
16
16
|
end
|
17
17
|
|
18
|
-
def add_child(
|
19
|
-
|
20
|
-
@children <<
|
18
|
+
def add_child(node)
|
19
|
+
node.parent = self
|
20
|
+
@children << node
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_children(nodes)
|
24
|
+
nodes.each do |node|
|
25
|
+
add_child(node)
|
26
|
+
end
|
21
27
|
end
|
22
28
|
|
23
29
|
def to_h
|
@@ -27,7 +27,11 @@ module TraceViz
|
|
27
27
|
add_children(representative_node.children)
|
28
28
|
end
|
29
29
|
|
30
|
-
def
|
30
|
+
def key
|
31
|
+
:summary_group
|
32
|
+
end
|
33
|
+
|
34
|
+
def duration
|
31
35
|
return 0 if count.zero?
|
32
36
|
|
33
37
|
total_duration / count
|
@@ -36,14 +40,6 @@ module TraceViz
|
|
36
40
|
def total_duration
|
37
41
|
children.map(&:duration).sum
|
38
42
|
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def add_children(nodes)
|
43
|
-
nodes.each do |node|
|
44
|
-
add_child(node)
|
45
|
-
end
|
46
|
-
end
|
47
43
|
end
|
48
44
|
end
|
49
45
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "trace_viz/helpers/config_helper"
|
4
|
+
|
5
|
+
module TraceViz
|
6
|
+
module Transformers
|
7
|
+
TransformedNode = Struct.new(:data, :children)
|
8
|
+
|
9
|
+
class BaseTransformer
|
10
|
+
include Helpers::ConfigHelper
|
11
|
+
|
12
|
+
def initialize(collector)
|
13
|
+
@collector = collector
|
14
|
+
end
|
15
|
+
|
16
|
+
def transform
|
17
|
+
raise NotImplementedError
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :collector
|
23
|
+
|
24
|
+
def data
|
25
|
+
raise NotImplementedError
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "trace_viz/trace_data/summary_node"
|
4
|
+
require_relative "base_transformer"
|
5
|
+
|
6
|
+
module TraceViz
|
7
|
+
module Transformers
|
8
|
+
class SummaryTransformer < BaseTransformer
|
9
|
+
def transform
|
10
|
+
return root_node unless valid_children?(root_node)
|
11
|
+
|
12
|
+
TransformedNode.new(
|
13
|
+
root_node,
|
14
|
+
transform_nodes(root_node.children),
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def valid_children?(node)
|
21
|
+
node.respond_to?(:children) && node.children.any?
|
22
|
+
end
|
23
|
+
|
24
|
+
def root_node
|
25
|
+
collector.hierarchy.root
|
26
|
+
end
|
27
|
+
|
28
|
+
def transform_nodes(nodes)
|
29
|
+
nodes.group_by { |node| node_key(node) }
|
30
|
+
.map { |_key, group| transform_group(group) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def node_key(node)
|
34
|
+
group_keys.map { |key| fetch_node_attribute(node, key) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def fetch_node_attribute(node, key)
|
38
|
+
node.respond_to?(key) ? node.public_send(key) : nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def transform_group(group)
|
42
|
+
if group.size > 1
|
43
|
+
create_summary_node(group)
|
44
|
+
else
|
45
|
+
create_single_node(group.first)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def create_summary_node(group)
|
50
|
+
summary_node = TraceData::SummaryNode.new(group: group)
|
51
|
+
|
52
|
+
TransformedNode.new(
|
53
|
+
summary_node,
|
54
|
+
transform_nodes(summary_node.children),
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_single_node(node)
|
59
|
+
TransformedNode.new(
|
60
|
+
node,
|
61
|
+
transform_nodes(node.children),
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
def group_keys
|
66
|
+
fetch_general_config(:group_keys)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|