rails-profiler 0.31.2 → 0.31.4

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +119 -0
  3. data/app/assets/builds/profiler.js +20 -4
  4. data/app/controllers/profiler/api/console_controller.rb +1 -11
  5. data/app/controllers/profiler/api/jobs_controller.rb +1 -11
  6. data/app/controllers/profiler/api/profiles_controller.rb +20 -28
  7. data/app/controllers/profiler/api/tests_controller.rb +1 -11
  8. data/app/controllers/profiler/api/toolbar_controller.rb +2 -20
  9. data/app/controllers/profiler/application_controller.rb +55 -15
  10. data/app/controllers/profiler/profiles_controller.rb +2 -16
  11. data/lib/profiler/ajax_data.rb +40 -0
  12. data/lib/profiler/cluster/slave_proxy.rb +7 -5
  13. data/lib/profiler/collectors/base_collector.rb +8 -3
  14. data/lib/profiler/collectors/cache_collector.rb +3 -3
  15. data/lib/profiler/collectors/database_collector.rb +128 -10
  16. data/lib/profiler/collectors/env_collector.rb +12 -4
  17. data/lib/profiler/collectors/exception_collector.rb +7 -9
  18. data/lib/profiler/collectors/flamegraph_collector.rb +5 -5
  19. data/lib/profiler/collectors/function_profiler_collector.rb +28 -4
  20. data/lib/profiler/collectors/mailer_collector.rb +2 -8
  21. data/lib/profiler/collectors/routes_collector.rb +7 -50
  22. data/lib/profiler/collectors/scoped_notifications.rb +229 -0
  23. data/lib/profiler/collectors/view_collector.rb +2 -2
  24. data/lib/profiler/configuration.rb +20 -5
  25. data/lib/profiler/instrumentation/executor_context_propagation.rb +47 -0
  26. data/lib/profiler/instrumentation/request_context.rb +77 -0
  27. data/lib/profiler/instrumentation/thread_context_propagation.rb +11 -16
  28. data/lib/profiler/job_profiler.rb +4 -2
  29. data/lib/profiler/mcp/resources/failing_tests.rb +1 -1
  30. data/lib/profiler/mcp/resources/recent_console.rb +2 -2
  31. data/lib/profiler/mcp/resources/recent_jobs.rb +2 -2
  32. data/lib/profiler/mcp/resources/slow_tests.rb +1 -1
  33. data/lib/profiler/mcp/server.rb +8 -2
  34. data/lib/profiler/mcp/tools/get_profile_ajax.rb +2 -0
  35. data/lib/profiler/mcp/tools/get_profile_detail.rb +8 -1
  36. data/lib/profiler/mcp/tools/get_test_profile_detail.rb +1 -1
  37. data/lib/profiler/mcp/tools/query_console_profiles.rb +1 -1
  38. data/lib/profiler/mcp/tools/query_jobs.rb +1 -1
  39. data/lib/profiler/mcp/tools/query_profiles.rb +1 -1
  40. data/lib/profiler/mcp/tools/query_test_profiles.rb +1 -1
  41. data/lib/profiler/mcp/tools/run_tests.rb +1 -1
  42. data/lib/profiler/middleware/profiler_middleware.rb +4 -1
  43. data/lib/profiler/process_snapshot.rb +157 -0
  44. data/lib/profiler/railtie.rb +3 -0
  45. data/lib/profiler/storage/file_store.rb +332 -58
  46. data/lib/profiler/storage/memory_store.rb +60 -31
  47. data/lib/profiler/storage/private_files.rb +13 -0
  48. data/lib/profiler/storage/redis_store.rb +251 -32
  49. data/lib/profiler/storage/sqlite_store.rb +57 -9
  50. data/lib/profiler/storage/summary.rb +50 -0
  51. data/lib/profiler/storage/unavailable.rb +58 -0
  52. data/lib/profiler/test_helpers/reporter.rb +1 -1
  53. data/lib/profiler/version.rb +1 -1
  54. data/lib/profiler.rb +17 -1
  55. metadata +8 -1
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Profiler
4
+ module Storage
5
+ # Stands in for a store that could not be created (an index or lock replaced by a symbolic
6
+ # link, a directory that cannot be written, a database that cannot be opened): the cause is
7
+ # said once per process, without a backtrace, rather than with one on every request. Saves are
8
+ # dropped; reads, which a person asked for from the dashboard or an MCP tool, raise the cause.
9
+ # Profiler.storage tries to create the store again on its next call, so fixing the cause is
10
+ # enough.
11
+ class Unavailable
12
+ # What the reads raise: the cause in one line, without a path (the profiler's routes answer
13
+ # it as a 503, the MCP tools as an error).
14
+ class Error < Profiler::Error; end
15
+
16
+ @said = {}
17
+ @mutex = Mutex.new
18
+
19
+ class << self
20
+ def for(error)
21
+ key = [Process.pid, error.class.name, error.message]
22
+ first = @mutex.synchronize { @said[key] ? false : (@said[key] = true) }
23
+ if first
24
+ warn "[Profiler] storage unavailable, profiles are not saved until it is fixed: " \
25
+ "#{error.class}: #{error.message}"
26
+ end
27
+ new(error)
28
+ end
29
+
30
+ def reset!
31
+ @mutex.synchronize { @said = {} }
32
+ end
33
+ end
34
+
35
+ def initialize(error)
36
+ @error = Error.new("The profiler storage is unavailable: #{self.class.short_cause(error)}")
37
+ end
38
+
39
+ # First line of the message, absolute paths replaced, credentials masked, at most 300
40
+ # characters.
41
+ def self.short_cause(error)
42
+ line = error.message.to_s.lines.first.to_s.strip
43
+ line = line.gsub(%r{(?<=\A|[\s'"(=])(?:[A-Za-z]:)?[/\\][^\s'"]*[^\s'":,.;)]}, "[path]")
44
+ line = Redaction.hide_credentials(line) if defined?(Redaction)
45
+ line = line[0, 300]
46
+ line.empty? ? error.class.name : line
47
+ end
48
+
49
+ def save(token, _profile)
50
+ token
51
+ end
52
+
53
+ %i[load list cleanup exists? find_by_parent delete clear].each do |name|
54
+ define_method(name) { |*, **| raise @error }
55
+ end
56
+ end
57
+ end
58
+ end
@@ -8,7 +8,7 @@ module Profiler
8
8
  def self.print
