trace_viz 0.0.2 → 1.0.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.
Files changed (143) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +40 -37
  3. data/Steepfile +34 -0
  4. data/examples/eu_central_bank.rb +69 -0
  5. data/examples/example.cast +189 -285
  6. data/lib/trace_viz/adapters/base_adapter.rb +24 -1
  7. data/lib/trace_viz/adapters/trace_point_adapter.rb +3 -10
  8. data/lib/trace_viz/collectors/base_collector.rb +42 -35
  9. data/lib/trace_viz/collectors/filters/base_class_filter.rb +29 -0
  10. data/lib/trace_viz/collectors/filters/base_exclude_filter.rb +16 -0
  11. data/lib/trace_viz/collectors/filters/base_filter.rb +2 -8
  12. data/lib/trace_viz/collectors/filters/base_include_filter.rb +16 -0
  13. data/lib/trace_viz/collectors/filters/exclude_classes_filter.rb +4 -17
  14. data/lib/trace_viz/collectors/filters/exclude_default_classes_filter.rb +22 -26
  15. data/lib/trace_viz/collectors/filters/include_classes_filter.rb +4 -17
  16. data/lib/trace_viz/collectors/hierarchy_linker.rb +30 -0
  17. data/lib/trace_viz/collectors/matchers/base_matcher.rb +13 -0
  18. data/lib/trace_viz/collectors/matchers/trace_point_action_matcher.rb +12 -10
  19. data/lib/trace_viz/collectors/matchers/within_depth_matcher.rb +6 -5
  20. data/lib/trace_viz/collectors/steps/assign_depth_for_call_step.rb +30 -0
  21. data/lib/trace_viz/collectors/steps/assign_depth_for_return_step.rb +39 -0
  22. data/lib/trace_viz/collectors/steps/base_step.rb +27 -0
  23. data/lib/trace_viz/collectors/steps/build_hierarchy_step.rb +32 -0
  24. data/lib/trace_viz/collectors/{evaluators/hidden_evaluator.rb → steps/hidden_step.rb} +9 -5
  25. data/lib/trace_viz/collectors/steps/linking_step.rb +36 -0
  26. data/lib/trace_viz/collectors/{evaluators/filter_evaluator.rb → steps/validation_step.rb} +9 -6
  27. data/lib/trace_viz/collectors/steps.rb +10 -0
  28. data/lib/trace_viz/collectors/trace_pipeline.rb +26 -0
  29. data/lib/trace_viz/collectors/trace_pipeline_builder.rb +29 -0
  30. data/lib/trace_viz/collectors/trace_point_collector.rb +1 -11
  31. data/lib/trace_viz/config/validator.rb +6 -5
  32. data/lib/trace_viz/configuration.rb +3 -3
  33. data/lib/trace_viz/context/tracking_context.rb +4 -0
  34. data/lib/trace_viz/core/tracer.rb +2 -0
  35. data/lib/trace_viz/defaults/actions.rb +84 -0
  36. data/lib/trace_viz/defaults/colors.rb +61 -0
  37. data/lib/trace_viz/defaults/config.rb +89 -0
  38. data/lib/trace_viz/defaults/themes.rb +66 -0
  39. data/lib/trace_viz/defaults.rb +10 -129
  40. data/lib/trace_viz/exporters/base_exporter.rb +8 -11
  41. data/lib/trace_viz/exporters/export_manager.rb +33 -0
  42. data/lib/trace_viz/exporters/registry.rb +25 -0
  43. data/lib/trace_viz/exporters/text_exporter.rb +22 -0
  44. data/lib/trace_viz/formatters/base_formatter.rb +3 -30
  45. data/lib/trace_viz/formatters/export/base_formatter.rb +12 -0
  46. data/lib/trace_viz/formatters/export/formatter_factory.rb +27 -0
  47. data/lib/trace_viz/formatters/export/method_call_formatter.rb +21 -0
  48. data/lib/trace_viz/formatters/export/method_return_formatter.rb +22 -0
  49. data/lib/trace_viz/formatters/export/summary_group_formatter.rb +35 -0
  50. data/lib/trace_viz/formatters/helpers/depth_helper.rb +2 -8
  51. data/lib/trace_viz/formatters/helpers/indent_helper.rb +1 -1
  52. data/lib/trace_viz/formatters/helpers/log/color_helper.rb +23 -0
  53. data/lib/trace_viz/formatters/helpers/log/depth_helper.rb +22 -0
  54. data/lib/trace_viz/formatters/helpers/log/method_name_helper.rb +29 -0
  55. data/lib/trace_viz/formatters/helpers/log/params_helper.rb +51 -0
  56. data/lib/trace_viz/formatters/helpers/log/result_helper.rb +27 -0
  57. data/lib/trace_viz/formatters/helpers/log/summary/params_helper.rb +53 -0
  58. data/lib/trace_viz/formatters/helpers/method_details_helper.rb +1 -1
  59. data/lib/trace_viz/formatters/helpers/params_helper.rb +26 -9
  60. data/lib/trace_viz/formatters/helpers/result_helper.rb +1 -1
  61. data/lib/trace_viz/formatters/helpers/source_helper.rb +2 -1
  62. data/lib/trace_viz/formatters/helpers/summary/params_helper.rb +41 -0
  63. data/lib/trace_viz/formatters/helpers/summary/source_helper.rb +24 -0
  64. data/lib/trace_viz/formatters/helpers/time_helper.rb +2 -2
  65. data/lib/trace_viz/formatters/helpers.rb +10 -0
  66. data/lib/trace_viz/formatters/log/base_formatter.rb +13 -0
  67. data/lib/trace_viz/formatters/log/formatter_factory.rb +27 -0
  68. data/lib/trace_viz/formatters/log/method_call_formatter.rb +34 -0
  69. data/lib/trace_viz/formatters/log/method_return_formatter.rb +24 -0
  70. data/lib/trace_viz/formatters/log/summary_group_formatter.rb +40 -0
  71. data/lib/trace_viz/formatters/log/verbose_formatter.rb +14 -0
  72. data/lib/trace_viz/formatters/trace_data_formatter.rb +24 -0
  73. data/lib/trace_viz/helpers/config_helper.rb +13 -0
  74. data/lib/trace_viz/helpers/trace_point/param_helper.rb +98 -0
  75. data/lib/trace_viz/helpers/tracking_helper.rb +26 -0
  76. data/lib/trace_viz/helpers.rb +9 -0
  77. data/lib/trace_viz/logger.rb +9 -20
  78. data/lib/trace_viz/loggers/base_logger.rb +29 -0
  79. data/lib/trace_viz/loggers/log_level_resolver.rb +18 -0
  80. data/lib/trace_viz/loggers/logging_manager.rb +46 -0
  81. data/lib/trace_viz/loggers/post_collection_logger.rb +39 -0
  82. data/lib/trace_viz/loggers/trace_logger.rb +17 -18
  83. data/lib/trace_viz/loggers/trace_stats_logger.rb +28 -14
  84. data/lib/trace_viz/renderers/base_renderer.rb +24 -0
  85. data/lib/trace_viz/renderers/render_context.rb +18 -0
  86. data/lib/trace_viz/renderers/renderer_factory.rb +41 -0
  87. data/lib/trace_viz/renderers/summary/node_processor.rb +82 -0
  88. data/lib/trace_viz/renderers/summary_renderer.rb +22 -0
  89. data/lib/trace_viz/renderers/verbose_renderer.rb +29 -0
  90. data/lib/trace_viz/shared/renderer_helper.rb +46 -0
  91. data/lib/trace_viz/shared.rb +8 -0
  92. data/lib/trace_viz/trace_data/base.rb +16 -23
  93. data/lib/trace_viz/trace_data/node.rb +33 -0
  94. data/lib/trace_viz/trace_data/root_node.rb +20 -0
  95. data/lib/trace_viz/trace_data/summary_node.rb +49 -0
  96. data/lib/trace_viz/trace_data/trace_point/base.rb +22 -31
  97. data/lib/trace_viz/trace_data/trace_point/method_call.rb +22 -17
  98. data/lib/trace_viz/trace_data/trace_point/method_return.rb +21 -1
  99. data/lib/trace_viz/traits/depth_trackable.rb +13 -0
  100. data/lib/trace_viz/traits/identifiable.rb +25 -0
  101. data/lib/trace_viz/traits/time_trackable.rb +13 -0
  102. data/lib/trace_viz/traits.rb +10 -0
  103. data/lib/trace_viz/utils/colorize.rb +6 -6
  104. data/lib/trace_viz/utils/format_utils/key_value_formatter.rb +37 -0
  105. data/lib/trace_viz/utils/format_utils/value_truncator.rb +74 -0
  106. data/lib/trace_viz/utils/format_utils.rb +10 -53
  107. data/lib/trace_viz/utils/id_generator.rb +35 -0
  108. data/lib/trace_viz/version.rb +1 -1
  109. data/sig/adapters/base_adapter.rbs +11 -0
  110. data/sig/adapters/trace_point_adapter.rbs +13 -0
  111. data/sig/collectors/filters/registry.rbs +13 -0
  112. data/sig/collectors/trace_point_collector.rbs +17 -0
  113. data/sig/config/copier.rbs +15 -0
  114. data/sig/config/validator.rbs +18 -0
  115. data/sig/configuration.rbs +22 -0
  116. data/sig/context/base_context.rbs +9 -0
  117. data/sig/context/config_context.rbs +13 -0
  118. data/sig/context/manager.rbs +10 -0
  119. data/sig/context/map.rbs +13 -0
  120. data/sig/context.rbs +5 -0
  121. data/sig/core/tracer.rbs +7 -0
  122. data/sig/core.rbs +4 -0
  123. data/sig/defaults.rbs +17 -0
  124. data/sig/errors.rbs +13 -0
  125. data/sig/logger.rbs +33 -0
  126. data/sig/trace_viz.rbs +1 -2
  127. data/sig/utils/colorize.rbs +8 -0
  128. data/sig/utils/format_utils/key_value_formatter.rbs +16 -0
  129. data/sig/utils/format_utils/value_truncator.rbs +19 -0
  130. data/sig/utils/format_utils.rbs +8 -0
  131. data/sig/version.rbs +3 -0
  132. metadata +97 -18
  133. data/lib/trace_viz/collectors/depth_manager.rb +0 -37
  134. data/lib/trace_viz/collectors/evaluators/base_evaluator.rb +0 -23
  135. data/lib/trace_viz/exporters/formatters/base_formatter.rb +0 -12
  136. data/lib/trace_viz/exporters/formatters/method_call_formatter.rb +0 -21
  137. data/lib/trace_viz/exporters/formatters/method_return_formatter.rb +0 -22
  138. data/lib/trace_viz/exporters/transformers/base_transformer.rb +0 -25
  139. data/lib/trace_viz/exporters/transformers/text_transformer.rb +0 -28
  140. data/lib/trace_viz/loggers/trace_builder.rb +0 -30
  141. data/lib/trace_viz/loggers/trace_formatters/base_formatter.rb +0 -32
  142. data/lib/trace_viz/loggers/trace_formatters/method_call_formatter.rb +0 -21
  143. data/lib/trace_viz/loggers/trace_formatters/method_return_formatter.rb +0 -22
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/helpers"
4
+ require_relative "trace_logger"
5
+ require_relative "post_collection_logger"
6
+ require_relative "trace_stats_logger"
7
+
8
+ module TraceViz
9
+ module Loggers
10
+ class LoggingManager
11
+ include Helpers::ConfigHelper
12
+
13
+ def log_runtime_trace(trace_data)
14
+ return unless runtime_logging_enabled?
15
+
16
+ TraceLogger.log(trace_data)
17
+ end
18
+
19
+ def log_stats(collector)
20
+ return unless stats_logging_enabled?
21
+
22
+ TraceStatsLogger.log(collector)
23
+ end
24
+
25
+ def log_post_collection(collector)
26
+ return unless post_collection_logging_enabled?
27
+
28
+ PostCollectionLogger.log(collector)
29
+ end
30
+
31
+ private
32
+
33
+ def runtime_logging_enabled?
34
+ config.log[:enabled] && config.log[:runtime]
35
+ end
36
+
37
+ def post_collection_logging_enabled?
38
+ config.log[:enabled] && config.log[:post_collection]
39
+ end
40
+
41
+ def stats_logging_enabled?
42
+ config.log[:enabled] && config.log[:stats]
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/formatters/log/formatter_factory"
4
+ require "trace_viz/shared"
5
+ require_relative "base_logger"
6
+ require_relative "log_level_resolver"
7
+
8
+ module TraceViz
9
+ module Loggers
10
+ class PostCollectionLogger < BaseLogger
11
+ include Shared::RendererHelper
12
+
13
+ def initialize(collector)
14
+ super()
15
+
16
+ @collector = collector
17
+ @renderer = build_renderer(collector, Formatters::Log::FormatterFactory)
18
+ end
19
+
20
+ def log
21
+ process_lines(renderer.to_lines) { |line| log_line(line) }
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :collector, :renderer
27
+
28
+ def log_line(line)
29
+ log_message(resolve_log_level(line[:trace_data]), line[:line])
30
+
31
+ process_lines(line[:nested_lines]) { |nested| log_line(nested) }
32
+ end
33
+
34
+ def resolve_log_level(trace_data)
35
+ LogLevelResolver.resolve(trace_data)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,37 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "trace_builder"
3
+ require_relative "base_logger"
4
+ require_relative "log_level_resolver"
5
+ require "trace_viz/formatters/log/formatter_factory"
4
6
 
