rails_memory_profiler 0.3.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da1c19f27cafbf571c7f5fe0e724c56e305d81307c99c1d970fdc96777459888
4
- data.tar.gz: d95173a0c57ec1afefc7a13eed43e06b5fef53a8350a3b5b2955f42ad01c382f
3
+ metadata.gz: 0ecc5cf3944827bacd93b4ba2609cf46516c1a2ecf54ff922e1b36d36e7e1592
4
+ data.tar.gz: 50de3643fab494e8d03a494d4c776914c234469844b095deb0964efbf94036ce
5
5
  SHA512:
6
- metadata.gz: c34cfa6505349cae21f6e808c55bd8c682456809ac3052ed2d67ed72099ec72f4cfd890653c36cf580d15f92c9988b1a94ce95dfa679c1cda1fb4f2fefa51747
7
- data.tar.gz: e5e1c2f7194e48d82b0073aed382662f95ffb552e119993a25dd62a58285f5a89e31e600664928a7bcd515696a5abebc2f02d32d9a49df5a5124d7c38c5165b6
6
+ metadata.gz: '091da3ac58edfd24e7fb0c8090e782a9af30d08dd2f5d59054b9f8108704c99f2c7ac238def2004730c22a77442ece51375ed221694666b828b76cb589e8dd0c'
7
+ data.tar.gz: 8bd3e45989fe1cac7bb15b02304d8e846977fa643652d949f2b4ba683019074334678d364dd81cc7ab939f453c6418f6a6f8556142685cf00fb7c65675912416
data/README.md CHANGED
@@ -74,7 +74,7 @@ All options and their defaults:
74
74
  | `store_size` | `100` | Max reports in the ring buffer; oldest are evicted when full |
75
75
  | `dashboard_enabled` | `true` in development | Enable the dashboard endpoint |
76
76
  | `min_allocated_objects` | `0` | Skip requests that allocate fewer objects than this |