9
9
  return unless Profiler.enabled?
10
10
 
11
- profiles = Profiler.storage.list(limit: 1000).select { |p| p.profile_type == "test" }
11
+ profiles = Profiler.storage.list(limit: 1000, type: "test").select { |p| p.profile_type == "test" }
12
12
  return if profiles.empty?
13
13
 
14
14
  passed = profiles.count { |p| test_status(p) == "passed" }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Profiler
4
- VERSION = "0.31.2"
4
+ VERSION = "0.31.4"
5
5
  end
data/lib/profiler.rb CHANGED
@@ -16,6 +16,9 @@ module Profiler
16
16
  attr_accessor :function_profiling_max_frames
17
17
  attr_accessor :function_profiling_mode
18
18
  attr_accessor :function_profiling_clock
19
+ # Without stackprof, the function profiler stays off unless this is true: it then traces
20
+ # every method call of the request's thread with a TracePoint, several times slower.
21
+ attr_accessor :function_profiling_tracepoint_fallback
19
22
 
20
23
  def configuration
21
24
  @configuration ||= Configuration.new
@@ -25,8 +28,17 @@ module Profiler
25
28
  yield(configuration)
26
29
  end
27
30
 
31
+ STORAGE_LOCK = Mutex.new
32
+
33
+ # Built once, under a lock: the first requests of a threaded server ask for it together, and
34
+ # a profile saved into a store that another thread replaced would be lost. Read without the
35
+ # lock once it exists.
36
+ # A store that cannot be created is said once (Storage::Unavailable) and tried again on the
37
+ # next call.
28
38
  def storage
29
- @storage ||= configuration.storage_backend
39
+ @storage || STORAGE_LOCK.synchronize { @storage ||= configuration.storage_backend }
40
+ rescue StandardError => e
41
+ Storage::Unavailable.for(e)
30
42
  end
31
43
 
32
44
  # Saves a profile from a path of the application (a job, a console command, a test, an
@@ -114,6 +126,7 @@ module Profiler
114
126
  self.function_profiling_max_frames = 2000
115
127
  self.function_profiling_mode = "lite"
116
128
  self.function_profiling_clock = "wall"
129
+ self.function_profiling_tracepoint_fallback = false
117
130
  end
118
131
 
119
132
  # Require core components
@@ -136,8 +149,11 @@ require_relative "profiler/collectors/mailer_collector"
136
149
 
137
150
  require_relative "profiler/storage/token"
138
151
  require_relative "profiler/storage/private_files"
152
+ require_relative "profiler/storage/unavailable"
153
+ require_relative "profiler/ajax_data"
139
154
  require_relative "profiler/env_override_store"
140
155
  require_relative "profiler/instrumentation/thread_context_propagation"
156
+ require_relative "profiler/instrumentation/executor_context_propagation"
141
157
  require_relative "profiler/sse/event_bus"
142
158
  require_relative "profiler/sse/redis_event_bus"
143
159
  require_relative "profiler/sse/bus"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.31.2
4
+ version: 0.31.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sébastien Duplessy
@@ -133,6 +133,7 @@ files:
133
133
  - config/routes.rb
134
134
  - exe/profiler-mcp
135
135
  - lib/profiler.rb
136
+ - lib/profiler/ajax_data.rb
136
137
  - lib/profiler/allocation_counter.rb
137
138
  - lib/profiler/boot_env.rb
138
139
  - lib/profiler/cluster/master_client.rb
@@ -158,6 +159,7 @@ files:
158
159
  - lib/profiler/collectors/mailer_collector.rb
159
160
  - lib/profiler/collectors/request_collector.rb
160
161
  - lib/profiler/collectors/routes_collector.rb
162
+ - lib/profiler/collectors/scoped_notifications.rb
161
163
  - lib/profiler/collectors/test_collector.rb
162
164
  - lib/profiler/collectors/view_collector.rb
163
165
  - lib/profiler/configuration.rb
@@ -167,8 +169,10 @@ files:
167
169
  - lib/profiler/env_override_store.rb
168
170
  - lib/profiler/explain_runner.rb
169
171
  - lib/profiler/instrumentation/active_job_instrumentation.rb
172
+ - lib/profiler/instrumentation/executor_context_propagation.rb
170
173
  - lib/profiler/instrumentation/irb_instrumentation.rb
171
174
  - lib/profiler/instrumentation/net_http_instrumentation.rb
175
+ - lib/profiler/instrumentation/request_context.rb
172
176
  - lib/profiler/instrumentation/sidekiq_middleware.rb
173
177
  - lib/profiler/instrumentation/thread_context_propagation.rb
174
178
  - lib/profiler/job_profiler.rb
@@ -215,6 +219,7 @@ files:
215
219
  - lib/profiler/models/profile.rb
216
220
  - lib/profiler/models/sql_query.rb
217
221
  - lib/profiler/models/timeline_event.rb
222
+ - lib/profiler/process_snapshot.rb
218
223
  - lib/profiler/railtie.rb
219
224
  - lib/profiler/redaction.rb
220
225
  - lib/profiler/sql_statement.rb
@@ -228,7 +233,9 @@ files:
228
233
  - lib/profiler/storage/private_files.rb
229
234
  - lib/profiler/storage/redis_store.rb
230
235
  - lib/profiler/storage/sqlite_store.rb
236
+ - lib/profiler/storage/summary.rb
231
237
  - lib/profiler/storage/token.rb
238
+ - lib/profiler/storage/unavailable.rb
232
239
  - lib/profiler/tasks/profiler.rake
233
240
  - lib/profiler/test_helpers/minitest_support.rb
234
241
  - lib/profiler/test_helpers/reporter.rb