5
7
  module TraceViz
6
8
  module Loggers
7
- class TraceLogger
8
- LOG_LEVELS = {
9
- call: :start,
10
- return: :finish,
11
- }.freeze
12
-
13
- class << self
14
- def log(trace_data)
15
- new(trace_data).log
16
- end
17
- end
18
-
9
+ class TraceLogger < BaseLogger
19
10
  def initialize(trace_data)
20
- @logger = TraceViz.logger
11
+ super()
12
+
21
13
  @trace_data = trace_data
22
14
  end
23
15
 
24
16
  def log
25
- log_level = LOG_LEVELS[trace_data.event] || :info
26
- logger.send(log_level, formatted_message)
17
+ log_message(log_level, formatted_message)
27
18
  end
28
19
 
29
20
  private
30
21
 
31
- attr_reader :logger, :trace_data
22
+ attr_reader :trace_data
23
+
24
+ def log_level
25
+ LogLevelResolver.resolve(trace_data)
26
+ end
32
27
 
33
28
  def formatted_message
34
- Loggers::TraceBuilder.new(trace_data).build
29
+ fetch_formatter(trace_data).call(trace_data)
30
+ end
31
+
32
+ def fetch_formatter(trace_data)
33
+ Formatters::Log::FormatterFactory.fetch_formatter(trace_data.event)
35
34
  end
