rails-profiler 0.30.13 → 0.30.14

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: 2613fd14e9adfbb7911645a1bd23fcd1043d4424f532e64c267601d021db7ad0
4
- data.tar.gz: 1f474b73d65dd2aac23151a8ea4f61aba98399f7182cd7db9dda39947afb7b28
3
+ metadata.gz: e09eb31d9bcb170273cd7c9df1f6e149d772d38cd52fd0f6d2930644054ccc8d
4
+ data.tar.gz: 5b8996d059b59b4a69e702ff238060dd83e08614fa416ae09ed8ed077d0d550f
5
5
  SHA512:
6
- metadata.gz: 67dd8e4b429926a3fdef908c1491650c796497c177cb263cfdd94e7b14a5587a7a6ef48ea09c33b430ef5bca1ac0c921a4294d16c093127a39b1eac9db5c5cd3
7
- data.tar.gz: 004f12ec514d606d212f49b0ac5c8c1f593437d62cf58e2a2b1242eef67fd144caa1ef165e8371947db4c9d8ae291a9bbdb83a2acf40058a8b53e5e50a78be71
6
+ metadata.gz: 5042a2f2c93acb5fd91e27907880d01b51aecaa7316a34886b827ec73584d9e3dcf356d07079f368066511fe447b06ecbeba1520e5a245befd82eb10f45b2d46
7
+ data.tar.gz: 8ca5df627c525ad56bddfcfa01771f0e8d23f2c3b6ade75d71dde0ea9db85a2d06ca2b2807f834f6195aba3423197d674986033427edae7d612ada1b7398b028
data/CHANGELOG.md CHANGED
@@ -19,6 +19,32 @@ every commit of every tag interval is accounted for one way or the other.
19
19
 
20
20
  ## [Unreleased]
21
21
 
22
+ ## [0.30.14] - 2026-10-05
23
+
24
+ <!-- stamped -->
25
+
26
+ ### Fixed
27
+
28
+ - **Railtie:** Honor `config.enabled` set in `config/initializers/profiler.rb`. The profiler
29
+ decided before the application's initializers had run, so `enabled = false` there still put its
30
+ middlewares in the stack, configured Sidekiq, included its ActiveJob instrumentation and, in
31
+ the test environment, loaded the test profiler, and `enabled = true` in production got none of
32
+ them. Those decisions are now taken once the application's initializers have run. An active
33
+ profiler keeps its place in the middleware stack, and its Sidekiq middlewares and ActiveJob
34
+ callbacks stay ahead of the ones the application installs. The profiler is now the outermost
35
+ layer around a job: it runs before every other Sidekiq middleware, including those of gems
36
+ loaded before it and those the application prepends (such as `Sidekiq::CurrentAttributes`),
37
+ and before the callbacks Rails adds to ActiveJob (logging, instrumentation, and on Rails 7.0
38
+ time zone and locale), so the duration of a profiled job now includes them.
39
+ - **Railtie:** Keep the `enabled`, `storage` and `track_tests` values set with
40
+ `Profiler.configure` in `config/application.rb`, which the Rails defaults overwrote at boot, and
41
+ apply `config.profiler` (`config.profiler.enabled = false` in `config/application.rb`), which was
42
+ accepted and never read. A `config.profiler` key that is not a profiler option logs a warning.
43
+ `config/initializers/profiler.rb` still has the last word. Check these places when upgrading:
44
+ an `enabled` set with `Profiler.configure` in `config/application.rb` or in a
45
+ `config/environments` file, or with `config.profiler.enabled`, now takes effect, in production
46
+ too, where it was overwritten or ignored before.
47
+
22
48
  ## [0.30.13] - 2026-10-04
23
49
 
24
50
  <!-- stamped -->
@@ -25,7 +25,11 @@ module Profiler
25
25
  BUNDLE_GEMFILE BUNDLE_PATH BUNDLE_WITHOUT GEM_HOME GEM_PATH BOOTSNAP_CACHE_DIR
26
26
  ].freeze
27
27
 
