trace_viz 0.0.1 → 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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +34 -0
  3. data/README.md +134 -39
  4. data/Steepfile +34 -0
  5. data/examples/eu_central_bank.rb +69 -0
  6. data/examples/example.cast +189 -0
  7. data/examples/example.rb +94 -23
  8. data/lib/trace_viz/adapters/base_adapter.rb +23 -2
  9. data/lib/trace_viz/adapters/trace_point_adapter.rb +10 -11
  10. data/lib/trace_viz/collectors/base_collector.rb +90 -0
  11. data/lib/trace_viz/collectors/filters/base_class_filter.rb +29 -0
  12. data/lib/trace_viz/collectors/filters/base_exclude_filter.rb +16 -0
  13. data/lib/trace_viz/collectors/filters/base_filter.rb +17 -0
  14. data/lib/trace_viz/collectors/filters/base_include_filter.rb +16 -0
  15. data/lib/trace_viz/collectors/filters/exclude_classes_filter.rb +15 -0
  16. data/lib/trace_viz/collectors/filters/exclude_default_classes_filter.rb +34 -0
  17. data/lib/trace_viz/collectors/filters/exclude_gems_filter.rb +30 -0
  18. data/lib/trace_viz/collectors/filters/exclude_internal_call_filter.rb +31 -0
  19. data/lib/trace_viz/collectors/filters/exclude_rails_framework_filter.rb +38 -0
  20. data/lib/trace_viz/collectors/filters/include_classes_filter.rb +15 -0
  21. data/lib/trace_viz/collectors/filters/include_gems_filter.rb +54 -0
  22. data/lib/trace_viz/collectors/filters/registry.rb +59 -0
  23. data/lib/trace_viz/collectors/hierarchy_linker.rb +30 -0
  24. data/lib/trace_viz/collectors/matchers/base_matcher.rb +13 -0
  25. data/lib/trace_viz/collectors/matchers/trace_point_action_matcher.rb +38 -0
  26. data/lib/trace_viz/collectors/matchers/within_depth_matcher.rb +26 -0
  27. data/lib/trace_viz/collectors/steps/assign_depth_for_call_step.rb +30 -0
  28. data/lib/trace_viz/collectors/steps/assign_depth_for_return_step.rb +39 -0
  29. data/lib/trace_viz/collectors/steps/base_step.rb +27 -0
  30. data/lib/trace_viz/collectors/steps/build_hierarchy_step.rb +32 -0
  31. data/lib/trace_viz/collectors/steps/hidden_step.rb +25 -0
  32. data/lib/trace_viz/collectors/steps/linking_step.rb +36 -0
  33. data/lib/trace_viz/collectors/steps/validation_step.rb +33 -0
  34. data/lib/trace_viz/collectors/steps.rb +10 -0
  35. data/lib/trace_viz/collectors/trace_pipeline.rb +26 -0
  36. data/lib/trace_viz/collectors/trace_pipeline_builder.rb +29 -0
  37. data/lib/trace_viz/collectors/trace_point_collector.rb +41 -0
  38. data/lib/trace_viz/collectors/trace_stats.rb +21 -0
  39. data/lib/trace_viz/config/copier.rb +38 -0
  40. data/lib/trace_viz/config/validator.rb +75 -0
  41. data/lib/trace_viz/configuration.rb +36 -30
  42. data/lib/trace_viz/context/config_context.rb +1 -1
  43. data/lib/trace_viz/context/manager.rb +17 -21
  44. data/lib/trace_viz/context/map.rb +29 -0
  45. data/lib/trace_viz/context/registry.rb +37 -0
  46. data/lib/trace_viz/context/tracking/active_calls.rb +37 -0
  47. data/lib/trace_viz/context/tracking_context.rb +11 -2
  48. data/lib/trace_viz/context.rb +2 -2
  49. data/lib/trace_viz/core/tracer.rb +3 -0
  50. data/lib/trace_viz/defaults/actions.rb +84 -0
  51. data/lib/trace_viz/defaults/colors.rb +61 -0
  52. data/lib/trace_viz/defaults/config.rb +89 -0
  53. data/lib/trace_viz/defaults/themes.rb +66 -0
  54. data/lib/trace_viz/defaults.rb +20 -0
  55. data/lib/trace_viz/exporters/base_exporter.rb +81 -0
  56. data/lib/trace_viz/exporters/export_manager.rb +33 -0
  57. data/lib/trace_viz/exporters/registry.rb +25 -0
  58. data/lib/trace_viz/exporters/text_exporter.rb +37 -0
  59. data/lib/trace_viz/formatters/base_formatter.rb +15 -0
  60. data/lib/trace_viz/formatters/export/base_formatter.rb +12 -0
  61. data/lib/trace_viz/formatters/export/formatter_factory.rb +27 -0
  62. data/lib/trace_viz/formatters/export/method_call_formatter.rb +21 -0
  63. data/lib/trace_viz/formatters/export/method_return_formatter.rb +22 -0
  64. data/lib/trace_viz/formatters/export/summary_group_formatter.rb +35 -0
  65. data/lib/trace_viz/formatters/helpers/depth_helper.rb +15 -0
  66. data/lib/trace_viz/formatters/helpers/indent_helper.rb +15 -0
  67. data/lib/trace_viz/formatters/helpers/log/color_helper.rb +23 -0
  68. data/lib/trace_viz/formatters/helpers/log/depth_helper.rb +22 -0
  69. data/lib/trace_viz/formatters/helpers/log/method_name_helper.rb +29 -0
  70. data/lib/trace_viz/formatters/helpers/log/params_helper.rb +51 -0
  71. data/lib/trace_viz/formatters/helpers/log/result_helper.rb +27 -0
  72. data/lib/trace_viz/formatters/helpers/log/summary/params_helper.rb +53 -0
  73. data/lib/trace_viz/formatters/helpers/method_details_helper.rb +15 -0
  74. data/lib/trace_viz/formatters/helpers/params_helper.rb +43 -0
  75. data/lib/trace_viz/formatters/helpers/result_helper.rb +21 -0
  76. data/lib/trace_viz/formatters/helpers/source_helper.rb +22 -0
  77. data/lib/trace_viz/formatters/helpers/summary/params_helper.rb +41 -0
  78. data/lib/trace_viz/formatters/helpers/summary/source_helper.rb +24 -0
  79. data/lib/trace_viz/formatters/helpers/time_helper.rb +15 -0
  80. data/lib/trace_viz/formatters/helpers.rb +10 -0
  81. data/lib/trace_viz/formatters/log/base_formatter.rb +13 -0
  82. data/lib/trace_viz/formatters/log/formatter_factory.rb +27 -0
  83. data/lib/trace_viz/formatters/log/method_call_formatter.rb +34 -0
  84. data/lib/trace_viz/formatters/log/method_return_formatter.rb +24 -0
  85. data/lib/trace_viz/formatters/log/summary_group_formatter.rb +40 -0
  86. data/lib/trace_viz/formatters/log/verbose_formatter.rb +14 -0
  87. data/lib/trace_viz/formatters/trace_data_formatter.rb +24 -0
  88. data/lib/trace_viz/helpers/config_helper.rb +13 -0
  89. data/lib/trace_viz/helpers/trace_point/param_helper.rb +98 -0
  90. data/lib/trace_viz/helpers/tracking_helper.rb +26 -0
  91. data/lib/trace_viz/helpers.rb +9 -0
  92. data/lib/trace_viz/logger.rb +28 -49
  93. data/lib/trace_viz/loggers/base_logger.rb +29 -0
  94. data/lib/trace_viz/loggers/log_level_resolver.rb +18 -0
  95. data/lib/trace_viz/loggers/logging_manager.rb +46 -0
  96. data/lib/trace_viz/loggers/post_collection_logger.rb +39 -0
  97. data/lib/trace_viz/loggers/trace_logger.rb +37 -0
  98. data/lib/trace_viz/loggers/trace_stats_logger.rb +47 -0
  99. data/lib/trace_viz/renderers/base_renderer.rb +24 -0
  100. data/lib/trace_viz/renderers/render_context.rb +18 -0
  101. data/lib/trace_viz/renderers/renderer_factory.rb +41 -0
  102. data/lib/trace_viz/renderers/summary/node_processor.rb +82 -0
  103. data/lib/trace_viz/renderers/summary_renderer.rb +22 -0
  104. data/lib/trace_viz/renderers/verbose_renderer.rb +29 -0
  105. data/lib/trace_viz/shared/renderer_helper.rb +46 -0
  106. data/lib/trace_viz/shared.rb +8 -0
  107. data/lib/trace_viz/trace_data/base.rb +49 -0
  108. data/lib/trace_viz/trace_data/node.rb +33 -0
  109. data/lib/trace_viz/trace_data/root_node.rb +20 -0
  110. data/lib/trace_viz/trace_data/summary_node.rb +49 -0
  111. data/lib/trace_viz/trace_data/trace_point/base.rb +59 -0
  112. data/lib/trace_viz/trace_data/trace_point/method_call.rb +47 -0
  113. data/lib/trace_viz/trace_data/trace_point/method_return.rb +45 -0
  114. data/lib/trace_viz/trace_data/trace_point_builder.rb +23 -0
  115. data/lib/trace_viz/traits/depth_trackable.rb +13 -0
  116. data/lib/trace_viz/traits/identifiable.rb +25 -0
  117. data/lib/trace_viz/traits/time_trackable.rb +13 -0
  118. data/lib/trace_viz/traits.rb +10 -0
  119. data/lib/trace_viz/utils/colorize.rb +12 -23
  120. data/lib/trace_viz/utils/format_utils/key_value_formatter.rb +37 -0
  121. data/lib/trace_viz/utils/format_utils/value_truncator.rb +74 -0
  122. data/lib/trace_viz/utils/format_utils.rb +24 -0
  123. data/lib/trace_viz/utils/id_generator.rb +35 -0
  124. data/lib/trace_viz/version.rb +1 -1
  125. data/sig/adapters/base_adapter.rbs +11 -0
  126. data/sig/adapters/trace_point_adapter.rbs +13 -0
  127. data/sig/collectors/filters/registry.rbs +13 -0
  128. data/sig/collectors/trace_point_collector.rbs +17 -0
  129. data/sig/config/copier.rbs +15 -0
  130. data/sig/config/validator.rbs +18 -0
  131. data/sig/configuration.rbs +22 -0
  132. data/sig/context/base_context.rbs +9 -0
  133. data/sig/context/config_context.rbs +13 -0
  134. data/sig/context/manager.rbs +10 -0
  135. data/sig/context/map.rbs +13 -0
  136. data/sig/context.rbs +5 -0
  137. data/sig/core/tracer.rbs +7 -0
  138. data/sig/core.rbs +4 -0
  139. data/sig/defaults.rbs +17 -0
  140. data/sig/errors.rbs +13 -0
  141. data/sig/logger.rbs +33 -0
  142. data/sig/trace_viz.rbs +1 -2
  143. data/sig/utils/colorize.rbs +8 -0
  144. data/sig/utils/format_utils/key_value_formatter.rbs +16 -0
  145. data/sig/utils/format_utils/value_truncator.rbs +19 -0
  146. data/sig/utils/format_utils.rbs +8 -0
  147. data/sig/version.rbs +3 -0
  148. metadata +140 -16
  149. data/lib/trace_viz/adapters/trace_point/depth_manager.rb +0 -34
  150. data/lib/trace_viz/adapters/trace_point/event_handler.rb +0 -36
  151. data/lib/trace_viz/adapters/trace_point/trace_data.rb +0 -89
  152. data/lib/trace_viz/adapters/trace_point/trace_formatter.rb +0 -95
  153. data/lib/trace_viz/adapters/trace_point/trace_logger.rb +0 -44
  154. data/lib/trace_viz/context/manager/context_map.rb +0 -31
  155. data/lib/trace_viz/context/manager/context_operations.rb +0 -60
  156. data/lib/trace_viz/context/manager/context_registry.rb +0 -20
  157. data/lib/trace_viz/context/manager/context_validation.rb +0 -34
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_filter"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class BaseClassFilter < BaseFilter
9
+ def initialize(classes:)
10
+ super()
11
+ @classes_and_modules = classes.map(&:to_s).freeze
12
+ end
13
+
14
+ protected
15
+
16
+ attr_reader :classes_and_modules
17
+
18
+ def normalize_class_name(klass)
19
+ # Normalize class/module names to handle dynamic/nested representations
20
+ klass.to_s.gsub(/^#<Class:/, "").gsub(/>$/, "").strip
21
+ end
22
+
23
+ def matches_hierarchy?(klass_name, target_name)
24
+ klass_name == target_name || klass_name.start_with?("#{target_name}::")
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_class_filter"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class BaseExcludeFilter < BaseClassFilter
9
+ def apply?(trace_data)
10
+ klass_name = normalize_class_name(trace_data.klass)
11
+ !classes_and_modules.any? { |excluded| matches_hierarchy?(klass_name, excluded) }
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/helpers"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class BaseFilter
9
+ include Helpers::ConfigHelper
10
+
11
+ def apply?(trace_data)
12
+ raise NotImplementedError
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_class_filter"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class BaseIncludeFilter < BaseClassFilter
9
+ def apply?(trace_data)
10
+ klass_name = normalize_class_name(trace_data.klass)
11
+ classes_and_modules.any? { |allowed| matches_hierarchy?(klass_name, allowed) }
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_exclude_filter"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class ExcludeClassesFilter < BaseExcludeFilter
9
+ def initialize(classes:)
10
+ super(classes: classes)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_exclude_filter"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class ExcludeDefaultClassesFilter < BaseExcludeFilter
9
+ DEFAULT_CLASSES_AND_MODULES = [
10
+ "Object",
11
+ "String",
12
+ "Array",
13
+ "Hash",
14
+ "Numeric",
15
+ "Integer",
16
+ "Float",
17
+ "Symbol",
18
+ "Kernel",
19
+ "Module",
20
+ "Class",
21
+ "Range",
22
+ "Regexp",
23
+ "BigDecimal",
24
+ "Set",
25
+ "Gem",
26
+ ].freeze
27
+
28
+ def initialize
29
+ super(classes: DEFAULT_CLASSES_AND_MODULES)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_filter"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class ExcludeGemsFilter < BaseFilter
9
+ def initialize(**options)
10
+ super()
11
+ @excluded_gems = options[:gems].map do |gem_name|
12
+ ::Gem.loaded_specs[gem_name]&.full_gem_path
13
+ end.compact.freeze
14
+ end
15
+
16
+ def apply?(trace_data)
17
+ !excluded_gem?(trace_data.path)
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :excluded_gems
23
+
24
+ def excluded_gem?(path)
25
+ excluded_gems.any? { |gem_path| path.start_with?(gem_path) }
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_filter"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class ExcludeInternalCallFilter < BaseFilter
9
+ INTERNAL_PATH_IDENTIFIER = "<internal:"
10
+ INTERNAL_CLASS_PREFIX = "TracePoint"
11
+
12
+ def apply?(trace_data)
13
+ [
14
+ internal_path?(trace_data.path),
15
+ internal_class?(trace_data.klass),
16
+ ].none?
17
+ end
18
+
19
+ private
20
+
21
+ def internal_path?(path)
22
+ path.include?(INTERNAL_PATH_IDENTIFIER)
23
+ end
24
+
25
+ def internal_class?(klass)
26
+ klass.to_s.start_with?(INTERNAL_CLASS_PREFIX)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_filter"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class ExcludeRailsFrameworkFilter < BaseFilter
9
+ RAILS_MODULES = [
10
+ "ActiveSupport",
11
+ "ActiveModel",
12
+ "ActiveRecord",
13
+ "ActionPack",
14
+ "ActionController",
15
+ "ActionView",
16
+ "ActionMailer",
17
+ "ActiveJob",
18
+ "ActionCable",
19
+ "ActionDispatch",
20
+ "ActiveStorage",
21
+ "ActionMailbox",
22
+ "ActionText",
23
+ "Rails",
24
+ ].freeze
25
+
26
+ def apply?(trace_data)
27
+ !rails_related?(trace_data.klass)
28
+ end
29
+
30
+ private
31
+
32
+ def rails_related?(klass)
33
+ RAILS_MODULES.any? { |mod| klass.to_s.start_with?(mod) }
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_include_filter"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class IncludeClassesFilter < BaseIncludeFilter
9
+ def initialize(classes:)
10
+ super(classes: classes)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_filter"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Filters
8
+ class IncludeGemsFilter < BaseFilter
9
+ DEFAULT_OPTIONS = {
10
+ app_running: true,
11
+ gems: [],
12
+ }.freeze
13
+
14
+ def initialize(**options)
15
+ super()
16
+ @include_app = options.fetch(:app_running, DEFAULT_OPTIONS[:app_running])
17
+ @app_path = options[:app_path] || detect_app_path
18
+ @app_path.freeze
19
+ @included_gems = options.fetch(:gems, DEFAULT_OPTIONS[:gems]).map do |gem_name|
20
+ ::Gem.loaded_specs[gem_name]&.full_gem_path
21
+ end.compact.freeze
22
+ end
23
+
24
+ def apply?(trace_data)
25
+ app_path_included?(trace_data.path) || included_gem?(trace_data.path)
26
+ end
27
+
28
+ private
29
+
30
+ attr_reader :include_app, :app_path, :included_gems
31
+
32
+ def included_gem?(path)
33
+ included_gems.any? { |gem_path| path.start_with?(gem_path) }
34
+ end
35
+
36
+ def app_path_included?(path)
37
+ include_app && path.start_with?(app_path)
38
+ end
39
+
40
+ def detect_app_path
41
+ if defined?(Bundler)
42
+ Bundler.root.to_s
43
+ else
44
+ # Use the directory of the currently running script
45
+ File.expand_path("..", $PROGRAM_NAME)
46
+ end
47
+ rescue StandardError
48
+ # Fallback to current working directory
49
+ Dir.pwd
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "include_classes_filter"
4
+ require_relative "include_gems_filter"
5
+ require_relative "exclude_internal_call_filter"
6
+ require_relative "exclude_gems_filter"
7
+ require_relative "exclude_rails_framework_filter"
8
+ require_relative "exclude_default_classes_filter"
9
+ require_relative "exclude_classes_filter"
10
+
11
+ module TraceViz
12
+ module Collectors
13
+ module Filters
14
+ class Registry
15
+ FILTERS = {
16
+ include_classes: IncludeClassesFilter,
17
+ include_gems: IncludeGemsFilter,
18
+ exclude_internal_call: ExcludeInternalCallFilter,
19
+ exclude_gems: ExcludeGemsFilter,
20
+ exclude_rails_framework: ExcludeRailsFrameworkFilter,
21
+ exclude_default_classes: ExcludeDefaultClassesFilter,
22
+ exclude_classes: ExcludeClassesFilter,
23
+ }.freeze
24
+
25
+ class << self
26
+ def build(filters)
27
+ filters.each_with_object([]) do |filter, result|
28
+ case filter
29
+ when Symbol
30
+ # Handle simple filters
31
+ # (e.g., :depth, :exclude_internal_call)
32
+ klass = fetch_filter_class(filter)
33
+ result << klass.new
34
+ when Hash
35
+ # Handle complex filters with options
36
+ # (e.g., { include_classes: { classes: [Example] } })
37
+ filter.each do |filter_key, options|
38
+ klass = fetch_filter_class(filter_key)
39
+ result << klass.new(**options)
40
+ end
41
+ else
42
+ raise ArgumentError, "Invalid filter format: #{filter.inspect}"
43
+ end
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def fetch_filter_class(filter_key)
50
+ FILTERS.fetch(filter_key) do
51
+ available_keys = FILTERS.keys.join(", ")
52
+ raise ArgumentError, "Unknown filter: #{filter_key}. Available filters are: #{available_keys}"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/trace_data/root_node"
4
+
5
+ module TraceViz
6
+ module TraceData
7
+ class HierarchyLinker
8
+ attr_reader :root
9
+
10
+ def initialize
11
+ @root = RootNode.new
12
+ end
13
+
14
+ def link(trace_data)
15
+ return unless valid?(trace_data)
16
+
17
+ root.add_child(trace_data)
18
+ end
19
+
20
+ private
21
+
22
+ def valid?(trace_data)
23
+ [
24
+ trace_data.event == :call,
25
+ trace_data.parent.nil?,
26
+ ].all?
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TraceViz
4
+ module Collectors
5
+ module Matchers
6
+ class BaseMatcher
7
+ def matches?
8
+ false
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/utils/id_generator"
4
+ require "trace_viz/helpers/tracking_helper"
5
+ require_relative "base_matcher"
6
+
7
+ module TraceViz
8
+ module Collectors
9
+ module Matchers
10
+ class TracePointActionMatcher < BaseMatcher
11
+ include Helpers::TrackingHelper
12
+
13
+ def matches?(trace_point)
14
+ current_action_id == build_action_id(trace_point)
15
+ end
16
+
17
+ private
18
+
19
+ def current_action
20
+ tracker.active_calls.current
21
+ end
22
+
23
+ def current_action_id
24
+ current_action&.action_id
25
+ end
26
+
27
+ def build_action_id(trace_point)
28
+ Utils::IDGenerator.generate_action_id(
29
+ memory_id: trace_point.self.object_id,
30
+ action: trace_point.callee_id,
31
+ )
32
+ end
33
+
34
+ private :tracker, :active_call_stack, :current_call, :current_depth
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/helpers/config_helper"
4
+ require_relative "base_matcher"
5
+
6
+ module TraceViz
7
+ module Collectors
8
+ module Matchers
9
+ class WithinDepthMatcher
10
+ include Helpers::ConfigHelper
11
+
12
+ def matches?(depth)
13
+ depth <= max_depth
14
+ end
15
+
16
+ private
17
+
18
+ def max_depth
19
+ config.general[:max_display_depth]
20
+ end
21
+
22
+ private :config
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_step"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Steps
8
+ class AssignDepthForCallStep < BaseStep
9
+ def call(trace_data)
10
+ assign_depth(trace_data) if valid?(trace_data)
11
+ trace_data
12
+ rescue StandardError => e
13
+ logger.error("Depth assignment failed for trace_data ID: #{trace_data.id} - #{e.message}")
14
+ nil
15
+ end
16
+
17
+ private
18
+
19
+ def valid?(trace_data)
20
+ trace_data.event == :call
21
+ end
22
+
23
+ def assign_depth(trace_data)
24
+ trace_data.assign_depth(current_depth)
25
+ active_call_stack.push(trace_data)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_step"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Steps
8
+ class AssignDepthForReturnStep < BaseStep
9
+ def call(trace_data)
10
+ assign_depth(trace_data) if valid?(trace_data)
11
+ trace_data
12
+ rescue StandardError => e
13
+ logger.error("Depth assignment failed for trace_data ID: #{trace_data.id} - #{e.message}")
14
+ nil
15
+ end
16
+
17
+ private
18
+
19
+ def valid?(trace_data)
20
+ trace_data.event == :return
21
+ end
22
+
23
+ def call_matches?(trace_data)
24
+ trace_data.action_id == current_call&.action_id
25
+ end
26
+
27
+ def assign_depth(trace_data)
28
+ if call_matches?(trace_data)
29
+ active_call_stack.pop
30
+ else
31
+ logger.warn("Unmatched return event for trace_data ID #{trace_data.id}")
32
+ end
33
+
34
+ trace_data.assign_depth(current_depth)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/helpers/tracking_helper"
4
+ require "trace_viz/helpers/config_helper"
5
+
6
+ module TraceViz
7
+ module Collectors
8
+ module Steps
9
+ class BaseStep
10
+ include Helpers::TrackingHelper
11
+ include Helpers::ConfigHelper
12
+
13
+ def initialize
14
+ @logger = TraceViz.logger
15
+ end
16
+
17
+ def call
18
+ raise NotImplementedError
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :logger
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_step"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Steps
8
+ class BuildHierarchyStep < BaseStep
9
+ def call(trace_data)
10
+ link_to_parent(trace_data) if valid?(trace_data)
11
+
12
+ trace_data
13
+ rescue StandardError => e
14
+ logger.error("Hierarchy building failed for trace_data ID: #{trace_data.id} - #{e.message}")
15
+ nil
16
+ end
17
+
18
+ private
19
+
20
+ def valid?(trace_data)
21
+ trace_data.event == :call
22
+ end
23
+
24
+ def link_to_parent(trace_data)
25
+ return unless current_call
26
+
27
+ current_call.add_child(trace_data)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_step"
4
+
5
+ module TraceViz
6
+ module Collectors
7
+ module Steps
8
+ class HiddenStep < BaseStep
9
+ def call(trace_data)
10
+ trace_data unless pass?(trace_data)
11
+ end
12
+
13
+ private
14
+
15
+ def pass?(trace_data)
16
+ !allowed_events.include?(trace_data.event)
17
+ end
18
+
19
+ def allowed_events
20
+ config.execution[:show_trace_events]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "trace_viz/context"
4
+ require_relative "base_step"
5
+
6
+ module TraceViz
7
+ module Collectors
8
+ module Steps
9
+ class LinkingStep < BaseStep
10
+ def call(trace_data)
11
+ valid?(trace_data) ? linking_trace(trace_data) : trace_data
12
+ rescue StandardError => e
13
+ logger.error("Linking failed for trace_data ID: #{trace_data.id} - #{e.message}")
14
+ nil
15
+ end
16
+
17
+ private
18
+
19
+ def valid?(trace_data)
20
+ return false unless current_call
21
+
22
+ [
23
+ trace_data.event == :return,
24
+ current_call.event == :call,
25
+ trace_data.action_id == current_call.action_id,
26
+ ].all?
27
+ end
28
+
29
+ def linking_trace(trace_data)
30
+ trace_data.link(current_call)
31
+ trace_data
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end