rails_tracepoint_stack 0.3.3 → 0.3.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37171281cd058faf3a6dadf86d4a2e56e57417f1ccf46af6d010a2a1f5657562
4
- data.tar.gz: 7bc1956035baaf3308ed562024c7376eb59a6c6bb59e23e450a66f51e2b2d650
3
+ metadata.gz: f67c982828a7ad060513cbb50daf9f88399229a534a43cf12a674571b6ae11ae
4
+ data.tar.gz: fd80c178bf9de58408e769742d7640b0ccdbcc99a4722ec9ccbd6e68d115ff51
5
5
  SHA512:
6
- metadata.gz: 0f452899bde414b1a11dce5fd483843b980629c1dad42aa73b045c9c3315dd9226b36cd98f47b8a5c11221aed26d2aaf62c87fd294a07145936a100c164f3a07
7
- data.tar.gz: 37fb83da7315e329a9d75ad32ca198c7464be7aadead056abd19f0a1ad3190e859c0d4c4bb47572a0755cb259349b45bd3984ec50ef74ece89a843aa4f2d5c52
6
+ metadata.gz: 57b7125a7a242bf59f15096fffeef7de3c8a7543162fa7851566a07256d2ed790d39ff9c9dfcd1f3c3f8ca54714b797ed5f5015f2eb0d6f0adbe57e3ad582412
7
+ data.tar.gz: cd33cf3e53fe35fe62ba3867cfe8ff56047cceae59e2139c55898fcb0ed0e44d8dccf57a0b66954f1543797c1cb1070b6c68f479f76ce80f0c15282518c50110
@@ -0,0 +1,19 @@
1
+ module RailsTracepointStack
2
+ module Filter
3
+ module CustomTraceSelectorFilter
4
+ def is_a_trace_required_to_watch_by_the_custom_configs?(trace:)
5
+ return false unless RailsTracepointStack.configuration.file_path_to_filter_patterns.any?
6
+
7
+ filter_match_a_custom_pattern_to_be_not_ignored?(trace)
8
+ end
9
+
10
+ private
11
+
12
+ def filter_match_a_custom_pattern_to_be_not_ignored?(trace)
13
+ RailsTracepointStack.configuration.file_path_to_filter_patterns.any? do |pattern|
14
+ trace.file_path.match?(pattern)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -2,7 +2,7 @@ module RailsTracepointStack
2
2
  module Filter
3
3
  class RbConfig
4
4
  def self.ruby_lib_path
5
- @ruby_lib_path ||= ::RbConfig::CONFIG['rubylibdir']
5
+ @ruby_lib_path ||= ::RbConfig::CONFIG["rubylibdir"]
6
6
  end
7
7
  end
8
8
  end
@@ -0,0 +1,42 @@
1
+ require 'rails_tracepoint_stack/filter/gem_path'
2
+ require 'rails_tracepoint_stack/filter/rb_config'
3
+
4
+ module RailsTracepointStack
5
+ module Filter
6
+ module TraceFromDependenciesFilter
7
+ def should_ignore_because_is_a_internal_dependency?(trace:)
8
+ return false if not_ignore_external_source_traces?
9
+
10
+ file_path_starts_with_gem_path?(trace) ||
11
+ file_path_starts_with_ruby_lib_path?(trace) ||
12
+ file_path_include_bundler_gems_path?(trace)
13
+ end
14
+
15
+ private
16
+
17
+ def file_path_starts_with_gem_path?(trace)
18
+ gem_paths.any? { |path| trace.file_path.start_with?(path) }
19
+ end
20
+
21
+ def file_path_starts_with_ruby_lib_path?(trace)
22
+ trace.file_path.start_with?(ruby_lib_path)
23
+ end
24
+
25
+ def file_path_include_bundler_gems_path?(trace)
26
+ trace.file_path.include?("gems/bundler")
27
+ end
28
+
29
+ def gem_paths
30
+ @gem_paths ||= RailsTracepointStack::Filter::GemPath.full_gem_path
31
+ end
32
+
33
+ def ruby_lib_path
34
+ @ruby_lib_path ||= RailsTracepointStack::Filter::RbConfig.ruby_lib_path
35
+ end
36
+
37
+ def not_ignore_external_source_traces?
38
+ RailsTracepointStack.configuration.log_external_sources
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,17 @@
1
+ module RailsTracepointStack
2
+ module Filter
3
+ module TraceFromRubyCodeFilter
4
+ def should_ignore_because_is_ruby_trace?(trace:)
5
+ return false if not_ignore_external_source_traces?
6
+
7
+ trace.file_path.start_with?('<internal:') || trace.file_path == '(eval)'
8
+ end
9
+
10
+ private
11
+
12
+ def not_ignore_external_source_traces?
13
+ RailsTracepointStack.configuration.log_external_sources
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module RailsTracepointStack
2
+ module Filter
3
+ module TraceToIgnoreFilter
4
+ def attends_some_custom_pattern_to_ignore?(trace:)
5
+ return false unless RailsTracepointStack.configuration.ignore_patterns.any?
6
+
7
+ RailsTracepointStack
8
+ .configuration
9
+ .ignore_patterns
10
+ .any? { |pattern| trace.file_path.match?(pattern) }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,5 @@
1
+ require "json"
2
+
1
3
  module RailsTracepointStack