36
35
  end
37
36
  end
@@ -1,32 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "trace_builder"
3
+ require_relative "base_logger"
4
4
 
5
5
  module TraceViz
6
6
  module Loggers
7
- class TraceStatsLogger
8
- class << self
9
- def log(collector)
10
- new(collector).log
11
- end
12
- end
13
-
7
+ class TraceStatsLogger < BaseLogger
14
8
  def initialize(collector)
15
- @logger = TraceViz.logger
9
+ super()
10
+ @collector = collector
16
11
  @stats = collector.stats
17
12
  end
18
13
 
19
14
  def log
20
- logger.stats(formatted_stats)
15
+ logger.stats(format_stats)
21
16
  end
22
17
 
23
18
  private
24
19
 
25
- attr_reader :logger, :stats
20
+ attr_reader :stats
21
+
22
+ def format_stats
23
+ [
24
+ total_traces_info,
25
+ max_depth_info,
26
+ event_counts_info,
27
+ ].join(" | ")
28
+ end
29
+
30
+ def total_traces_info
31
+ "Total Traces: #{stats.total_traces}"
32
+ end
33
+
34
+ def max_depth_info
35
+ "Max Depth: #{stats.max_depth}"
36
+ end
37
+
38
+ def event_counts_info
39
+ "Event Counts: [#{formatted_event_counts}]"
40
+ end
26
41
 