77
- | `ignore_paths` | `[]` | Paths to skip — strings (prefix) or regexes |
77
+ | `ignore_paths` | `[]` | Additional paths to skip — strings (prefix) or regexes (the dashboard's own mount path is auto-ignored) |
78
78
  | `ignore_controllers` | `[]` | Controller names to skip (e.g. `"rails/health"`) |
79
79
  | `detailed_reports` | `false` | Capture full `MemoryProfiler.report` breakdowns; requires `gem "memory_profiler"` in your Gemfile |
80
80
  | `detailed_sample_rate` | `10` | When `detailed_reports` is enabled, capture a full report every Nth profiled request |
@@ -88,7 +88,7 @@ Example:
88
88
  RailsMemoryProfiler.configure do |config|
89
89
  config.sample_rate = 5
90
90
  config.min_allocated_objects = 1_000
91
- config.ignore_paths = ["/rails/memory", "/up"]
91
+ config.ignore_paths = ["/up"] # dashboard mount path is auto-ignored
92
92
  config.ignore_controllers = ["rails/health"]
93
93
  config.notifiers = [RailsMemoryProfiler::Notifiers::Console.new]
94
94
  config.log_file = Rails.root.join("log/memory_profiler.jsonl")
@@ -98,11 +98,18 @@ end
98
98
  ### Test helpers
99
99
 
100
100
  ```ruby
101
- # Minitest / plain Ruby
101
+ # Plain Ruby / shared utility
102
102
  require "rails_memory_profiler/test_helper"
103
103
 
104
104
  count = RailsMemoryProfiler::TestHelper.capture_allocations { MyClass.new }
105
105
  RailsMemoryProfiler::TestHelper.assert_allocations_below(500) { MyClass.new }
106
+ # raises Minitest::Assertion when Minitest is loaded, RuntimeError otherwise
107
+
108
+ # Minitest — adds assert_allocates_fewer_than to all Minitest::Test subclasses
109
+ require "rails_memory_profiler/minitest_matchers"
110
+
111
+ assert_allocates_fewer_than(500) { MyClass.new }
112
+ assert_allocates_fewer_than(500, "MyClass allocates too much") { MyClass.new }
106
113
 
107
114
  # RSpec
108
115
  require "rails_memory_profiler/rspec_matchers"
@@ -2,6 +2,30 @@
2
2
  .rmp-header h1 { font-size: 1.4rem; font-weight: 600; }
3
3
  .rmp-header p { color: var(--muted); margin-top: 0.2rem; }
4
4
 
5
+ .rmp-header-row {
6
+ display: flex;
7
+ align-items: center;
8
+ justify-content: space-between;
9
+ gap: 1rem;
10
+ }
11
+
12
+ .rmp-btn-danger {
13
+ font-family: inherit;
14
+ font-size: 12px;
15
+ padding: 0.3rem 0.8rem;
16
+ border: 1px solid #dc3545;
17
+ border-radius: var(--radius);
18
+ background: transparent;
19
+ color: #dc3545;
20
+ cursor: pointer;
21
+ white-space: nowrap;
22
+ }
23
+
24
+ .rmp-btn-danger:hover {
25
+ background: #dc3545;
26
+ color: #fff;
27
+ }
28
+
5
29
  .rmp-empty { color: var(--muted); font-style: italic; margin-top: 1rem; }
6
30
  .rmp-summary { margin-bottom: 0.5rem; }
7
31
 
@@ -15,6 +15,11 @@ module RailsMemoryProfiler
15
15
  end
16
16
  end
17
17
 
18
+ def clear
19
+ ReportStore.clear
20
+ redirect_to reports_path
21
+ end
22
+
18
23
  def show
19
24
  @report = ReportStore.find(params[:id])
20
25
 
@@ -59,8 +59,8 @@
59
59
  %>
60
60
  <tr>
61
61
  <td class="rmp-compare-field"><%= label %></td>
62
- <td><%= number_with_delimiter(lv.is_a?(Float) ? lv : lv) %></td>
63
- <td><%= number_with_delimiter(rv.is_a?(Float) ? rv : rv) %></td>
62
+ <td><%= number_with_delimiter(lv.is_a?(Float) ? lv.round(2) : lv) %></td>
63
+ <td><%= number_with_delimiter(rv.is_a?(Float) ? rv.round(2) : rv) %></td>
64
64
  <td class="<%= delta_class %>"><%= delta_str %></td>
65
65
  </tr>
66
66
  <% end %>
@@ -1,6 +1,15 @@
1
1
  <div class="rmp-header">
2
- <h1>Memory Profiler</h1>
3
- <p><%= @reports.size %> request<%= "s" unless @reports.size == 1 %> captured</p>
2
+ <div class="rmp-header-row">
3
+ <div>
4
+ <h1>Memory Profiler</h1>
5
+ <p><%= @reports.size %> request<%= "s" unless @reports.size == 1 %> captured</p>
6
+ </div>
7
+ <% unless @reports.empty? %>
8
+ <%= button_to "Clear All", clear_reports_path, method: :delete,
9
+ class: "rmp-btn-danger",
10
+ form: { data: { turbo_confirm: "Clear all reports? This cannot be undone." } } %>
11
+ <% end %>
12
+ </div>
4
13
  </div>
5
14
 
6
15
  <div data-controller="filter compare" data-compare-path-value="<%= comparison_path %>">
data/config/routes.rb CHANGED
@@ -1,4 +1,8 @@
1
1
  RailsMemoryProfiler::Engine.routes.draw do
2
- resources :reports, only: [:index, :show]
3
- resource :comparison, only: [:show]
2
+ resources :reports, only: [:index, :show] do
3
+ collection do
4
+ delete :clear
5
+ end
6
+ end
7
+ resource :comparison, only: [:show]
4
8
  end
@@ -6,6 +6,21 @@ module RailsMemoryProfiler
6
6
  isolate_namespace RailsMemoryProfiler
7
7
  config.generators.api_only = true
8
8
 
9
+ class << self
10
+ def mount_path
11
+ @mount_path ||= begin
12
+ mounted = Rails.application.routes.routes.find do |route|
13
+ route.app.app == self rescue false
14
+ end
15
+ mounted&.path&.spec&.to_s&.gsub(/\([^)]*\)/, "")
16
+ end
17
+ end
18
+
19
+ def reset_mount_path!
20
+ @mount_path = nil
21
+ end
22
+ end
23
+
9
24
  initializer "rails_memory_profiler.assets" do |app|
10
25
  if app.config.respond_to?(:assets)
11
26
  app.config.assets.paths << root.join("app/javascript")
@@ -143,6 +143,9 @@ module RailsMemoryProfiler
143
143
  end
144
144
 
145
145
  def ignored_path?(path)
146
+ mount = RailsMemoryProfiler::Engine.mount_path
147
+ return true if mount && path.start_with?(mount)
148
+
146
149
  RailsMemoryProfiler.config.ignore_paths.any? do |pattern|
147
150
  pattern.is_a?(Regexp) ? pattern.match?(path) : path.start_with?(pattern.to_s)
148
151
  end
@@ -0,0 +1,15 @@
1
+ require "rails_memory_profiler/test_helper"
2
+
3
+ if defined?(Minitest)
4
+ module RailsMemoryProfiler
5
+ module MinitestMatchers
6
+ def assert_allocates_fewer_than(threshold, msg = nil, &block)
7
+ count = RailsMemoryProfiler::TestHelper.capture_allocations(&block)
8
+ message = msg || "Expected fewer than #{threshold} allocated objects but got #{count}"
9
+ assert count < threshold, message
10
+ end
11
+ end
12
+ end
13
+
14
+ Minitest::Test.include RailsMemoryProfiler::MinitestMatchers
15
+ end
@@ -15,7 +15,9 @@ module RailsMemoryProfiler
15
15
  count = capture_allocations(&block)
16
16
  return if count < threshold
17
17
 
18
- raise "Expected fewer than #{threshold} allocated objects but got #{count}"
18
+ message = "Expected fewer than #{threshold} allocated objects but got #{count}"
19
+ error_class = Object.const_defined?(:Minitest) ? Minitest::Assertion : RuntimeError
20
+ raise error_class, message
19
21
  end
20
22
  end
21
23
  end
@@ -1,3 +1,3 @@
1
1
  module RailsMemoryProfiler
2
- VERSION = "0.3.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -1,6 +1,5 @@
1
1
  require "rails_memory_profiler/version"
2
2
  require "rails_memory_profiler/configuration"
3
- require "rails_memory_profiler/request_context"
4
3
  require "rails_memory_profiler/report_store"
5
4
  require "rails_memory_profiler/notifiers"
6
5
  require "rails_memory_profiler/middleware"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_memory_profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuck Smith
@@ -71,7 +71,6 @@ files:
71
71
  - app/assets/stylesheets/rails_memory_profiler/_05_filters.css
72
72
  - app/assets/stylesheets/rails_memory_profiler/_06_breakdowns.css
73
73
  - app/assets/stylesheets/rails_memory_profiler/_07_compare.css
74
- - app/controllers/rails_memory_profiler/application_controller.rb
75
74
  - app/controllers/rails_memory_profiler/base_controller.rb
76
75
  - app/controllers/rails_memory_profiler/comparisons_controller.rb
77
76
  - app/controllers/rails_memory_profiler/reports_controller.rb
@@ -81,9 +80,6 @@ files:
81
80
  - app/javascript/rails_memory_profiler/controllers/compare_controller.js
82
81
  - app/javascript/rails_memory_profiler/controllers/filter_controller.js
83
82
  - app/javascript/rails_memory_profiler/controllers/index.js
84
- - app/jobs/rails_memory_profiler/application_job.rb
85
- - app/mailers/rails_memory_profiler/application_mailer.rb
86
- - app/models/rails_memory_profiler/application_record.rb
87
83
  - app/views/layouts/rails_memory_profiler/application.html.erb
88
84
  - app/views/rails_memory_profiler/comparisons/show.html.erb
89
85
  - app/views/rails_memory_profiler/reports/index.html.erb
@@ -96,17 +92,16 @@ files:
96
92
  - lib/rails_memory_profiler/configuration.rb
97
93
  - lib/rails_memory_profiler/engine.rb
98
94
  - lib/rails_memory_profiler/middleware.rb
95
+ - lib/rails_memory_profiler/minitest_matchers.rb
99
96
  - lib/rails_memory_profiler/notifiers.rb
100
97
  - lib/rails_memory_profiler/notifiers/console.rb
101
98
  - lib/rails_memory_profiler/notifiers/file_logger.rb
102
99
  - lib/rails_memory_profiler/notifiers/logger.rb
103
100
  - lib/rails_memory_profiler/notifiers/stdout.rb
104
101
  - lib/rails_memory_profiler/report_store.rb
105
- - lib/rails_memory_profiler/request_context.rb
106
102
  - lib/rails_memory_profiler/rspec_matchers.rb
107
103
  - lib/rails_memory_profiler/test_helper.rb
108
104
  - lib/rails_memory_profiler/version.rb
109
- - lib/tasks/rails_memory_profiler_tasks.rake
110
105
  homepage: https://github.com/eclectic-coding/rails_memory_profiler
111
106
  licenses:
112
107
  - MIT
@@ -1,4 +0,0 @@
1
- module RailsMemoryProfiler
2
- class ApplicationController < ActionController::API
3
- end
4
- end
@@ -1,4 +0,0 @@
1
- module RailsMemoryProfiler
2
- class ApplicationJob < ActiveJob::Base
3
- end
4
- end
@@ -1,6 +0,0 @@
1
- module RailsMemoryProfiler
2
- class ApplicationMailer < ActionMailer::Base
3
- default from: "from@example.com"
4
- layout "mailer"
5
- end
6
- end
@@ -1,5 +0,0 @@
1
- module RailsMemoryProfiler
2
- class ApplicationRecord < ActiveRecord::Base
3
- self.abstract_class = true
4
- end
5
- end
@@ -1,22 +0,0 @@
1
- module RailsMemoryProfiler
2
- module RequestContext
3
- class << self
4
- def set(controller:, action:, path:, method:)
5
- Thread.current[:rails_memory_profiler_context] = {
6
- controller: controller,
7
- action: action,
8
- path: path,
9
- method: method
10
- }
11
- end
12
-
13
- def current
14
- Thread.current[:rails_memory_profiler_context] || {}
15
- end
16
-
17
- def clear
18
- Thread.current[:rails_memory_profiler_context] = nil
19
- end
20
- end
21
- end
22
- end
@@ -1,4 +0,0 @@
1
- # desc "Explaining what the task does"
2
- # task :rails_memory_profiler do
3
- # # Task goes here
4
- # end