2
4
  module LogFormatter
3
5
  def self.message(trace)
@@ -10,17 +12,183 @@ module RailsTracepointStack
10
12
  end
11
13
 
12
14
  def self.text(trace)
13
- "called: #{trace.class_name}##{trace.method_name} in #{trace.file_path}:#{trace.line_number} with params: #{trace.params}"
15
+ "called: #{trace.class_name}##{trace.method_name} in #{trace.file_path}:#{trace.line_number} with params: #{text_value(trace.params)}"
14
16
  end
15
17
 
16
18
  def self.json(trace)
17
- {
18
- class: trace.class_name,
19
- method_name: trace.method_name,
20
- path: trace.file_path,
19
+ JSON.generate(
20
+ class: stringify(trace.class_name),
21
+ method_name: stringify(trace.method_name),
22
+ path: stringify(trace.file_path),
21
23
  line: trace.line_number,
22
- params: trace.params
23
- }.to_json
24
+ params: safe_value(trace.params)
25
+ )
26
+ end
27
+
28
+ def self.stringify(value)
29
+ return nil if value.nil?
30
+
31
+ value.to_s
32
+ rescue SystemStackError, StandardError => error
33
+ inspect_fallback(value, error)
34
+ end
35
+
36
+ def self.safe_value(value, ancestry = {})
37
+ case value
38
+ when nil, true, false, Numeric, String
39
+ value
40
+ when Symbol
41
+ value.to_s
42
+ when Array
43
+ safe_array(value, ancestry)
44
+ when Hash
45
+ safe_hash(value, ancestry)
46
+ else
47
+ safe_json_object(value)
48
+ end
49
+ rescue SystemStackError, StandardError => error
50
+ inspect_fallback(value, error)
51
+ end
52
+
53
+ def self.safe_array(value, ancestry)
54
+ object_id = value.__id__
55
+ return recursive_placeholder(value) if ancestry.key?(object_id)
56
+
57
+ ancestry[object_id] = true
58
+ value.map { |item| safe_value(item, ancestry) }
59
+ ensure
60
+ ancestry.delete(object_id)
61
+ end
62
+
63
+ def self.safe_hash(value, ancestry)
64
+ object_id = value.__id__
65
+ return recursive_placeholder(value) if ancestry.key?(object_id)
66
+
67
+ ancestry[object_id] = true
68
+ value.each_with_object({}) do |(key, item), result|
69
+ result[safe_hash_key(key, ancestry)] = safe_value(item, ancestry)
70
+ end
71
+ ensure
72
+ ancestry.delete(object_id)
73
+ end
74
+
75
+ def self.safe_hash_key(key, ancestry = {})
76
+ case key
77
+ when String
78
+ key
79
+ when Symbol, Numeric
80
+ key.to_s
81
+ when true, false, nil
82
+ key.inspect
83
+ else
84
+ stringify_hash_key(key, ancestry)
85
+ end
86
+ end
87
+
88
+ def self.safe_json_object(value)
89
+ json_value = JSON.parse(JSON.generate(value))
90
+
91
+ return json_value unless default_string_representation?(value, json_value)
92
+
93
+ safe_object_string(value)
94
+ rescue SystemStackError, StandardError
95
+ safe_object_string(value)
96
+ end
97
+
98
+ def self.default_string_representation?(value, json_value)
99
+ json_value.is_a?(String) &&
100
+ value.method(:to_s).owner == Kernel &&
101
+ json_value == value.to_s
102
+ rescue SystemStackError, StandardError
103
+ false
104
+ end
105
+
106
+ def self.stringify_hash_key(key, ancestry)
107
+ normalized_key = safe_value(key, ancestry)
108
+
109
+ case normalized_key
110
+ when String
111
+ normalized_key
112
+ when nil
113
+ "null"
114
+ when true, false, Numeric
115
+ normalized_key.to_s
116
+ else
117
+ JSON.generate(normalized_key)
118
+ end
119
+ rescue SystemStackError, StandardError
120
+ safe_object_string(key)
121
+ end
122
+
123
+ def self.safe_object_string(value)
124
+ value.inspect
125
+ rescue SystemStackError, StandardError => error
126
+ inspect_fallback(value, error)
127
+ end
128
+
129
+ def self.inspect_fallback(value, error)
130
+ class_name = value.nil? ? "NilClass" : value.class.to_s
131
+ "#<#{class_name} unserializable: #{error.class}: #{error.message}>"
132
+ end
133
+
134
+ def self.recursive_placeholder(value)
135
+ "[recursive #{value.class}]"
136
+ end
137
+
138
+ def self.text_value(value, ancestry = {})
139
+ case value
140
+ when nil
141
+ "nil"
142
+ when true, false, Numeric
143
+ value.to_s
144
+ when String
145
+ value.inspect
146
+ when Symbol
147
+ ":#{value}"
148
+ when Array
149
+ text_array(value, ancestry)
150
+ when Hash
151
+ text_hash(value, ancestry)
152
+ else
153
+ safe_object_string(value)
154
+ end
155
+ rescue SystemStackError, StandardError => error
156
+ inspect_fallback(value, error)
157
+ end
158
+
159
+ def self.text_array(value, ancestry)
160
+ object_id = value.__id__
161
+ return recursive_placeholder(value) if ancestry.key?(object_id)
162
+
163
+ ancestry[object_id] = true
164
+ "[#{value.map { |item| text_value(item, ancestry) }.join(", ")}]"
165
+ ensure
166
+ ancestry.delete(object_id)
167
+ end
168
+
169
+ def self.text_hash(value, ancestry)
170
+ object_id = value.__id__
171
+ return recursive_placeholder(value) if ancestry.key?(object_id)
172
+
173
+ ancestry[object_id] = true
174
+ pairs = value.map do |key, item|
175
+ "#{text_hash_key(key, ancestry)}=>#{text_value(item, ancestry)}"
176
+ end
177
+
178
+ "{#{pairs.join(", ")}}"
179
+ ensure
180
+ ancestry.delete(object_id)
181
+ end
182
+
183
+ def self.text_hash_key(key, ancestry = {})
184
+ case key
185
+ when Symbol
186
+ ":#{key}"
187
+ when String
188
+ key.inspect
189
+ else
190
+ text_value(key, ancestry)
191
+ end
24
192
  end