27
- def formatted_stats
28
- event_counts = stats.event_counts.map { |event, count| "#{event.capitalize}: #{count}" }.join(", ")
29
- "Total Traces: #{stats.total_traces} | Max Depth: #{stats.max_depth} | Event Counts: [#{event_counts}]"
42
+ def formatted_event_counts
43
+ stats.event_counts.map { |event, count| "#{event.capitalize}: #{count}" }.join(", ")
30
44
  end
31
45
  end
32
46
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TraceViz
4
+ module Renderers
5
+ class BaseRenderer
6
+ def initialize(data, context:)
7
+ @data = data
8
+ @context = context
9
+ end
10
+
11
+ def render
12
+ to_lines.map { |line| line[:line] }.join("\n")
13
+ end
14
+
15
+ def to_lines
16
+ []
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :data, :context
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TraceViz
4
+ module Renderers
5
+ class RenderContext
6
+ attr_reader :formatter_factory, :group_keys
7
+
8
+ def initialize(formatter_factory:, group_keys: [])
9
+ @formatter_factory = formatter_factory
10
+ @group_keys = group_keys
11
+ end
12
+
13
+ def fetch_formatter(key)
14
+ formatter_factory.fetch_formatter(key)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "verbose_renderer"
4
+ require_relative "summary_renderer"
5
+
6
+ module TraceViz
7
+ module Renderers
8
+ class RendererFactory
9
+ RENDERERS = {
10
+ verbose: VerboseRenderer,
11
+ summary: SummaryRenderer,
12
+ }.freeze
13
+
14
+ class << self
15
+ def build(mode, collector, context:)
16
+ renderer_class = fetch_renderer_class(mode)
17
+ renderer_class.new(determine_input(mode, collector), context: context)
18
+ end
19
+
20
+ private
21
+
22
+ def fetch_renderer_class(mode)
23
+ RENDERERS.fetch(mode) do
24
+ raise ArgumentError, "Unknown mode: #{mode}. Valid modes are: #{RENDERERS.keys.join(", ")}"
25
+ end
26
+ end
27
+
28
+ def determine_input(mode, collector)
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
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/trace_data/summary_node"
4
+
5
+ module TraceViz
6
+ module Renderers
7
+ class NodeProcessor
8
+ def initialize(nodes, context)
9
+ @nodes = nodes
10
+ @context = context
11
+ end
12
+
13
+ def process
14
+ grouped_nodes.flat_map { |key, group| render_node_or_group(key, group) }
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :nodes, :context
20
+
21
+ def grouped_nodes
22
+ nodes.group_by { |node| node_key(node) }
23
+ end
24
+
25
+ def group_keys
26
+ context.group_keys
27
+ end
28
+
29
+ def node_key(node)
30
+ group_keys.map { |key| fetch_node_attribute(node, key) }
31
+ end
32
+
33
+ def fetch_node_attribute(node, key)
34
+ node.respond_to?(key) ? node.public_send(key) : nil
35
+ end
36
+
37
+ def render_node_or_group(key, group)
38
+ if group.size > 1
39
+ render_group(key, group)
40
+ else
41
+ render_single_node(group.first)
42
+ end
43
+ end
44
+
45
+ def render_group(key, group)
46
+ representative_node = group.first
47
+ nested_lines = process_nested_nodes(representative_node)
48
+
49
+ [{
50
+ line: format_group_line(group),
51
+ trace_data: representative_node,
52
+ nested_lines: nested_lines,
53
+ }]
54
+ end
55
+
56
+ def render_single_node(node)
57
+ current_line = {
58
+ line: format_node(node),
59
+ trace_data: node,
60
+ nested_lines: process_nested_nodes(node),
61
+ }
62
+
63
+ [current_line]
64
+ end
65
+
66
+ def process_nested_nodes(node)
67
+ return [] unless node.respond_to?(:children) && node.children.any?
68
+
69
+ NodeProcessor.new(node.children, context).process
70
+ end
71
+
72
+ def format_node(node)
73
+ context.fetch_formatter(node.event).call(node)
74
+ end
75
+
76
+ def format_group_line(group)
77
+ node = TraceData::SummaryNode.new(group: group)
78
+ context.fetch_formatter(:summary_group).call(node)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_renderer"
4
+ require_relative "summary/node_processor"
5
+
6
+ module TraceViz
7
+ module Renderers
8
+ class SummaryRenderer < BaseRenderer
9
+ def to_lines
10
+ return [] unless valid_children?(data)
11
+
12
+ NodeProcessor.new(data.children, context).process
13
+ end
14
+
15
+ private
16
+
17
+ def valid_children?(node)
18
+ node.respond_to?(:children) && node.children.any?
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_renderer"
4
+ require "trace_viz/formatters/log/formatter_factory"
5
+
6
+ module TraceViz
7
+ module Renderers
8
+ class VerboseRenderer < BaseRenderer
9
+ def to_lines
10
+ traverse_data(data)
11
+ end
12
+
13
+ private
14
+
15
+ def traverse_data(data)
16
+ data.map do |trace_data|
17
+ {
18
+ line: format_for(trace_data),
19
+ trace_data: trace_data,
20
+ }
21
+ end
22
+ end
23
+
24
+ def format_for(trace_data)
25
+ context.fetch_formatter(trace_data.event).call(trace_data)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
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
+ module TraceViz
9
+ module Shared
10
+ 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
+ def process_lines(lines, &block)
26
+ return [] unless lines.is_a?(Array)
27
+
28
+ lines.map do |line|
29
+ validate_line_structure!(line)
30
+ block.call(line)
31
+ end.compact
32
+ end
33
+
34
+ private
35
+
36
+ def fetch_config(collector, key)
37
+ collector.config.general[key]
38
+ end
39
+
40
+ def validate_line_structure!(line)
41
+ raise ArgumentError, "Line must be a Hash" unless line.is_a?(Hash)
42
+ raise KeyError, "Line must include a :line key" unless line.key?(:line)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir[File.join(__dir__, "shared/**/*.rb")].each { |file| require_relative file }
4
+
5
+ module TraceViz
6
+ module Shared
7
+ end
8
+ end
@@ -1,28 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "trace_viz/context"
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
- attr_reader :config,
9
- :timestamp
10
- attr_accessor :depth
9
+ include Helpers::ConfigHelper
10
+ include Traits::DepthTrackable
11
+ include Traits::TimeTrackable
11
12
 
