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
data/lib/trace_viz/logger.rb
CHANGED
@@ -1,73 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "trace_viz/utils/colorize"
|
4
|
+
|
3
5
|
module TraceViz
|
4
6
|
class Logger
|
5
|
-
|
6
|
-
reset: "\e[0m",
|
7
|
-
info: "\e[34m",
|
8
|
-
success: "\e[32m",
|
9
|
-
error: "\e[31m",
|
10
|
-
warn: "\e[33m",
|
11
|
-
start: "\e[36m",
|
12
|
-
finish: "\e[35m",
|
13
|
-
}.freeze
|
14
|
-
|
15
|
-
EMOJIS = {
|
16
|
-
info: "ℹ️",
|
17
|
-
success: "✅",
|
18
|
-
error: "❌",
|
19
|
-
warn: "⚠️",
|
20
|
-
start: "🚀",
|
21
|
-
finish: "🏁",
|
22
|
-
}.freeze
|
23
|
-
|
24
|
-
LEVELS = [:info, :success, :error, :warn, :start, :finish].freeze
|
7
|
+
LEVELS = Defaults::Actions.keys.freeze
|
25
8
|
|
26
9
|
def initialize(output: $stdout)
|
27
10
|
@output = output
|
28
11
|
end
|
29
12
|
|
30
|
-
|
31
|
-
|
13
|
+
LEVELS.each do |level|
|
14
|
+
define_method(level) do |message|
|
15
|
+
log(message, level)
|
16
|
+
end
|
32
17
|
end
|
33
18
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
19
|
+
def log(message, level = :default)
|
20
|
+
validate_message!(message)
|
21
|
+
validate_level!(level)
|
37
22
|
|
38
|
-
|
39
|
-
|
40
|
-
end
|
23
|
+
colors = Defaults::Actions.colors_for(level)
|
24
|
+
emoji = Defaults::Actions.emoji_for(level)
|
41
25
|
|
42
|
-
|
43
|
-
|
44
|
-
end
|
26
|
+
raw_message = build_message(message, level, emoji)
|
27
|
+
formatted_message = apply_colors(raw_message, colors)
|
45
28
|
|
46
|
-
|
47
|
-
log(:start, message)
|
48
|
-
end
|
49
|
-
|
50
|
-
def finish(message)
|
51
|
-
log(:finish, message)
|
29
|
+
@output.puts(formatted_message)
|
52
30
|
end
|
53
31
|
|
54
32
|
private
|
55
33
|
|
56
|
-
def
|
57
|
-
|
34
|
+
def validate_message!(message)
|
35
|
+
raise ArgumentError, "Message must be a String" unless message.is_a?(String)
|
36
|
+
end
|
58
37
|
|
59
|
-
|
60
|
-
|
38
|
+
def validate_level!(level)
|
39
|
+
raise ArgumentError, "Invalid log level: #{level}" unless LEVELS.include?(level)
|
40
|
+
end
|
61
41
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
message,
|
68
|
-
)
|
42
|
+
def build_message(message, level, emoji)
|
43
|
+
level_str = level == :default ? "" : "[#{level.to_s.upcase}]"
|
44
|
+
merged_emoji_level = "#{emoji} #{level_str}".strip
|
45
|
+
format("%s%s", merged_emoji_level, message)
|
46
|
+
end
|
69
47
|
|
70
|
-
|
48
|
+
def apply_colors(message, colors)
|
49
|
+
Utils::Colorize.colorize(message, *colors)
|
71
50
|
end
|
72
51
|
end
|
73
52
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TraceViz
|
4
|
+
module Loggers
|
5
|
+
class BaseLogger
|
6
|
+
def initialize
|
7
|
+
@logger = TraceViz.logger
|
8
|
+
end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def log(*args)
|
12
|
+
new(*args).log
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def log
|
17
|
+
raise NotImplementedError
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :logger
|
23
|
+
|
24
|
+
def log_message(level, message)
|
25
|
+
logger.send(level, message)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TraceViz
|
4
|
+
module Loggers
|
5
|
+
class LogLevelResolver
|
6
|
+
LOG_LEVELS = {
|
7
|
+
call: :start,
|
8
|
+
return: :finish,
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def resolve(trace_data)
|
13
|
+
LOG_LEVELS[trace_data.event] || :info
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -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
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base_logger"
|
4
|
+
require_relative "log_level_resolver"
|
5
|
+
require "trace_viz/formatters/log/formatter_factory"
|
6
|
+
|
7
|
+
module TraceViz
|
8
|
+
module Loggers
|
9
|
+
class TraceLogger < BaseLogger
|
10
|
+
def initialize(trace_data)
|
11
|
+
super()
|
12
|
+
|
13
|
+
@trace_data = trace_data
|
14
|
+
end
|
15
|
+
|
16
|
+
def log
|
17
|
+
log_message(log_level, formatted_message)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :trace_data
|
23
|
+
|
24
|
+
def log_level
|
25
|
+
LogLevelResolver.resolve(trace_data)
|
26
|
+
end
|
27
|
+
|
28
|
+
def formatted_message
|
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)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "base_logger"
|
4
|
+
|
5
|
+
module TraceViz
|
6
|
+
module Loggers
|
7
|
+
class TraceStatsLogger < BaseLogger
|
8
|
+
def initialize(collector)
|
9
|
+
super()
|
10
|
+
@collector = collector
|
11
|
+
@stats = collector.stats
|
12
|
+
end
|
13
|
+
|
14
|
+
def log
|
15
|
+
logger.stats(format_stats)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
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
|
41
|
+
|
42
|
+
def formatted_event_counts
|
43
|
+
stats.event_counts.map { |event, count| "#{event.capitalize}: #{count}" }.join(", ")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
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,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "trace_viz/helpers"
|
4
|
+
require "trace_viz/traits"
|
5
|
+
|
6
|
+
module TraceViz
|
7
|
+
module TraceData
|
8
|
+
class Base
|
9
|
+
include Helpers::ConfigHelper
|
10
|
+
include Traits::DepthTrackable
|
11
|
+
include Traits::TimeTrackable
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
assign_depth(0)
|
15
|
+
record_timestamp
|
16
|
+
end
|
17
|
+
|
18
|
+
def event
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
|
22
|
+
def klass
|
23
|
+
raise NotImplementedError
|
24
|
+
end
|
25
|
+
|
26
|
+
def action
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
def path
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
|
34
|
+
def line_number
|
35
|
+
raise NotImplementedError
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_h
|
39
|
+
{
|
40
|
+
event: event,
|
41
|
+
klass: klass,
|
42
|
+
action: action,
|
43
|
+
path: path,
|
44
|
+
line_number: line_number,
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
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
|