28
- attr_accessor :enabled, :storage_options, :collectors,
28
+ # Options whose default depends on the Rails environment: the railtie sets them only when
29
+ # the application has not assigned them itself (see #default).
30
+ RAILS_DEFAULTED = %i[enabled storage track_tests].freeze
31
+
32
+ attr_accessor :storage_options, :collectors,
29
33
  :skip_paths, :slow_query_threshold, :max_queries_warning,
30
34
  :track_memory, :memory_warning_threshold,
31
35
  :mcp_enabled, :mcp_transport, :mcp_port,
@@ -36,7 +40,7 @@ module Profiler
36
40
  :track_jobs,
37
41
  :track_console,
38
42
  :apply_env_overrides_when_disabled,
39
- :track_tests, :test_runner_allow_undiscovered_files,
43
+ :test_runner_allow_undiscovered_files,
40
44
  :track_mailers, :capture_mail_body, :sanitize_mailer_recipients, :mailer_skip_actions,
41
45
  :compress_bodies, :compress_body_threshold,
42
46
  :redact_sensitive_data, :filter_parameters, :env_allowlist,
@@ -47,9 +51,10 @@ module Profiler
47
51
 
48
52
  attr_writer :tmp_path
49
53
 
50
- attr_reader :authorize_block
54
+ attr_reader :authorize_block, :enabled, :track_tests
51
55
 
52
56
  def initialize
57
+ @assigned = []
53
58
  @enabled = false
54
59
  @storage = :memory
55
60
  @storage_options = {}
@@ -112,6 +117,26 @@ module Profiler
112
117
  @tmp_path || default_tmp_path
113
118
  end
114
119
 
120
+ def enabled=(value)
121
+ @assigned |= [:enabled]
122
+ @enabled = value
123
+ end
124
+
125
+ def track_tests=(value)
126
+ @assigned |= [:track_tests]
127
+ @track_tests = value
128
+ end
129
+
130
+ # Sets one of RAILS_DEFAULTED to value unless the application assigned it, in
131
+ # config/application.rb for instance, which runs before the railtie's initializers.
132
+ def default(option, value)
133
+ raise ArgumentError, "#{option} has no Rails default" unless RAILS_DEFAULTED.include?(option)
134
+ return if @assigned.include?(option)
135
+
136
+ public_send("#{option}=", value)
137
+ @assigned.delete(option)
138
+ end
139
+
115
140
  def slave?
116
141
  !master_url.nil? && !master_url.empty?
117
142
  end
@@ -162,6 +187,7 @@ module Profiler
162
187
  end
163
188
 
164
189
  def storage=(value)
190
+ @assigned |= [:storage]
165
191
  @storage = value
166
192
  @storage_backend = nil
167
193
  end
@@ -8,11 +8,12 @@ module Profiler
8
8
  included do
9
9
  attr_accessor :profiler_parent_token
10
10
 
11
- before_enqueue do |job|
11
+ # Ahead of the application's callbacks, which may already be there when this is included.
12
+ before_enqueue(prepend: true) do |job|
12
13
  job.profiler_parent_token = Profiler::CurrentContext.token
13
14
  end
14
15
 