25
193
  end
26
194
  end
@@ -5,7 +5,7 @@ module RailsTracepointStack
5
5
  RailsTracepointStack.configuration.logger.info(msg)
6
6
  else
7
7
  # TODO: Add the support to Rails.env for the default filename
8
- File.open("log/rails_tracepoint_stack.log", 'a') do |f|
8
+ File.open("log/rails_tracepoint_stack.log", "a") do |f|
9
9
  f.puts msg
10
10
  end
11
11
  end
@@ -1,4 +1,4 @@
1
- require 'forwardable'
1
+ require "forwardable"
2
2
 
3
3
  module RailsTracepointStack
4
4
  class Trace
@@ -1,63 +1,30 @@
1
- require 'rails_tracepoint_stack/filter/gem_path'
2
- require 'rails_tracepoint_stack/filter/rb_config'
1
+ require 'rails_tracepoint_stack/filter/custom_trace_selector_filter'
2
+ require 'rails_tracepoint_stack/filter/trace_from_dependencies_filter'
3
+ require 'rails_tracepoint_stack/filter/trace_from_ruby_code_filter'
4
+ require 'rails_tracepoint_stack/filter/trace_to_ignore_filter'
3
5
 
4
6
  module RailsTracepointStack
5
- class TraceFilter
6
- def self.ignore_trace?(trace:)
7
- if defined_file_path_to_filter_patterns?
8
- not_matches_file_path_to_filter_patterns?(trace)
9
- else
10
- contains_to_ignore_strings?(trace) || from_gempath_or_lib_path?(trace) || is_a_to_ignore_pattern?(trace)
7
+ module TraceFilter
8
+ include RailsTracepointStack::Filter::CustomTraceSelectorFilter
9
+ include RailsTracepointStack::Filter::TraceFromDependenciesFilter
10
+ include RailsTracepointStack::Filter::TraceFromRubyCodeFilter
11
+ include RailsTracepointStack::Filter::TraceToIgnoreFilter
12
+
13
+ def ignore_trace?(trace:)
14
+ if attends_some_custom_pattern_to_ignore?(trace: trace)
15
+ return true
11
16
  end
