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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +34 -0
- data/README.md +134 -39
- data/Steepfile +34 -0
- data/examples/eu_central_bank.rb +69 -0
- data/examples/example.cast +189 -0
- data/examples/example.rb +94 -23
- data/lib/trace_viz/adapters/base_adapter.rb +23 -2
- data/lib/trace_viz/adapters/trace_point_adapter.rb +10 -11
- data/lib/trace_viz/collectors/base_collector.rb +90 -0
- data/lib/trace_viz/collectors/filters/base_class_filter.rb +29 -0
- data/lib/trace_viz/collectors/filters/base_exclude_filter.rb +16 -0
- data/lib/trace_viz/collectors/filters/base_filter.rb +17 -0
- data/lib/trace_viz/collectors/filters/base_include_filter.rb +16 -0
- data/lib/trace_viz/collectors/filters/exclude_classes_filter.rb +15 -0
- data/lib/trace_viz/collectors/filters/exclude_default_classes_filter.rb +34 -0
- data/lib/trace_viz/collectors/filters/exclude_gems_filter.rb +30 -0
- data/lib/trace_viz/collectors/filters/exclude_internal_call_filter.rb +31 -0
- data/lib/trace_viz/collectors/filters/exclude_rails_framework_filter.rb +38 -0
- data/lib/trace_viz/collectors/filters/include_classes_filter.rb +15 -0
- data/lib/trace_viz/collectors/filters/include_gems_filter.rb +54 -0
- data/lib/trace_viz/collectors/filters/registry.rb +59 -0
- 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 +38 -0
- data/lib/trace_viz/collectors/matchers/within_depth_matcher.rb +26 -0
- 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/steps/hidden_step.rb +25 -0
- data/lib/trace_viz/collectors/steps/linking_step.rb +36 -0
- data/lib/trace_viz/collectors/steps/validation_step.rb +33 -0
- 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 +41 -0
- data/lib/trace_viz/collectors/trace_stats.rb +21 -0
- data/lib/trace_viz/config/copier.rb +38 -0
- data/lib/trace_viz/config/validator.rb +75 -0
- data/lib/trace_viz/configuration.rb +36 -30
- data/lib/trace_viz/context/config_context.rb +1 -1
- data/lib/trace_viz/context/manager.rb +17 -21
- data/lib/trace_viz/context/map.rb +29 -0
- data/lib/trace_viz/context/registry.rb +37 -0
- data/lib/trace_viz/context/tracking/active_calls.rb +37 -0
- data/lib/trace_viz/context/tracking_context.rb +11 -2
- data/lib/trace_viz/context.rb +2 -2
- data/lib/trace_viz/core/tracer.rb +3 -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 +89 -0
- data/lib/trace_viz/defaults/themes.rb +66 -0
- data/lib/trace_viz/defaults.rb +20 -0
- data/lib/trace_viz/exporters/base_exporter.rb +81 -0
- data/lib/trace_viz/exporters/export_manager.rb +33 -0
- data/lib/trace_viz/exporters/registry.rb +25 -0
- data/lib/trace_viz/exporters/text_exporter.rb +37 -0
- data/lib/trace_viz/formatters/base_formatter.rb +15 -0
- data/lib/trace_viz/formatters/export/base_formatter.rb +12 -0
- data/lib/trace_viz/formatters/export/formatter_factory.rb +27 -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 +15 -0
- data/lib/trace_viz/formatters/helpers/indent_helper.rb +15 -0
- 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 +51 -0
- data/lib/trace_viz/formatters/helpers/log/result_helper.rb +27 -0
- data/lib/trace_viz/formatters/helpers/log/summary/params_helper.rb +53 -0
- data/lib/trace_viz/formatters/helpers/method_details_helper.rb +15 -0
- data/lib/trace_viz/formatters/helpers/params_helper.rb +43 -0
- data/lib/trace_viz/formatters/helpers/result_helper.rb +21 -0
- data/lib/trace_viz/formatters/helpers/source_helper.rb +22 -0
- data/lib/trace_viz/formatters/helpers/summary/params_helper.rb +41 -0
- data/lib/trace_viz/formatters/helpers/summary/source_helper.rb +24 -0
- data/lib/trace_viz/formatters/helpers/time_helper.rb +15 -0
- 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 +27 -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 +13 -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 +28 -49
- 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 +39 -0
- data/lib/trace_viz/loggers/trace_logger.rb +37 -0
- data/lib/trace_viz/loggers/trace_stats_logger.rb +47 -0
- data/lib/trace_viz/renderers/base_renderer.rb +24 -0
- data/lib/trace_viz/renderers/render_context.rb +18 -0
- data/lib/trace_viz/renderers/renderer_factory.rb +41 -0
- data/lib/trace_viz/renderers/summary/node_processor.rb +82 -0
- data/lib/trace_viz/renderers/summary_renderer.rb +22 -0
- data/lib/trace_viz/renderers/verbose_renderer.rb +29 -0
- data/lib/trace_viz/shared/renderer_helper.rb +46 -0
- data/lib/trace_viz/shared.rb +8 -0
- data/lib/trace_viz/trace_data/base.rb +49 -0
- data/lib/trace_viz/trace_data/node.rb +33 -0
- data/lib/trace_viz/trace_data/root_node.rb +20 -0
- data/lib/trace_viz/trace_data/summary_node.rb +49 -0
- data/lib/trace_viz/trace_data/trace_point/base.rb +59 -0
- data/lib/trace_viz/trace_data/trace_point/method_call.rb +47 -0
- data/lib/trace_viz/trace_data/trace_point/method_return.rb +45 -0
- data/lib/trace_viz/trace_data/trace_point_builder.rb +23 -0
- 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/utils/colorize.rb +12 -23
- data/lib/trace_viz/utils/format_utils/key_value_formatter.rb +37 -0
- data/lib/trace_viz/utils/format_utils/value_truncator.rb +74 -0
- data/lib/trace_viz/utils/format_utils.rb +24 -0
- data/lib/trace_viz/utils/id_generator.rb +35 -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 +140 -16
- data/lib/trace_viz/adapters/trace_point/depth_manager.rb +0 -34
- data/lib/trace_viz/adapters/trace_point/event_handler.rb +0 -36
- data/lib/trace_viz/adapters/trace_point/trace_data.rb +0 -89
- data/lib/trace_viz/adapters/trace_point/trace_formatter.rb +0 -95
- data/lib/trace_viz/adapters/trace_point/trace_logger.rb +0 -44
- data/lib/trace_viz/context/manager/context_map.rb +0 -31
- data/lib/trace_viz/context/manager/context_operations.rb +0 -60
- data/lib/trace_viz/context/manager/context_registry.rb +0 -20
- 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,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
|