trace_viz 0.0.2 → 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 +68 -43
- data/Steepfile +34 -0
- data/examples/eu_central_bank.rb +69 -0
- data/examples/example.cast +189 -285
- data/lib/trace_viz/adapters/base_adapter.rb +24 -1
- data/lib/trace_viz/adapters/trace_point_adapter.rb +3 -10
- 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/base_collector.rb +42 -35
- data/lib/trace_viz/collectors/filters/base_class_filter.rb +31 -0
- data/lib/trace_viz/collectors/filters/base_exclude_filter.rb +16 -0
- data/lib/trace_viz/collectors/filters/base_filter.rb +2 -8
- data/lib/trace_viz/collectors/filters/base_include_filter.rb +16 -0
- data/lib/trace_viz/collectors/filters/exclude_classes_filter.rb +4 -17
- data/lib/trace_viz/collectors/filters/exclude_default_classes_filter.rb +22 -26
- data/lib/trace_viz/collectors/filters/include_classes_filter.rb +4 -17
- data/lib/trace_viz/collectors/hierarchy_linker.rb +30 -0
- data/lib/trace_viz/collectors/matchers/base_matcher.rb +13 -0
- data/lib/trace_viz/collectors/matchers/trace_point_action_matcher.rb +12 -10
- data/lib/trace_viz/collectors/matchers/within_depth_matcher.rb +6 -5
- data/lib/trace_viz/collectors/steps/assign_depth_for_call_step.rb +30 -0
- data/lib/trace_viz/collectors/steps/assign_depth_for_return_step.rb +39 -0
- data/lib/trace_viz/collectors/steps/base_step.rb +27 -0
- data/lib/trace_viz/collectors/steps/build_hierarchy_step.rb +32 -0
- data/lib/trace_viz/collectors/{evaluators/hidden_evaluator.rb → steps/hidden_step.rb} +9 -5
- data/lib/trace_viz/collectors/steps/linking_step.rb +36 -0
- data/lib/trace_viz/collectors/{evaluators/filter_evaluator.rb → steps/validation_step.rb} +9 -6
- data/lib/trace_viz/collectors/steps.rb +10 -0
- data/lib/trace_viz/collectors/trace_pipeline.rb +26 -0
- data/lib/trace_viz/collectors/trace_pipeline_builder.rb +29 -0
- data/lib/trace_viz/collectors/trace_point_collector.rb +1 -11
- data/lib/trace_viz/config/validator.rb +6 -5
- data/lib/trace_viz/configuration.rb +3 -3
- data/lib/trace_viz/context/tracking_context.rb +4 -0
- data/lib/trace_viz/core/tracer.rb +2 -0
- data/lib/trace_viz/defaults/actions.rb +84 -0
- data/lib/trace_viz/defaults/colors.rb +61 -0
- data/lib/trace_viz/defaults/config.rb +91 -0
- data/lib/trace_viz/defaults/themes.rb +66 -0
- data/lib/trace_viz/defaults.rb +10 -129
- data/lib/trace_viz/exporters/base_exporter.rb +31 -13
- data/lib/trace_viz/exporters/export_manager.rb +33 -0
- data/lib/trace_viz/exporters/mermaid_exporter.rb +17 -0
- data/lib/trace_viz/exporters/registry.rb +27 -0
- data/lib/trace_viz/exporters/text_exporter.rb +2 -2
- 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 +4 -30
- 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/base_formatter.rb +12 -0
- data/lib/trace_viz/formatters/export/formatter_factory.rb +22 -0
- data/lib/trace_viz/formatters/export/method_call_formatter.rb +21 -0
- data/lib/trace_viz/formatters/export/method_return_formatter.rb +22 -0
- data/lib/trace_viz/formatters/export/summary_group_formatter.rb +35 -0
- data/lib/trace_viz/formatters/helpers/depth_helper.rb +2 -8
- 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/indent_helper.rb +1 -1
- data/lib/trace_viz/formatters/helpers/log/color_helper.rb +23 -0
- data/lib/trace_viz/formatters/helpers/log/depth_helper.rb +22 -0
- data/lib/trace_viz/formatters/helpers/log/method_name_helper.rb +29 -0
- data/lib/trace_viz/formatters/helpers/log/params_helper.rb +55 -0
- data/lib/trace_viz/formatters/helpers/log/result_helper.rb +27 -0
- data/lib/trace_viz/formatters/helpers/log/summary/params_helper.rb +57 -0
- data/lib/trace_viz/formatters/helpers/method_details_helper.rb +1 -1
- data/lib/trace_viz/formatters/helpers/params_helper.rb +30 -9
- data/lib/trace_viz/formatters/helpers/result_helper.rb +5 -4
- data/lib/trace_viz/formatters/helpers/source_helper.rb +6 -4
- data/lib/trace_viz/formatters/helpers/summary/params_helper.rb +45 -0
- data/lib/trace_viz/formatters/helpers/summary/source_helper.rb +24 -0
- data/lib/trace_viz/formatters/helpers/time_helper.rb +2 -2
- data/lib/trace_viz/formatters/helpers.rb +10 -0
- data/lib/trace_viz/formatters/log/base_formatter.rb +13 -0
- data/lib/trace_viz/formatters/log/formatter_factory.rb +22 -0
- data/lib/trace_viz/formatters/log/method_call_formatter.rb +34 -0
- data/lib/trace_viz/formatters/log/method_return_formatter.rb +24 -0
- data/lib/trace_viz/formatters/log/summary_group_formatter.rb +40 -0
- data/lib/trace_viz/formatters/log/verbose_formatter.rb +14 -0
- data/lib/trace_viz/formatters/trace_data_formatter.rb +24 -0
- data/lib/trace_viz/helpers/config_helper.rb +17 -0
- data/lib/trace_viz/helpers/trace_point/param_helper.rb +98 -0
- data/lib/trace_viz/helpers/tracking_helper.rb +26 -0
- data/lib/trace_viz/helpers.rb +9 -0
- data/lib/trace_viz/logger.rb +9 -20
- data/lib/trace_viz/loggers/base_logger.rb +29 -0
- data/lib/trace_viz/loggers/log_level_resolver.rb +18 -0
- data/lib/trace_viz/loggers/logging_manager.rb +46 -0
- data/lib/trace_viz/loggers/post_collection_logger.rb +44 -0
- data/lib/trace_viz/loggers/trace_logger.rb +14 -18
- data/lib/trace_viz/loggers/trace_stats_logger.rb +28 -14
- 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 +27 -0
- data/lib/trace_viz/renderers/diagram/sequence_renderer.rb +59 -0
- data/lib/trace_viz/renderers/render_context.rb +17 -0
- data/lib/trace_viz/renderers/renderer_builder.rb +20 -0
- data/lib/trace_viz/renderers/renderer_factory.rb +29 -0
- data/lib/trace_viz/renderers/summary_renderer.rb +34 -0
- data/lib/trace_viz/renderers/verbose_renderer.rb +29 -0
- data/lib/trace_viz/shared/renderer_helper.rb +25 -0
- data/lib/trace_viz/shared.rb +8 -0
- data/lib/trace_viz/syntax/mermaid/sequence_syntax.rb +99 -0
- data/lib/trace_viz/trace_data/base.rb +22 -22
- data/lib/trace_viz/trace_data/node.rb +39 -0
- data/lib/trace_viz/trace_data/root_node.rb +24 -0
- data/lib/trace_viz/trace_data/summary_node.rb +45 -0
- data/lib/trace_viz/trace_data/trace_point/base.rb +26 -31
- data/lib/trace_viz/trace_data/trace_point/method_call.rb +25 -16
- data/lib/trace_viz/trace_data/trace_point/method_return.rb +21 -1
- data/lib/trace_viz/traits/depth_trackable.rb +13 -0
- data/lib/trace_viz/traits/identifiable.rb +25 -0
- data/lib/trace_viz/traits/time_trackable.rb +13 -0
- data/lib/trace_viz/traits.rb +10 -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/colorize.rb +6 -6
- 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/id_generator.rb +35 -0
- data/lib/trace_viz/utils.rb +8 -0
- data/lib/trace_viz/version.rb +1 -1
- data/sig/adapters/base_adapter.rbs +11 -0
- data/sig/adapters/trace_point_adapter.rbs +13 -0
- data/sig/collectors/filters/registry.rbs +13 -0
- data/sig/collectors/trace_point_collector.rbs +17 -0
- data/sig/config/copier.rbs +15 -0
- data/sig/config/validator.rbs +18 -0
- data/sig/configuration.rbs +22 -0
- data/sig/context/base_context.rbs +9 -0
- data/sig/context/config_context.rbs +13 -0
- data/sig/context/manager.rbs +10 -0
- data/sig/context/map.rbs +13 -0
- data/sig/context.rbs +5 -0
- data/sig/core/tracer.rbs +7 -0
- data/sig/core.rbs +4 -0
- data/sig/defaults.rbs +17 -0
- data/sig/errors.rbs +13 -0
- data/sig/logger.rbs +33 -0
- data/sig/trace_viz.rbs +1 -2
- data/sig/utils/colorize.rbs +8 -0
- data/sig/utils/format_utils/key_value_formatter.rbs +16 -0
- data/sig/utils/format_utils/value_truncator.rbs +19 -0
- data/sig/utils/format_utils.rbs +8 -0
- data/sig/version.rbs +3 -0
- metadata +124 -18
- data/lib/trace_viz/collectors/depth_manager.rb +0 -37
- data/lib/trace_viz/collectors/evaluators/base_evaluator.rb +0 -23
- data/lib/trace_viz/exporters/formatters/base_formatter.rb +0 -12
- data/lib/trace_viz/exporters/formatters/method_call_formatter.rb +0 -21
- data/lib/trace_viz/exporters/formatters/method_return_formatter.rb +0 -22
- data/lib/trace_viz/exporters/transformers/base_transformer.rb +0 -25
- data/lib/trace_viz/exporters/transformers/text_transformer.rb +0 -28
- data/lib/trace_viz/loggers/trace_builder.rb +0 -30
- data/lib/trace_viz/loggers/trace_formatters/base_formatter.rb +0 -32
- data/lib/trace_viz/loggers/trace_formatters/method_call_formatter.rb +0 -21
- data/lib/trace_viz/loggers/trace_formatters/method_return_formatter.rb +0 -22
- data/lib/trace_viz/utils/format_utils.rb +0 -67
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TraceViz
|
4
|
+
module Managers
|
5
|
+
module Diagram
|
6
|
+
class ParticipantsManager
|
7
|
+
def initialize(participants)
|
8
|
+
@participants_map = build_participants_map(participants)
|
9
|
+
end
|
10
|
+
|
11
|
+
def find(name)
|
12
|
+
@participants_map[name.to_s]
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def build_participants_map(participants)
|
18
|
+
participants.each_with_object({}) { |participant, memo| memo[participant.name] = participant }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -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
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TraceViz
|
4
|
+
module Renderers
|
5
|
+
class BaseRenderer
|
6
|
+
NodeLine = Struct.new(:data, :line)
|
7
|
+
|
8
|
+
def initialize(collector, context)
|
9
|
+
@collector = collector
|
10
|
+
@context = context
|
11
|
+
end
|
12
|
+
|
13
|
+
def render
|
14
|
+
to_lines.map { |line| line[:line] }.join("\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
# [ { line: 'line1' }, { line: 'line2' } ]
|
18
|
+
def to_lines
|
19
|
+
[]
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :collector, :context
|
25
|
+
end
|
26
|
+
end
|
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
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TraceViz
|
4
|
+
module Renderers
|
5
|
+
class RenderContext
|
6
|
+
attr_reader :formatter_factory
|
7
|
+
|
8
|
+
def initialize(formatter_factory:)
|
9
|
+
@formatter_factory = formatter_factory
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch_formatter(key)
|
13
|
+
formatter_factory.fetch_formatter(key)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -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
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "verbose_renderer"
|
4
|
+
require_relative "summary_renderer"
|
5
|
+
require_relative "diagram/sequence_renderer"
|
6
|
+
|
7
|
+
module TraceViz
|
8
|
+
module Renderers
|
9
|
+
class RendererFactory
|
10
|
+
RENDERERS = {
|
11
|
+
verbose: VerboseRenderer,
|
12
|
+
summary: SummaryRenderer,
|
13
|
+
sequence_diagram: Diagram::SequenceRenderer,
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
def initialize(collector, context)
|
17
|
+
@collector = collector
|
18
|
+
@context = context
|
19
|
+
end
|
20
|
+
|
21
|
+
def build(key)
|
22
|
+
renderer_class = RENDERERS[key]
|
23
|
+
raise ArgumentError, "Invalid renderer key: #{key}" unless renderer_class
|
24
|
+
|
25
|
+
renderer_class.new(@collector, @context)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base_renderer"
|
4
|
+
require "trace_viz/transformers/summary_transformer"
|
5
|
+
|
6
|
+
module TraceViz
|
7
|
+
module Renderers
|
8
|
+
class SummaryRenderer < BaseRenderer
|
9
|
+
def to_lines
|
10
|
+
render_nodes(data.children)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
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)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base_renderer"
|
4
|
+
|
5
|
+
module TraceViz
|
6
|
+
module Renderers
|
7
|
+
class VerboseRenderer < BaseRenderer
|
8
|
+
def to_lines
|
9
|
+
traverse_data(data)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def data
|
15
|
+
collector.collection
|
16
|
+
end
|
17
|
+
|
18
|
+
def traverse_data(data)
|
19
|
+
data.map do |trace_data|
|
20
|
+
NodeLine.new(trace_data, format_for(trace_data))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def format_for(trace_data)
|
25
|
+
context.fetch_formatter(trace_data.key).call(trace_data)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TraceViz
|
4
|
+
module Shared
|
5
|
+
module RendererHelper
|
6
|
+
def process_lines(lines, &block)
|
7
|
+
return [] unless lines.is_a?(Array)
|
8
|
+
|
9
|
+
lines.map do |line|
|
10
|
+
validate_line_structure!(line)
|
11
|
+
block.call(line)
|
12
|
+
end.compact
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def validate_line_structure!(line)
|
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
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
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
|
@@ -1,36 +1,36 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "trace_viz/
|
3
|
+
require "trace_viz/helpers"
|
4
|
+
require "trace_viz/traits"
|
4
5
|
|
5
6
|
module TraceViz
|
6
7
|
module TraceData
|
7
8
|
class Base
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
include Helpers::ConfigHelper
|
10
|
+
include Traits::DepthTrackable
|
11
|
+
include Traits::TimeTrackable
|
11
12
|
|
12
13
|
def initialize
|
13
|
-
|
14
|
-
|
15
|
-
@depth = 0
|
14
|
+
assign_depth(0)
|
16
15
|
record_timestamp
|
17
16
|
end
|
18
17
|
|
19
|
-
#
|
20
|
-
|
21
|
-
|
18
|
+
#
|
19
|
+
# Represents trace data type code
|
20
|
+
#
|
21
|
+
def key
|
22
|
+
:base
|
22
23
|
end
|
23
24
|
|
24
|
-
|
25
|
-
def action_id
|
25
|
+
def event
|
26
26
|
raise NotImplementedError
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
29
|
+
def klass
|
30
30
|
raise NotImplementedError
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
33
|
+
def action
|
34
34
|
raise NotImplementedError
|
35
35
|
end
|
36
36
|
|
@@ -42,14 +42,14 @@ module TraceViz
|
|
42
42
|
raise NotImplementedError
|
43
43
|
end
|
44
44
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
45
|
+
def to_h
|
46
|
+
{
|
47
|
+
event: event,
|
48
|
+
klass: klass,
|
49
|
+
action: action,
|
50
|
+
path: path,
|
51
|
+
line_number: line_number,
|
52
|
+
}
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base"
|
4
|
+
|
5
|
+
module TraceViz
|
6
|
+
module TraceData
|
7
|
+
class Node < Base
|
8
|
+
attr_accessor :parent
|
9
|
+
attr_reader :children
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
super()
|
13
|
+
|
14
|
+
@parent = nil
|
15
|
+
@children = []
|
16
|
+
end
|
17
|
+
|
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
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_h
|
30
|
+
super.merge(
|
31
|
+
{
|
32
|
+
parent: parent&.to_s,
|
33
|
+
children: children.map(&:to_h),
|
34
|
+
},
|
35
|
+
)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "node"
|
4
|
+
|
5
|
+
module TraceViz
|
6
|
+
module TraceData
|
7
|
+
class RootNode < Node
|
8
|
+
def initialize
|
9
|
+
super()
|
10
|
+
|
11
|
+
# Explicitly ensure no parent for root
|
12
|
+
@parent = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
def root?
|
16
|
+
true
|
17
|
+
end
|
18
|
+
|
19
|
+
def parent=(_parent)
|
20
|
+
raise NoMethodError, "RootNode cannot have a parent"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "node"
|
4
|
+
|
5
|
+
module TraceViz
|
6
|
+
module TraceData
|
7
|
+
class SummaryNode < Node
|
8
|
+
attr_reader :group, :count, :representative_node, :event, :klass, :action, :path, :params, :result
|
9
|
+
|
10
|
+
def initialize(group:)
|
11
|
+
super()
|
12
|
+
|
13
|
+
@group = group
|
14
|
+
@count = group.size
|
15
|
+
|
16
|
+
@representative_node = group.first
|
17
|
+
@depth = representative_node.depth
|
18
|
+
@event = representative_node.event
|
19
|
+
@klass = representative_node.klass
|
20
|
+
@path = representative_node.path
|
21
|
+
@action = representative_node.action
|
22
|
+
|
23
|
+
# Representative node is the first node in the group belonging to MethodCall
|
24
|
+
@params = representative_node.params
|
25
|
+
@result = representative_node.method_return.result
|
26
|
+
|
27
|
+
add_children(representative_node.children)
|
28
|
+
end
|
29
|
+
|
30
|
+
def key
|
31
|
+
:summary_group
|
32
|
+
end
|
33
|
+
|
34
|
+
def duration
|
35
|
+
return 0 if count.zero?
|
36
|
+
|
37
|
+
total_duration / count
|
38
|
+
end
|
39
|
+
|
40
|
+
def total_duration
|
41
|
+
children.map(&:duration).sum
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|