12
- end
13
-
14
- private
15
-
16
- def self.contains_to_ignore_strings?(trace)
17
- trace.file_path.start_with?('<internal:') || trace.file_path == '(eval)'
18
- end
19
-
20
- def self.from_gempath_or_lib_path?(trace)
21
- !RailsTracepointStack.configuration&.log_external_sources &&
22
- (
23
- file_path_starts_with_gem_path?(trace) ||
24
- file_path_starts_with_ruby_lib_path?(trace) ||
25
- file_path_starts_with_bundler_path?(trace)
26
- )
27
- end
28
-
29
- def self.is_a_to_ignore_pattern?(trace)
30
- RailsTracepointStack.configuration&.ignore_patterns&.any? { |pattern| trace.file_path.match?(pattern) }
31
- end
32
-
33
- def self.file_path_starts_with_gem_path?(trace)
34
- gem_paths.any? { |path| trace.file_path.start_with?(path) }
35
- end
36
-
37
- def self.file_path_starts_with_ruby_lib_path?(trace)
38
- trace.file_path.start_with?(ruby_lib_path)
39
- end
40
-
41
- def self.file_path_starts_with_bundler_path?(trace)
42
- trace.file_path.include?("gems/bundler")
43
- end
44
-
45
- def self.gem_paths
46
- @gem_paths ||= RailsTracepointStack::Filter::GemPath.full_gem_path
47
- end
48
-
49
- def self.ruby_lib_path
50
- @ruby_lib_path ||= RailsTracepointStack::Filter::RbConfig.ruby_lib_path
51
- end
52
-
53
- def self.defined_file_path_to_filter_patterns?
54
- RailsTracepointStack.configuration&.file_path_to_filter_patterns&.any?
55
- end
56
-
57
- def self.not_matches_file_path_to_filter_patterns?(trace)
58
- !RailsTracepointStack.configuration.file_path_to_filter_patterns.any? do |pattern|
59
- trace.file_path.match?(pattern)
17
+ if is_a_trace_required_to_watch_by_the_custom_configs?(trace: trace)
18
+ return false
60
19
  end
20
+ if should_ignore_because_is_a_internal_dependency?(trace: trace)
21
+ return true
22
+ end
23
+ if should_ignore_because_is_ruby_trace?(trace: trace)
24
+ return true
25
+ end
26
+
27
+ return false
61
28
  end
62
29
  end
63
30
  end
@@ -1,21 +1,31 @@
1
- #TODO: Move to a loader file
2
- require 'rails_tracepoint_stack/logger'
3
- require 'rails_tracepoint_stack/trace_filter'
4
- require 'rails_tracepoint_stack/trace'
5
- require 'rails_tracepoint_stack/log_formatter'
1
+ # TODO: Move to a loader file
2
+ require "rails_tracepoint_stack/logger"
3
+ require "rails_tracepoint_stack/trace_filter"
4
+ require "rails_tracepoint_stack/trace"
5
+ require "rails_tracepoint_stack/log_formatter"
6
6
 
7
7
  module RailsTracepointStack
8
8
  class Tracer
9
- # TODO: Tracer.new shoud return the tracer. Is weird to call Tracer.new.tracer
10
- def tracer
9
+ include RailsTracepointStack::TraceFilter
10
+ extend Forwardable
11
+
12
+ def_delegators :@tracer, :enable, :disable
13
+
14
+ def initialize
15
+ generate_tracer
16
+ end
17
+
18
+ private
19
+
20
+ def generate_tracer
11
21
  @tracer ||= TracePoint.new(:call) do |tracepoint|
12
22
  trace = RailsTracepointStack::Trace.new(trace_point: tracepoint)
13
23
 
14
- next if RailsTracepointStack::TraceFilter.ignore_trace?(trace: trace)
24
+ next if ignore_trace?(trace: trace)
15
25
 
16
26
  # TODO: Use proper OO
17
27
  message = RailsTracepointStack::LogFormatter.message trace