15
- around_perform do |job, block|
16
+ around_perform(prepend: true) do |job, block|
16
17
  Profiler::JobProfiler.profile(
17
18
  job_class: job.class.name,
18
19
  job_id: job.job_id,
@@ -6,27 +6,38 @@ module Profiler
6
6
  class Railtie < Rails::Railtie
7
7
  config.profiler = ActiveSupport::OrderedOptions.new
8
8
 
9
+ # Runs before the application's config/initializers, so that they override what it sets.
10
+ # The Rails defaults go only where config/application.rb, which runs earlier still, has not
11
+ # assigned the option, and config.profiler, also set there, is applied on top.
9
12
  initializer "profiler.set_configs" do |app|
10
- # Set default configuration for Rails environment
13
+ development_or_test = Rails.env.development? || Rails.env.test?
11
14
  Profiler.configure do |config|
12
- config.enabled = Rails.env.development? || Rails.env.test?
13
- config.storage = (Rails.env.development? || Rails.env.test?) ? :file : :memory
14
- config.tmp_path = Rails.root.join("tmp", "rails-profiler")
15
- config.track_tests = Rails.env.test?
15
+ config.default(:enabled, development_or_test)
16
+ config.default(:storage, development_or_test ? :file : :memory)
17
+ config.default(:track_tests, Rails.env.test?)
18
+
19
+ app.config.profiler.each do |key, value|
20
+ if config.respond_to?("#{key}=")
21
+ config.public_send("#{key}=", value)
22
+ else
23
+ Rails.logger&.warn("[Profiler] config.profiler.#{key} is not a profiler option, ignored")
24
+ end
25
+ end
16
26
  end
17
27
  end
18
28
 
29
+ # Always inserted here, before the application's initializers have decided `enabled`, so
30
+ # that the profiler keeps its place in the stack relative to the middlewares they insert;
31
+ # profiler.remove_disabled_middleware takes it out again once they have run.
19
32
  initializer "profiler.insert_middleware", before: :build_middleware_stack do |app|
20
- if Profiler.configuration.enabled
21
- require_relative "middleware/profiler_middleware"
33
+ require_relative "middleware/profiler_middleware"
22
34
 
23
- # Always inserted: it sets the framing headers of every profiler response, and its
24
- # CORS headers only when extension_cors_enabled is set.
25
- require_relative "middleware/cors_middleware"
26
- app.middleware.insert_before 0, Profiler::Middleware::CorsMiddleware
35
+ # It sets the framing headers of every profiler response, and its CORS headers only
36
+ # when extension_cors_enabled is set.
37
+ require_relative "middleware/cors_middleware"
38
+ app.middleware.insert_before 0, Profiler::Middleware::CorsMiddleware
27
39
 
28
- app.middleware.insert_before 0, Profiler::Middleware::ProfilerMiddleware
29
- end
40
+ app.middleware.insert_before 0, Profiler::Middleware::ProfilerMiddleware
30
41
  end
31
42
 
32
43
  initializer "profiler.load_collectors" do
@@ -52,6 +63,17 @@ module Profiler
52
63
  end
53
64
  end
54
65
 
66
+ # Everything below runs after the application's config/initializers, where `enabled` is
67
+ # decided, and before the middleware stack is built. An initializer declared without
68
+ # `after:` runs after the one declared before it, so these stay declared last, in order.
69
+ initializer "profiler.remove_disabled_middleware", after: :load_config_initializers do |app|
70
+ next if Profiler.configuration.enabled
71
+
72
+ # Rails applies every delete after the other middleware operations, whatever their order.
73
+ app.middleware.delete Profiler::Middleware::ProfilerMiddleware
74
+ app.middleware.delete Profiler::Middleware::CorsMiddleware
75
+ end
76
+
55
77
  initializer "profiler.setup_test_profiler" do
56
78
  next unless Profiler.configuration.enabled && Profiler.configuration.track_tests
57
79
 
@@ -68,16 +90,19 @@ module Profiler
68
90
 
69
91
  require_relative "job_profiler"
70
92
 
93
+ # This runs after the application's initializers: prepend, not add, keeps the profiler
94
+ # ahead of the middlewares and callbacks they install, so that a job's profile covers them.
95
+ # Sidekiq::Middleware::Chain#prepend is there from Sidekiq 3.3 (2014) to 8.1 at least.
71
96
  if defined?(Sidekiq)
72
97
  require_relative "instrumentation/sidekiq_middleware"
73
98
  Sidekiq.configure_server do |config|
74
99
  config.server_middleware do |chain|
75
- chain.add Profiler::Instrumentation::SidekiqMiddleware
100
+ chain.prepend Profiler::Instrumentation::SidekiqMiddleware
76
101
  end
77
102
  end
78
103
  Sidekiq.configure_client do |config|
79
104
  config.client_middleware do |chain|
80
- chain.add Profiler::Instrumentation::SidekiqClientMiddleware
105
+ chain.prepend Profiler::Instrumentation::SidekiqClientMiddleware
81
106
  end
82
107
  end
83
108
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Profiler
4
- VERSION = "0.30.13"
4
+ VERSION = "0.30.14"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.30.13
4
+ version: 0.30.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sébastien Duplessy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-04 00:00:00.000000000 Z
11
+ date: 2026-10-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails