rack-mini-profiler 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +64 -68
- data/lib/generators/rack_mini_profiler/USAGE +9 -0
- data/lib/generators/rack_mini_profiler/install_generator.rb +13 -0
- data/lib/generators/{rack_profiler/templates/rack_profiler.rb → rack_mini_profiler/templates/rack_mini_profiler.rb} +1 -1
- data/lib/generators/rack_profiler/install_generator.rb +6 -3
- data/lib/mini_profiler/config.rb +3 -1
- data/lib/mini_profiler/storage/file_store.rb +2 -0
- data/lib/mini_profiler/storage/memory_store.rb +2 -0
- data/lib/mini_profiler/storage/redis_store.rb +1 -0
- data/lib/mini_profiler/storage.rb +7 -0
- data/lib/mini_profiler/timer_struct/base.rb +2 -0
- data/lib/mini_profiler/timer_struct/sql.rb +2 -0
- data/lib/mini_profiler/timer_struct.rb +8 -0
- data/lib/mini_profiler/version.rb +1 -1
- data/lib/{mini_profiler/profiler.rb → mini_profiler.rb} +90 -60
- data/lib/patches/net_patches.rb +18 -17
- data/lib/rack-mini-profiler.rb +1 -24
- data/rack-mini-profiler.gemspec +2 -2
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7544df4d22f5f615b146fb0d63f18098ffd702ac9dec966d8040187f2e8302b9
|
4
|
+
data.tar.gz: 7c39c41a96205c8c7fbd69765ab5f1e0a3a3a37950055fc58d0f27f4a0591e0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e3f5f9a51fc5395dda4a7e793903f998513499d850aeb291fe036171a78617d11c3d8cd6fef57d1144359aa4992055ad54ba878075896c3d0280c426a84e3be
|
7
|
+
data.tar.gz: c4e353c8442db93f29d11d04e2724e6c3f8dacaaf082210acbbb7d47655ffc3a6b5297079750e305fe9f1cd3e7efb1d806aef0ec68bbc1a8e40a0f958de0ec52
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 3.1.0 - 2023-04-11
|
4
|
+
|
5
|
+
- [FEATURE] The query parameter that RMP uses (by default, pp) is now configurable [#553](https://github.com/MiniProfiler/rack-mini-profiler/pull/553)
|
6
|
+
- [FEATURE] You can now opt-out of the Net::HTTP patch by using RACK_MINI_PROFILER_PATCH_NET_HTTP="false"
|
7
|
+
- [FIX] Error responses now include header values from the app, and stackprof not installed message now has correct content [#547](https://github.com/MiniProfiler/rack-mini-profiler/pull/547)
|
8
|
+
- [FIX] RMP pages now have more valid HTML, with title elements [#562](https://github.com/MiniProfiler/rack-mini-profiler/pull/562)
|
9
|
+
- [BREAKING CHANGE] Ruby 2.4 and Ruby 2.5 are no longer supported.
|
10
|
+
- [FIX] Now works with apps that don't otherwise require erb [#531](https://github.com/MiniProfiler/rack-mini-profiler/pull/531)
|
11
|
+
- [DOCS] Added Heroku Redis instructions
|
12
|
+
- [DEPRECATION] We are changing the name of the generators to `rack_mini_profiler`, e.g. `rack_mini_profiler:install` [#550](https://github.com/MiniProfiler/rack-mini-profiler/pull/550)
|
13
|
+
|
3
14
|
## 3.0.0 - 2022-02-24
|
4
15
|
|
5
16
|
- PERF: Improve snapshots page performance (#518) (introduces breaking changes to the API of `AbstractStore`, `MemoryStore` and `RedisStore`, and removes the `snapshots_limit` config option.)
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# rack-mini-profiler
|
2
2
|
|
3
|
-
Middleware that displays speed badge for every
|
3
|
+
Middleware that displays speed badge for every HTML page, along with (optional) flamegraphs and memory profiling. Designed to work both in production and in development.
|
4
|
+
|
5
|
+
![Screenshot 2023-04-05 at 3 13 52 PM](https://user-images.githubusercontent.com/845662/229996538-0f2d9c48-23d9-4d53-a1de-8b4c84c87fbd.png)
|
4
6
|
|
5
7
|
#### Features
|
6
8
|
|
@@ -27,7 +29,7 @@ If you feel like taking on any of this start an issue and update us on your prog
|
|
27
29
|
|
28
30
|
## Installation
|
29
31
|
|
30
|
-
Install/add to Gemfile in Ruby 2.
|
32
|
+
Install/add to Gemfile in Ruby 2.6+
|
31
33
|
|
32
34
|
```ruby
|
33
35
|
gem 'rack-mini-profiler'
|
@@ -101,7 +103,7 @@ be loaded outright, and an attempt to re-initialize it manually will raise an ex
|
|
101
103
|
Then run the generator which will set up rack-mini-profiler in development:
|
102
104
|
|
103
105
|
```bash
|
104
|
-
bundle exec rails g
|
106
|
+
bundle exec rails g rack_mini_profiler:install
|
105
107
|
```
|
106
108
|
|
107
109
|
#### Rack Builder
|
@@ -164,11 +166,19 @@ export RACK_MINI_PROFILER_PATCH="false"
|
|
164
166
|
# initializers/rack_profiler.rb: SqlPatches.patch %w(mongo)
|
165
167
|
```
|
166
168
|
|
169
|
+
#### Patching Net::HTTP
|
170
|
+
|
171
|
+
Other than databases, `rack-mini-profiler` applies a patch to `Net::HTTP`. You may want to disable this patch:
|
172
|
+
|
173
|
+
```bash
|
174
|
+
export RACK_MINI_PROFILER_PATCH_NET_HTTP="false"
|
175
|
+
```
|
176
|
+
|
167
177
|
### Flamegraphs
|
168
178
|
|
169
179
|
To generate [flamegraphs](http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-miniprofiler), add the [**stackprof**](https://rubygems.org/gems/stackprof) gem to your Gemfile.
|
170
180
|
|
171
|
-
Then, to view the flamegraph as a direct HTML response from your request, just visit any page in your app with `?pp=flamegraph` appended to the URL.
|
181
|
+
Then, to view the flamegraph as a direct HTML response from your request, just visit any page in your app with `?pp=flamegraph` appended to the URL.
|
172
182
|
|
173
183
|
Conversely, if you want your regular response instead (which is specially useful for JSON and/or XHR requests), just append the `?pp=async-flamegraph` parameter to your request/fetch URL; the request will then return as normal, and the flamegraph data will be stored for later *async* viewing, both for this request and for all subsequent requests made by this page (based on the `REFERER` header). For viewing these async flamegraphs, use the 'flamegraph' link that will appear inside the MiniProfiler UI for these requests.
|
174
184
|
|
@@ -406,39 +416,40 @@ Rack::MiniProfiler.config.start_hidden = true
|
|
406
416
|
```
|
407
417
|
The available configuration options are:
|
408
418
|
|
409
|
-
Option|Default|Description
|
410
|
-
|
411
|
-
pre_authorize_cb|Rails: dev only<br>Rack: always on|A lambda callback that returns true to make mini_profiler visible on a given request.
|
412
|
-
position
|
413
|
-
skip_paths
|
414
|
-
skip_schema_queries|Rails dev: `true`<br>Othwerwise: `false
|
415
|
-
auto_inject
|
416
|
-
backtrace_ignores
|
417
|
-
backtrace_includes|Rails: `[/^\/?(app\|config\|lib\|test)/]`<br>Rack: `[]
|
418
|
-
backtrace_remove|rails: `Rails.root`<br>Rack: `nil
|
419
|
-
toggle_shortcut|Alt+P|Keyboard shortcut to toggle the mini_profiler's visibility. See [jquery.hotkeys](https://github.com/jeresig/jquery.hotkeys).
|
420
|
-
start_hidden
|
421
|
-
backtrace_threshold_ms
|
422
|
-
flamegraph_sample_rate
|
423
|
-
flamegraph_mode
|
424
|
-
base_url_path
|
425
|
-
cookie_path
|
426
|
-
collapse_results
|
427
|
-
max_traces_to_show|20|Maximum number of mini profiler timing blocks to show on one page
|
428
|
-
html_container
|
429
|
-
show_total_sql_count
|
430
|
-
enable_advanced_debugging_tools
|
431
|
-
assets_url
|
432
|
-
snapshot_every_n_requests
|
433
|
-
max_snapshot_groups
|
434
|
-
max_snapshots_per_group
|
435
|
-
snapshot_hidden_custom_fields
|
436
|
-
snapshots_transport_destination_url
|
437
|
-
snapshots_transport_auth_key
|
438
|
-
snapshots_redact_sql_queries
|
439
|
-
snapshots_transport_gzip_requests
|
440
|
-
content_security_policy_nonce|Rails: Current nonce<br>Rack: nil|Set the content security policy nonce to use when inserting MiniProfiler's script block.
|
441
|
-
enable_hotwire_turbo_drive_support| `false`
|
419
|
+
Option | Default | Description
|
420
|
+
------------------------------------|---------------------------------------------------------|------------------------
|
421
|
+
pre_authorize_cb | Rails: dev only<br>Rack: always on | A lambda callback that returns true to make mini_profiler visible on a given request.
|
422
|
+
position | `'top-left'` | Display mini_profiler on `'top-right'`, `'top-left'`, `'bottom-right'` or `'bottom-left'`.
|
423
|
+
skip_paths | `[]` | An array of paths that skip profiling. Both `String` and `Regexp` are acceptable in the array.
|
424
|
+
skip_schema_queries | Rails dev: `true`<br>Othwerwise: `false` | `true` to skip schema queries.
|
425
|
+
auto_inject | `true` | `true` to inject the miniprofiler script in the page.
|
426
|
+
backtrace_ignores | `[]` | Regexes of lines to be removed from backtraces.
|
427
|
+
backtrace_includes | Rails: `[/^\/?(app\|config\|lib\|test)/]`<br>Rack: `[]` | Regexes of lines to keep in backtraces.
|
428
|
+
backtrace_remove | rails: `Rails.root`<br>Rack: `nil` | A string or regex to remove part of each line in the backtrace.
|
429
|
+
toggle_shortcut | Alt+P | Keyboard shortcut to toggle the mini_profiler's visibility. See [jquery.hotkeys](https://github.com/jeresig/jquery.hotkeys).
|
430
|
+
start_hidden | `false` | `false` to make mini_profiler visible on page load.
|
431
|
+
backtrace_threshold_ms | `0` | Minimum SQL query elapsed time before a backtrace is recorded.
|
432
|
+
flamegraph_sample_rate | `0.5` | How often to capture stack traces for flamegraphs in milliseconds.
|
433
|
+
flamegraph_mode | `:wall` | The [StackProf mode](https://github.com/tmm1/stackprof#all-options) to pass to `StackProf.run`.
|
434
|
+
base_url_path | `'/mini-profiler-resources/'` | Path for assets; added as a prefix when naming assets and sought when responding to requests.
|
435
|
+
cookie_path | `'/'` | Set-Cookie header path for profile cookie
|
436
|
+
collapse_results | `true` | If multiple timing results exist in a single page, collapse them till clicked.
|
437
|
+
max_traces_to_show | 20 | Maximum number of mini profiler timing blocks to show on one page
|
438
|
+
html_container | `body` | The HTML container (as a jQuery selector) to inject the mini_profiler UI into
|
439
|
+
show_total_sql_count | `false` | Displays the total number of SQL executions.
|
440
|
+
enable_advanced_debugging_tools | `false` | Enables sensitive debugging tools that can be used via the UI. In production we recommend keeping this disabled as memory and environment debugging tools can expose contents of memory that may contain passwords. Defaults to `true` in development.
|
441
|
+
assets_url | `nil` | See the "Register MiniProfiler's assets in the Rails assets pipeline" section above.
|
442
|
+
snapshot_every_n_requests | `-1` | Determines how frequently snapshots are taken. See the "Snapshots Sampling" above for more details.
|
443
|
+
max_snapshot_groups | `50` | Determines how many snapshot groups Mini Profiler is allowed to keep.
|
444
|
+
max_snapshots_per_group | `15` | Determines how many snapshots per group Mini Profiler is allowed to keep.
|
445
|
+
snapshot_hidden_custom_fields | `[]` | Each snapshot custom field will have a dedicated column in the UI by default. Use this config to exclude certain custom fields from having their own columns.
|
446
|
+
snapshots_transport_destination_url | `nil` | Set this config to a valid URL to enable snapshots transporter which will `POST` snapshots to the given URL. The transporter requires `snapshots_transport_auth_key` config to be set as well.
|
447
|
+
snapshots_transport_auth_key | `nil` | `POST` requests made by the snapshots transporter to the destination URL will have a `Mini-Profiler-Transport-Auth` header with the value of this config. Make sure you use a secure and random key for this config.
|
448
|
+
snapshots_redact_sql_queries | `true` | When this is true, SQL queries will be redacted from sampling snapshots, but the backtrace and duration of each SQL query will be saved with the snapshot to keep debugging performance issues possible.
|
449
|
+
snapshots_transport_gzip_requests | `false` | Make the snapshots transporter gzip the requests it makes to `snapshots_transport_destination_url`.
|
450
|
+
content_security_policy_nonce | Rails: Current nonce<br>Rack: nil | Set the content security policy nonce to use when inserting MiniProfiler's script block.
|
451
|
+
enable_hotwire_turbo_drive_support | `false` | Enable support for Hotwire TurboDrive page transitions.
|
452
|
+
profile_parameter | `'pp'` | The query parameter used to interact with this gem.
|
442
453
|
|
443
454
|
### Using MiniProfiler with `Rack::Deflate` middleware
|
444
455
|
|
@@ -448,41 +459,26 @@ which means it will run after `Rack::Deflate` on response processing. To prevent
|
|
448
459
|
HTML in already compressed response body MiniProfiler will suppress compression by setting
|
449
460
|
`identity` encoding in `Accept-Encoding` request header.
|
450
461
|
|
451
|
-
|
452
|
-
|
453
|
-
If you include the query string `pp=help` at the end of your request you will see the various options available. You can use these options to extend or contract the amount of diagnostics rack-mini-profiler gathers.
|
454
|
-
|
455
|
-
|
456
|
-
## Rails 2.X support
|
462
|
+
### Using MiniProfiler with Heroku Redis
|
457
463
|
|
458
|
-
|
459
|
-
|
460
|
-
Add the following code to your environment.rb (or just in a specific environment such as development.rb) for initialization and configuration of MiniProfiler.
|
464
|
+
If you are using Heroku Redis, you may need to add the following to your `config/initializers/mini_profiler.rb`, in order to get Mini Profiler to work:
|
461
465
|
|
462
466
|
```ruby
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
tmp = Rails.root.to_s + "/tmp/miniprofiler"
|
470
|
-
FileUtils.mkdir_p(tmp) unless File.exist?(tmp)
|
471
|
-
c.storage_options = {:path => tmp}
|
472
|
-
c.storage = ::Rack::MiniProfiler::FileStore
|
473
|
-
config.middleware.use(::Rack::MiniProfiler)
|
474
|
-
::Rack::MiniProfiler.profile_method(ActionController::Base, :process) {|action| "Executing action: #{action}"}
|
475
|
-
::Rack::MiniProfiler.profile_method(ActionView::Template, :render) {|x,y| "Rendering: #{path_without_format_and_extension}"}
|
476
|
-
|
477
|
-
# monkey patch away an activesupport and json_pure incompatability
|
478
|
-
# http://pivotallabs.com/users/alex/blog/articles/1332-monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8
|
479
|
-
if JSON.const_defined?(:Pure)
|
480
|
-
class JSON::Pure::Generator::State
|
481
|
-
include ActiveSupport::CoreExtensions::Hash::Except
|
482
|
-
end
|
467
|
+
if Rails.env.production?
|
468
|
+
Rack::MiniProfiler.config.storage_options = {
|
469
|
+
url: ENV["REDIS_URL"],
|
470
|
+
ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE }
|
471
|
+
}
|
472
|
+
Rack::MiniProfiler.config.storage = Rack::MiniProfiler::RedisStore
|
483
473
|
end
|
484
474
|
```
|
485
475
|
|
476
|
+
The above code snippet is [Heroku's officially suggested workaround](https://help.heroku.com/HC0F8CUS/redis-connection-issues).
|
477
|
+
|
478
|
+
## Special query strings
|
479
|
+
|
480
|
+
If you include the query string `pp=help` at the end of your request you will see the various options available. You can use these options to extend or contract the amount of diagnostics rack-mini-profiler gathers.
|
481
|
+
|
486
482
|
## Development
|
487
483
|
|
488
484
|
If you want to contribute to this project, that's great, thank you! You can run the following rake task:
|
@@ -501,8 +497,8 @@ Make sure to prepend `bundle exec` before any Rake tasks you run.
|
|
501
497
|
You need Memcached and Redis services running for the specs.
|
502
498
|
|
503
499
|
```
|
504
|
-
$ rake build
|
505
|
-
$ rake spec
|
500
|
+
$ bundle exec rake build
|
501
|
+
$ bundle exec rake spec
|
506
502
|
```
|
507
503
|
|
508
504
|
## Licence
|
@@ -0,0 +1,9 @@
|
|
1
|
+
Description:
|
2
|
+
Generates an initializer for rack-mini-profiler. Use an initializer when manually
|
3
|
+
requiring rack-mini-profiler in your application (using require: false in your Gemfile).
|
4
|
+
|
5
|
+
Example:
|
6
|
+
`bin/rails generate rack_mini_profiler:install`
|
7
|
+
|
8
|
+
This generates a an initializer that requires and initializes
|
9
|
+
rack-mini-profiler in development mode.
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RackMiniProfiler
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
7
|
+
|
8
|
+
def create_initializer_file
|
9
|
+
copy_file "rack_mini_profiler.rb", "config/initializers/rack_mini_profiler.rb"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,12 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "generators/rack_mini_profiler/install_generator"
|
4
|
+
|
3
5
|
module RackProfiler
|
4
6
|
module Generators
|
5
|
-
class InstallGenerator < ::
|
6
|
-
source_root File.expand_path("templates", __dir__)
|
7
|
+
class InstallGenerator < RackMiniProfiler::Generators::InstallGenerator
|
8
|
+
source_root File.expand_path("../rack_mini_profiler/templates", __dir__)
|
7
9
|
|
8
10
|
def create_initializer_file
|
9
|
-
|
11
|
+
warn("bin/rails generate rack_profiler:install is deprecated. Please use rack_mini_profiler:install instead.")
|
12
|
+
super
|
10
13
|
end
|
11
14
|
end
|
12
15
|
end
|
data/lib/mini_profiler/config.rb
CHANGED
@@ -62,6 +62,8 @@ module Rack
|
|
62
62
|
@snapshots_transport_gzip_requests = false
|
63
63
|
@enable_hotwire_turbo_drive_support = false
|
64
64
|
|
65
|
+
@profile_parameter = "pp"
|
66
|
+
|
65
67
|
self
|
66
68
|
}
|
67
69
|
end
|
@@ -74,7 +76,7 @@ module Rack
|
|
74
76
|
:storage_options, :user_provider, :enable_advanced_debugging_tools,
|
75
77
|
:skip_sql_param_names, :suppress_encoding, :max_sql_param_length,
|
76
78
|
:content_security_policy_nonce, :enable_hotwire_turbo_drive_support,
|
77
|
-
:flamegraph_mode
|
79
|
+
:flamegraph_mode, :profile_parameter
|
78
80
|
|
79
81
|
# ui accessors
|
80
82
|
attr_accessor :collapse_results, :max_traces_to_show, :position,
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mini_profiler/timer_struct/base'
|
4
|
+
require 'mini_profiler/timer_struct/page'
|
5
|
+
require 'mini_profiler/timer_struct/sql'
|
6
|
+
require 'mini_profiler/timer_struct/custom'
|
7
|
+
require 'mini_profiler/timer_struct/client'
|
8
|
+
require 'mini_profiler/timer_struct/request'
|
@@ -1,6 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'cgi'
|
4
|
+
require 'json'
|
5
|
+
require 'erb'
|
6
|
+
|
7
|
+
require 'mini_profiler/timer_struct'
|
8
|
+
require 'mini_profiler/storage'
|
9
|
+
require 'mini_profiler/config'
|
10
|
+
require 'mini_profiler/profiling_methods'
|
11
|
+
require 'mini_profiler/context'
|
12
|
+
require 'mini_profiler/client_settings'
|
13
|
+
require 'mini_profiler/gc_profiler'
|
14
|
+
require 'mini_profiler/snapshots_transporter'
|
4
15
|
|
5
16
|
module Rack
|
6
17
|
class MiniProfiler
|
@@ -27,11 +38,11 @@ module Rack
|
|
27
38
|
end
|
28
39
|
|
29
40
|
def resources_root
|
30
|
-
@resources_root ||= ::File.expand_path("
|
41
|
+
@resources_root ||= ::File.expand_path("../html", __FILE__)
|
31
42
|
end
|
32
43
|
|
33
44
|
def share_template
|
34
|
-
@share_template ||= ERB.new(::File.read(::File.expand_path("
|
45
|
+
@share_template ||= ERB.new(::File.read(::File.expand_path("html/share.html", ::File.dirname(__FILE__))))
|
35
46
|
end
|
36
47
|
|
37
48
|
def current
|
@@ -223,7 +234,7 @@ module Rack
|
|
223
234
|
# Someone (e.g. Rails engine) could change the SCRIPT_NAME so we save it
|
224
235
|
env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME'] = ENV['PASSENGER_BASE_URI'] || env['SCRIPT_NAME']
|
225
236
|
|
226
|
-
skip_it =
|
237
|
+
skip_it = /#{@config.profile_parameter}=skip/.match?(query_string) || (
|
227
238
|
@config.skip_paths &&
|
228
239
|
@config.skip_paths.any? do |p|
|
229
240
|
if p.instance_of?(String)
|
@@ -255,11 +266,11 @@ module Rack
|
|
255
266
|
|
256
267
|
has_disable_cookie = client_settings.disable_profiling?
|
257
268
|
# manual session disable / enable
|
258
|
-
if query_string =~
|
269
|
+
if query_string =~ /#{@config.profile_parameter}=disable/ || has_disable_cookie
|
259
270
|
skip_it = true
|
260
271
|
end
|
261
272
|
|
262
|
-
if query_string =~
|
273
|
+
if query_string =~ /#{@config.profile_parameter}=enable/
|
263
274
|
skip_it = false
|
264
275
|
config.enabled = true
|
265
276
|
end
|
@@ -273,22 +284,24 @@ module Rack
|
|
273
284
|
end
|
274
285
|
|
275
286
|
# profile gc
|
276
|
-
if query_string =~
|
287
|
+
if query_string =~ /#{@config.profile_parameter}=profile-gc/
|
277
288
|
return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
|
278
289
|
current.measure = false if current
|
279
290
|
return client_settings.handle_cookie(Rack::MiniProfiler::GCProfiler.new.profile_gc(@app, env))
|
280
291
|
end
|
281
292
|
|
282
293
|
# profile memory
|
283
|
-
if query_string =~
|
294
|
+
if query_string =~ /#{@config.profile_parameter}=profile-memory/
|
284
295
|
return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
|
285
296
|
|
286
297
|
unless defined?(MemoryProfiler) && MemoryProfiler.respond_to?(:report)
|
287
298
|
message = "Please install the memory_profiler gem and require it: add gem 'memory_profiler' to your Gemfile"
|
288
|
-
|
299
|
+
status, headers, body = @app.call(env)
|
289
300
|
body.close if body.respond_to? :close
|
290
301
|
|
291
|
-
return client_settings.handle_cookie(
|
302
|
+
return client_settings.handle_cookie(
|
303
|
+
text_result(message, status: 500, headers: headers)
|
304
|
+
)
|
292
305
|
end
|
293
306
|
|
294
307
|
query_params = Rack::Utils.parse_nested_query(query_string)
|
@@ -308,12 +321,12 @@ module Rack
|
|
308
321
|
|
309
322
|
MiniProfiler.create_current(env, @config)
|
310
323
|
|
311
|
-
if query_string =~
|
324
|
+
if query_string =~ /#{@config.profile_parameter}=normal-backtrace/
|
312
325
|
client_settings.backtrace_level = ClientSettings::BACKTRACE_DEFAULT
|
313
|
-
elsif query_string =~
|
326
|
+
elsif query_string =~ /#{@config.profile_parameter}=no-backtrace/
|
314
327
|
current.skip_backtrace = true
|
315
328
|
client_settings.backtrace_level = ClientSettings::BACKTRACE_NONE
|
316
|
-
elsif query_string =~
|
329
|
+
elsif query_string =~ /#{@config.profile_parameter}=full-backtrace/ || client_settings.backtrace_full?
|
317
330
|
current.full_backtrace = true
|
318
331
|
client_settings.backtrace_level = ClientSettings::BACKTRACE_FULL
|
319
332
|
elsif client_settings.backtrace_none?
|
@@ -322,7 +335,7 @@ module Rack
|
|
322
335
|
|
323
336
|
flamegraph = nil
|
324
337
|
|
325
|
-
trace_exceptions = query_string =~
|
338
|
+
trace_exceptions = query_string =~ /#{@config.profile_parameter}=trace-exceptions/ && defined? TracePoint
|
326
339
|
status, headers, body, exceptions, trace = nil
|
327
340
|
|
328
341
|
if trace_exceptions
|
@@ -347,12 +360,7 @@ module Rack
|
|
347
360
|
env['HTTP_ACCEPT_ENCODING'] = 'identity' if config.suppress_encoding
|
348
361
|
|
349
362
|
if query_string =~ /pp=(async-)?flamegraph/ || env['HTTP_REFERER'] =~ /pp=async-flamegraph/
|
350
|
-
|
351
|
-
headers = { 'Content-Type' => 'text/html' }
|
352
|
-
message = "Please install the stackprof gem and require it: add gem 'stackprof' to your Gemfile"
|
353
|
-
body.close if body.respond_to? :close
|
354
|
-
return client_settings.handle_cookie([500, headers, message])
|
355
|
-
else
|
363
|
+
if defined?(StackProf) && StackProf.respond_to?(:run)
|
356
364
|
# do not sully our profile with mini profiler timings
|
357
365
|
current.measure = false
|
358
366
|
match_data = query_string.match(/flamegraph_sample_rate=([\d\.]+)/)
|
@@ -379,12 +387,24 @@ module Rack
|
|
379
387
|
) do
|
380
388
|
status, headers, body = @app.call(env)
|
381
389
|
end
|
390
|
+
else
|
391
|
+
message = "Please install the stackprof gem and require it: add gem 'stackprof' to your Gemfile"
|
392
|
+
status, headers, body = @app.call(env)
|
393
|
+
body.close if body.respond_to? :close
|
394
|
+
|
395
|
+
return client_settings.handle_cookie(
|
396
|
+
text_result(message, status: status, headers: headers)
|
397
|
+
)
|
382
398
|
end
|
383
399
|
elsif path == '/rack-mini-profiler/requests'
|
384
400
|
blank_page_html = <<~HTML
|
401
|
+
<!DOCTYPE html>
|
385
402
|
<html>
|
386
|
-
<head
|
387
|
-
|
403
|
+
<head>
|
404
|
+
<title>Rack::MiniProfiler Requests</title>
|
405
|
+
</head>
|
406
|
+
<body>
|
407
|
+
</body>
|
388
408
|
</html>
|
389
409
|
HTML
|
390
410
|
|
@@ -419,19 +439,19 @@ module Rack
|
|
419
439
|
return client_settings.handle_cookie(dump_exceptions exceptions)
|
420
440
|
end
|
421
441
|
|
422
|
-
if query_string =~
|
442
|
+
if query_string =~ /#{@config.profile_parameter}=env/
|
423
443
|
return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
|
424
444
|
body.close if body.respond_to? :close
|
425
445
|
return client_settings.handle_cookie(dump_env env)
|
426
446
|
end
|
427
447
|
|
428
|
-
if query_string =~
|
448
|
+
if query_string =~ /#{@config.profile_parameter}=analyze-memory/
|
429
449
|
return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
|
430
450
|
body.close if body.respond_to? :close
|
431
451
|
return client_settings.handle_cookie(analyze_memory)
|
432
452
|
end
|
433
453
|
|
434
|
-
if query_string =~
|
454
|
+
if query_string =~ /#{@config.profile_parameter}=help/
|
435
455
|
body.close if body.respond_to? :close
|
436
456
|
return client_settings.handle_cookie(help(client_settings, env))
|
437
457
|
end
|
@@ -440,7 +460,7 @@ module Rack
|
|
440
460
|
page_struct[:user] = user(env)
|
441
461
|
page_struct[:root].record_time((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000)
|
442
462
|
|
443
|
-
if flamegraph && query_string =~
|
463
|
+
if flamegraph && query_string =~ /#{@config.profile_parameter}=flamegraph/
|
444
464
|
body.close if body.respond_to? :close
|
445
465
|
return client_settings.handle_cookie(self.flamegraph(flamegraph, path))
|
446
466
|
elsif flamegraph # async-flamegraph
|
@@ -538,7 +558,7 @@ module Rack
|
|
538
558
|
|
539
559
|
body << "\nBacktraces\n"
|
540
560
|
exceptions.each_with_index do |e, i|
|
541
|
-
body << "##{i + 1}: #{e.class} - \"#{e.message}\"\n #{e.backtrace.join("\n ")}\n\n"
|
561
|
+
body << "##{i + 1}: #{e.class} - \"#{e.message.lines.first.chomp}\"\n #{e.backtrace.join("\n ")}\n\n"
|
542
562
|
end
|
543
563
|
end
|
544
564
|
text_result(body)
|
@@ -638,45 +658,51 @@ module Rack
|
|
638
658
|
text_result(body)
|
639
659
|
end
|
640
660
|
|
641
|
-
def text_result(body)
|
642
|
-
headers = {
|
643
|
-
[
|
661
|
+
def text_result(body, status: 200, headers: nil)
|
662
|
+
headers = (headers || {}).merge('Content-Type' => 'text/plain; charset=utf-8')
|
663
|
+
[status, headers, [body]]
|
644
664
|
end
|
645
665
|
|
646
666
|
def make_link(postfix, env)
|
647
|
-
link = env["PATH_INFO"] + "?" + env["QUERY_STRING"].sub("
|
648
|
-
"
|
667
|
+
link = env["PATH_INFO"] + "?" + env["QUERY_STRING"].sub("#{@config.profile_parameter}=help", "#{@config.profile_parameter}=#{postfix}")
|
668
|
+
"#{@config.profile_parameter}=<a href='#{ERB::Util.html_escape(link)}'>#{postfix}</a>"
|
649
669
|
end
|
650
670
|
|
651
671
|
def help(client_settings, env)
|
652
672
|
headers = { 'Content-Type' => 'text/html' }
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
"
|
678
|
-
|
679
|
-
|
673
|
+
html = <<~HTML
|
674
|
+
<!DOCTYPE html>
|
675
|
+
<html>
|
676
|
+
<head>
|
677
|
+
<title>Rack::MiniProfiler Help</title>
|
678
|
+
</head>
|
679
|
+
<body>
|
680
|
+
<pre style='line-height: 30px; font-size: 16px'>
|
681
|
+
This is the help menu of the <a href='#{Rack::MiniProfiler::SOURCE_CODE_URI}'>rack-mini-profiler</a> gem, append the following to your query string for more options:
|
682
|
+
|
683
|
+
#{make_link "help", env} : display this screen
|
684
|
+
#{make_link "env", env} : display the rack environment
|
685
|
+
#{make_link "skip", env} : skip mini profiler for this request
|
686
|
+
#{make_link "no-backtrace", env} #{"(*) " if client_settings.backtrace_none?}: don't collect stack traces from all the SQL executed (sticky, use #{@config.profile_parameter}=normal-backtrace to enable)
|
687
|
+
#{make_link "normal-backtrace", env} #{"(*) " if client_settings.backtrace_default?}: collect stack traces from all the SQL executed and filter normally
|
688
|
+
#{make_link "full-backtrace", env} #{"(*) " if client_settings.backtrace_full?}: enable full backtraces for SQL executed (use #{@config.profile_parameter}=normal-backtrace to disable)
|
689
|
+
#{make_link "disable", env} : disable profiling for this session
|
690
|
+
#{make_link "enable", env} : enable profiling for this session (if previously disabled)
|
691
|
+
#{make_link "profile-gc", env} : perform gc profiling on this request, analyzes ObjectSpace generated by request
|
692
|
+
#{make_link "profile-memory", env} : requires the memory_profiler gem, new location based report
|
693
|
+
#{make_link "flamegraph", env} : a graph representing sampled activity (requires the stackprof gem).
|
694
|
+
#{make_link "async-flamegraph", env} : store flamegraph data for this page and all its AJAX requests. Flamegraph links will be available in the mini-profiler UI (requires the stackprof gem).
|
695
|
+
#{make_link "flamegraph&flamegraph_sample_rate=1", env}: creates a flamegraph with the specified sample rate (in ms). Overrides value set in config
|
696
|
+
#{make_link "flamegraph&flamegraph_mode=cpu", env}: creates a flamegraph with the specified mode (one of cpu, wall, object, or custom). Overrides value set in config
|
697
|
+
#{make_link "flamegraph_embed", env} : a graph representing sampled activity (requires the stackprof gem), embedded resources for use on an intranet.
|
698
|
+
#{make_link "trace-exceptions", env} : will return all the spots where your application raises exceptions
|
699
|
+
#{make_link "analyze-memory", env} : will perform basic memory analysis of heap
|
700
|
+
</pre>
|
701
|
+
</body>
|
702
|
+
</html>
|
703
|
+
HTML
|
704
|
+
|
705
|
+
[200, headers, [html]]
|
680
706
|
end
|
681
707
|
|
682
708
|
def flamegraph(graph, path)
|
@@ -685,6 +711,7 @@ This is the help menu of the <a href='#{Rack::MiniProfiler::SOURCE_CODE_URI}'>ra
|
|
685
711
|
<!DOCTYPE html>
|
686
712
|
<html>
|
687
713
|
<head>
|
714
|
+
<title>Rack::MiniProfiler Flamegraph</title>
|
688
715
|
<style>
|
689
716
|
body { margin: 0; height: 100vh; }
|
690
717
|
#speedscope-iframe { width: 100%; height: 100%; border: none; }
|
@@ -773,7 +800,7 @@ This is the help menu of the <a href='#{Rack::MiniProfiler::SOURCE_CODE_URI}'>ra
|
|
773
800
|
end
|
774
801
|
|
775
802
|
# TODO : cache this snippet
|
776
|
-
script = ::File.read(::File.expand_path('
|
803
|
+
script = ::File.read(::File.expand_path('html/profile_handler.js', ::File.dirname(__FILE__)))
|
777
804
|
# replace the variables
|
778
805
|
settings.each do |k, v|
|
779
806
|
regex = Regexp.new("\\{#{k.to_s}\\}")
|
@@ -828,8 +855,11 @@ This is the help menu of the <a href='#{Rack::MiniProfiler::SOURCE_CODE_URI}'>ra
|
|
828
855
|
response = Rack::Response.new([], status, headers)
|
829
856
|
|
830
857
|
response.write <<~HTML
|
858
|
+
<!DOCTYPE html>
|
831
859
|
<html>
|
832
|
-
<head
|
860
|
+
<head>
|
861
|
+
<title>Rack::MiniProfiler Snapshots</title>
|
862
|
+
</head>
|
833
863
|
<body class="mp-snapshots">
|
834
864
|
HTML
|
835
865
|
response.write(data_html)
|
data/lib/patches/net_patches.rb
CHANGED
@@ -1,26 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
if
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
if ENV['RACK_MINI_PROFILER_PATCH_NET_HTTP'] != 'false'
|
4
|
+
if (defined?(Net) && defined?(Net::HTTP))
|
5
|
+
if defined?(Rack::MINI_PROFILER_PREPEND_NET_HTTP_PATCH)
|
6
|
+
module NetHTTPWithMiniProfiler
|
7
|
+
def request(request, *args, &block)
|
8
|
+
Rack::MiniProfiler.step("Net::HTTP #{request.method} #{request.path}") do
|
9
|
+
super
|
10
|
+
end
|
10
11
|
end
|
11
12
|
end
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
Net::HTTP.prepend(NetHTTPWithMiniProfiler)
|
14
|
+
else
|
15
|
+
Net::HTTP.class_eval do
|
16
|
+
def request_with_mini_profiler(*args, &block)
|
17
|
+
request = args[0]
|
18
|
+
Rack::MiniProfiler.step("Net::HTTP #{request.method} #{request.path}") do
|
19
|
+
request_without_mini_profiler(*args, &block)
|
20
|
+
end
|
20
21
|
end
|
22
|
+
alias request_without_mini_profiler request
|
23
|
+
alias request request_with_mini_profiler
|
21
24
|
end
|
22
|
-
alias request_without_mini_profiler request
|
23
|
-
alias request request_with_mini_profiler
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
data/lib/rack-mini-profiler.rb
CHANGED
@@ -1,33 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'json'
|
4
|
-
require 'timeout'
|
5
|
-
require 'thread'
|
6
|
-
require 'securerandom'
|
7
|
-
|
8
3
|
require 'mini_profiler/version'
|
9
4
|
require 'mini_profiler/asset_version'
|
10
5
|
|
11
|
-
require 'mini_profiler
|
12
|
-
require 'mini_profiler/timer_struct/page'
|
13
|
-
require 'mini_profiler/timer_struct/sql'
|
14
|
-
require 'mini_profiler/timer_struct/custom'
|
15
|
-
require 'mini_profiler/timer_struct/client'
|
16
|
-
require 'mini_profiler/timer_struct/request'
|
17
|
-
|
18
|
-
require 'mini_profiler/storage/abstract_store'
|
19
|
-
require 'mini_profiler/storage/memcache_store'
|
20
|
-
require 'mini_profiler/storage/memory_store'
|
21
|
-
require 'mini_profiler/storage/redis_store'
|
22
|
-
require 'mini_profiler/storage/file_store'
|
6
|
+
require 'mini_profiler'
|
23
7
|
|
24
|
-
require 'mini_profiler/config'
|
25
|
-
require 'mini_profiler/profiling_methods'
|
26
|
-
require 'mini_profiler/context'
|
27
|
-
require 'mini_profiler/client_settings'
|
28
|
-
require 'mini_profiler/gc_profiler'
|
29
|
-
require 'mini_profiler/snapshots_transporter'
|
30
|
-
require 'mini_profiler/profiler'
|
31
8
|
require 'patches/sql_patches'
|
32
9
|
require 'patches/net_patches'
|
33
10
|
|
data/rack-mini-profiler.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
"CHANGELOG.md"
|
22
22
|
]
|
23
23
|
s.add_runtime_dependency 'rack', '>= 1.2.0'
|
24
|
-
s.required_ruby_version = '>= 2.
|
24
|
+
s.required_ruby_version = '>= 2.6.0'
|
25
25
|
|
26
26
|
s.metadata = {
|
27
27
|
'source_code_uri' => Rack::MiniProfiler::SOURCE_CODE_URI,
|
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.add_development_dependency 'rake'
|
32
32
|
s.add_development_dependency 'rack-test'
|
33
33
|
s.add_development_dependency 'dalli'
|
34
|
-
s.add_development_dependency 'rspec', '~> 3.
|
34
|
+
s.add_development_dependency 'rspec', '~> 3.12.0'
|
35
35
|
s.add_development_dependency 'redis'
|
36
36
|
s.add_development_dependency 'sassc'
|
37
37
|
s.add_development_dependency 'stackprof'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-mini-profiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-04-11 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|
@@ -74,14 +74,14 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - "~>"
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 3.
|
77
|
+
version: 3.12.0
|
78
78
|
type: :development
|
79
79
|
prerelease: false
|
80
80
|
version_requirements: !ruby/object:Gem::Requirement
|
81
81
|
requirements:
|
82
82
|
- - "~>"
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version: 3.
|
84
|
+
version: 3.12.0
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
86
|
name: redis
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
@@ -262,9 +262,11 @@ files:
|
|
262
262
|
- CHANGELOG.md
|
263
263
|
- README.md
|
264
264
|
- lib/enable_rails_patches.rb
|
265
|
+
- lib/generators/rack_mini_profiler/USAGE
|
266
|
+
- lib/generators/rack_mini_profiler/install_generator.rb
|
267
|
+
- lib/generators/rack_mini_profiler/templates/rack_mini_profiler.rb
|
265
268
|
- lib/generators/rack_profiler/USAGE
|
266
269
|
- lib/generators/rack_profiler/install_generator.rb
|
267
|
-
- lib/generators/rack_profiler/templates/rack_profiler.rb
|
268
270
|
- lib/html/dot.1.1.2.min.js
|
269
271
|
- lib/html/includes.css
|
270
272
|
- lib/html/includes.js
|
@@ -291,19 +293,21 @@ files:
|
|
291
293
|
- lib/html/speedscope/source-map.438fa06b.js
|
292
294
|
- lib/html/speedscope/speedscope.44364064.js
|
293
295
|
- lib/html/vendor.js
|
296
|
+
- lib/mini_profiler.rb
|
294
297
|
- lib/mini_profiler/asset_version.rb
|
295
298
|
- lib/mini_profiler/client_settings.rb
|
296
299
|
- lib/mini_profiler/config.rb
|
297
300
|
- lib/mini_profiler/context.rb
|
298
301
|
- lib/mini_profiler/gc_profiler.rb
|
299
|
-
- lib/mini_profiler/profiler.rb
|
300
302
|
- lib/mini_profiler/profiling_methods.rb
|
301
303
|
- lib/mini_profiler/snapshots_transporter.rb
|
304
|
+
- lib/mini_profiler/storage.rb
|
302
305
|
- lib/mini_profiler/storage/abstract_store.rb
|
303
306
|
- lib/mini_profiler/storage/file_store.rb
|
304
307
|
- lib/mini_profiler/storage/memcache_store.rb
|
305
308
|
- lib/mini_profiler/storage/memory_store.rb
|
306
309
|
- lib/mini_profiler/storage/redis_store.rb
|
310
|
+
- lib/mini_profiler/timer_struct.rb
|
307
311
|
- lib/mini_profiler/timer_struct/base.rb
|
308
312
|
- lib/mini_profiler/timer_struct/client.rb
|
309
313
|
- lib/mini_profiler/timer_struct/custom.rb
|
@@ -347,14 +351,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
347
351
|
requirements:
|
348
352
|
- - ">="
|
349
353
|
- !ruby/object:Gem::Version
|
350
|
-
version: 2.
|
354
|
+
version: 2.6.0
|
351
355
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
352
356
|
requirements:
|
353
357
|
- - ">="
|
354
358
|
- !ruby/object:Gem::Version
|
355
359
|
version: '0'
|
356
360
|
requirements: []
|
357
|
-
rubygems_version: 3.
|
361
|
+
rubygems_version: 3.4.6
|
358
362
|
signing_key:
|
359
363
|
specification_version: 4
|
360
364
|
summary: Profiles loading speed for rack applications.
|