12
13
  def initialize
13
- @config = Context.for(:config).configuration
14
-
15
- @depth = 0
14
+ assign_depth(0)
16
15
  record_timestamp
17
16
  end
18
17
 
19
- # Unique ID for each individual event
20
- def id
18
+ def event
21
19
  raise NotImplementedError
22
20
  end
23
21
 
24
- # Shared ID betweem events for the same method call
25
- def action_id
22
+ def klass
26
23
  raise NotImplementedError
27
24
  end
28
25
 
@@ -30,10 +27,6 @@ module TraceViz
30
27
  raise NotImplementedError
31
28
  end
32
29
 
33
- def event
34
- raise NotImplementedError
35
- end
36
-
37
30
  def path
38
31
  raise NotImplementedError
39
32
  end
@@ -42,14 +35,14 @@ module TraceViz
42
35
  raise NotImplementedError
43
36
  end
44
37
 
45
- def klass
46
- raise NotImplementedError
47
- end
48
-
49
- private
50
-
51
- def record_timestamp
52
- @timestamp = Time.now
38
+ def to_h
39
+ {
40
+ event: event,
41
+ klass: klass,
42
+ action: action,
43
+ path: path,
44
+ line_number: line_number,
45
+ }
53
46
  end
54
47
  end
55
48
  end
@@ -0,0 +1,33 @@
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(child)
19
+ child.parent = self
20
+ @children << child
21
+ end
22
+
23
+ def to_h
24
+ super.merge(
25
+ {
26
+ parent: parent&.to_s,
27
+ children: children.map(&:to_h),
28
+ },
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,20 @@
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 parent=(_parent)
16
+ raise NoMethodError, "RootNode cannot have a parent"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,49 @@
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 average_duration
31
+ return 0 if count.zero?
32
+
33
+ total_duration / count
34
+ end
35
+
36
+ def total_duration
37
+ children.map(&:duration).sum
38
+ end
39
+
40
+ private
41
+
42
+ def add_children(nodes)
43
+ nodes.each do |node|
44
+ add_child(node)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end