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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +119 -0
- data/app/assets/builds/profiler.js +20 -4
- data/app/controllers/profiler/api/console_controller.rb +1 -11
- data/app/controllers/profiler/api/jobs_controller.rb +1 -11
- data/app/controllers/profiler/api/profiles_controller.rb +20 -28
- data/app/controllers/profiler/api/tests_controller.rb +1 -11
- data/app/controllers/profiler/api/toolbar_controller.rb +2 -20
- data/app/controllers/profiler/application_controller.rb +55 -15
- data/app/controllers/profiler/profiles_controller.rb +2 -16
- data/lib/profiler/ajax_data.rb +40 -0
- data/lib/profiler/cluster/slave_proxy.rb +7 -5
- data/lib/profiler/collectors/base_collector.rb +8 -3
- data/lib/profiler/collectors/cache_collector.rb +3 -3
- data/lib/profiler/collectors/database_collector.rb +128 -10
- data/lib/profiler/collectors/env_collector.rb +12 -4
- data/lib/profiler/collectors/exception_collector.rb +7 -9
- data/lib/profiler/collectors/flamegraph_collector.rb +5 -5
- data/lib/profiler/collectors/function_profiler_collector.rb +28 -4
- data/lib/profiler/collectors/mailer_collector.rb +2 -8
- data/lib/profiler/collectors/routes_collector.rb +7 -50
- data/lib/profiler/collectors/scoped_notifications.rb +229 -0
- data/lib/profiler/collectors/view_collector.rb +2 -2
- data/lib/profiler/configuration.rb +20 -5
- data/lib/profiler/instrumentation/executor_context_propagation.rb +47 -0
- data/lib/profiler/instrumentation/request_context.rb +77 -0
- data/lib/profiler/instrumentation/thread_context_propagation.rb +11 -16
- data/lib/profiler/job_profiler.rb +4 -2
- data/lib/profiler/mcp/resources/failing_tests.rb +1 -1
- data/lib/profiler/mcp/resources/recent_console.rb +2 -2
- data/lib/profiler/mcp/resources/recent_jobs.rb +2 -2
- data/lib/profiler/mcp/resources/slow_tests.rb +1 -1
- data/lib/profiler/mcp/server.rb +8 -2
- data/lib/profiler/mcp/tools/get_profile_ajax.rb +2 -0
- data/lib/profiler/mcp/tools/get_profile_detail.rb +8 -1
- data/lib/profiler/mcp/tools/get_test_profile_detail.rb +1 -1
- data/lib/profiler/mcp/tools/query_console_profiles.rb +1 -1
- data/lib/profiler/mcp/tools/query_jobs.rb +1 -1
- data/lib/profiler/mcp/tools/query_profiles.rb +1 -1
- data/lib/profiler/mcp/tools/query_test_profiles.rb +1 -1
- data/lib/profiler/mcp/tools/run_tests.rb +1 -1
- data/lib/profiler/middleware/profiler_middleware.rb +4 -1
- data/lib/profiler/process_snapshot.rb +157 -0
- data/lib/profiler/railtie.rb +3 -0
- data/lib/profiler/storage/file_store.rb +332 -58
- data/lib/profiler/storage/memory_store.rb +60 -31
- data/lib/profiler/storage/private_files.rb +13 -0
- data/lib/profiler/storage/redis_store.rb +251 -32
- data/lib/profiler/storage/sqlite_store.rb +57 -9
- data/lib/profiler/storage/summary.rb +50 -0
- data/lib/profiler/storage/unavailable.rb +58 -0
- data/lib/profiler/test_helpers/reporter.rb +1 -1
- data/lib/profiler/version.rb +1 -1
- data/lib/profiler.rb +17 -1
- 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" }
|
data/lib/profiler/version.rb
CHANGED
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.
|
|
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
|