18
- RailsTracepointStack::Logger.log message
28
+ RailsTracepointStack::Logger.log message
19
29
  end
20
30
  end
21
31
  end
@@ -1,3 +1,3 @@
1
1
  module RailsTracepointStack
2
- VERSION = "0.3.3"
2
+ VERSION = "0.3.5"
3
3
  end
@@ -1,4 +1,3 @@
1
- require 'json'
2
1
  require 'rails_tracepoint_stack/configuration'
3
2
  require 'rails_tracepoint_stack/log_formatter'
4
3
  require 'rails_tracepoint_stack/tracer'
@@ -7,18 +6,21 @@ $rails_tracer_rtps = nil
7
6
 
8
7
  module RailsTracepointStack
9
8
  class << self
10
- attr_accessor :configuration, :logger
9
+ attr_writer :configuration, :logger
10
+
11
+ def configuration
12
+ @configuration ||= RailsTracepointStack::Configuration.new
13
+ end
11
14
  end
12
15
 
13
16
  def self.configure
14
- self.configuration ||= RailsTracepointStack::Configuration.new
15
17
  yield(configuration)
16
18
  end
17
19
 
18
20
  def self.enable_trace
19
21
  raise ArgumentError, "Block not given to #enable_trace" unless block_given?
20
22
 
21
- tracer = RailsTracepointStack::Tracer.new.tracer
23
+ tracer = RailsTracepointStack::Tracer.new
22
24
  tracer.enable
23
25
  yield
24
26
  ensure
@@ -26,8 +28,8 @@ module RailsTracepointStack
26
28
  end
27
29
  end
28
30
 
29
- if ENV.fetch('RAILS_TRACEPOINT_STACK_ENABLED', 'false') == 'true'
30
- $rails_tracer_rtps = RailsTracepointStack::Tracer.new.tracer
31
+ if ENV.fetch("RAILS_TRACEPOINT_STACK_ENABLED", "false") == "true"
32
+ $rails_tracer_rtps = RailsTracepointStack::Tracer.new
31
33
  $rails_tracer_rtps.enable
32
34
 
33
35
  at_exit do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_tracepoint_stack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Daniel Pohlod
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-24 00:00:00.000000000 Z
11
+ date: 2026-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -50,6 +50,26 @@ dependencies:
50
50
  - - ">="
51
51
  - !ruby/object:Gem::Version
52
52
  version: 13.0.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: standard
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.39'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.39.1
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.39'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 1.39.1
53
73
  description: A formatted output of all methods called in your rails application of
54
74
  code created by the developer, with the complete path to the class/module, including
55
75
  passed params.
@@ -60,8 +80,12 @@ extra_rdoc_files: []
60
80
  files:
61
81
  - lib/rails_tracepoint_stack.rb
62
82
  - lib/rails_tracepoint_stack/configuration.rb
83
+ - lib/rails_tracepoint_stack/filter/custom_trace_selector_filter.rb
63
84
  - lib/rails_tracepoint_stack/filter/gem_path.rb
64
85
  - lib/rails_tracepoint_stack/filter/rb_config.rb
86
+ - lib/rails_tracepoint_stack/filter/trace_from_dependencies_filter.rb
87
+ - lib/rails_tracepoint_stack/filter/trace_from_ruby_code_filter.rb
88
+ - lib/rails_tracepoint_stack/filter/trace_to_ignore_filter.rb
65
89
  - lib/rails_tracepoint_stack/log_formatter.rb
66
90
  - lib/rails_tracepoint_stack/logger.rb
67
91
  - lib/rails_tracepoint_stack/trace.rb
@@ -74,7 +98,7 @@ licenses:
74
98
  metadata:
75
99
  documentation_uri: https://github.com/carlosdanielpohlod/rails_tracepoint_stack/
76
100
  changelog_uri: https://github.com/carlosdanielpohlod/rails_tracepoint_stack/blob/main/changelog.md
77
- post_install_message:
101
+ post_install_message:
78
102
  rdoc_options: []
79
103
  require_paths:
80
104
  - lib
@@ -89,8 +113,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
89
113
  - !ruby/object:Gem::Version
90
114
  version: '0'
91
115
  requirements: []
92
- rubygems_version: 3.4.10
93
- signing_key:
116
+ rubygems_version: 3.4.19
117
+ signing_key:
94
118
  specification_version: 4
95
119
  summary: Get a complete stack trace for your code on a Rails application.
96
120
  test_files: []