rails_mini_profiler 0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +29 -111
- data/Rakefile +18 -0
- data/app/{javascript/images → assets/images/rails_mini_profiler}/bookmark.svg +0 -0
- data/app/{javascript/images → assets/images/rails_mini_profiler}/chart.svg +0 -0
- data/app/{javascript/images → assets/images/rails_mini_profiler}/delete.svg +0 -0
- data/app/{javascript/images → assets/images/rails_mini_profiler}/graph.svg +0 -0
- data/app/{javascript/images → assets/images/rails_mini_profiler}/logo.svg +0 -0
- data/app/{javascript/images → assets/images/rails_mini_profiler}/logo_variant.svg +2 -2
- data/app/assets/images/rails_mini_profiler/search.svg +10 -0
- data/app/{javascript/images → assets/images/rails_mini_profiler}/setting.svg +0 -0
- data/app/{javascript/images → assets/images/rails_mini_profiler}/show.svg +0 -0
- data/app/assets/javascripts/rails_mini_profiler.js +76 -1
- data/app/assets/stylesheets/rails_mini_profiler/application.css +149 -1
- data/app/assets/stylesheets/rails_mini_profiler/flamegraph.css +14 -0
- data/app/{javascript/stylesheets/flashes.scss → assets/stylesheets/rails_mini_profiler/flashes.css} +5 -3
- data/app/{javascript/stylesheets/navbar.scss → assets/stylesheets/rails_mini_profiler/navbar.css} +14 -8
- data/app/assets/stylesheets/rails_mini_profiler/profiled_requests.css +180 -0
- data/app/{javascript/stylesheets/traces.scss → assets/stylesheets/rails_mini_profiler/traces.css} +22 -17
- data/app/controllers/rails_mini_profiler/application_controller.rb +4 -9
- data/app/controllers/rails_mini_profiler/profiled_requests_controller.rb +10 -23
- data/app/helpers/rails_mini_profiler/application_helper.rb +0 -11
- data/app/models/rails_mini_profiler/application_record.rb +1 -1
- data/app/models/rails_mini_profiler/controller_trace.rb +3 -7
- data/app/models/rails_mini_profiler/flamegraph.rb +0 -4
- data/app/models/rails_mini_profiler/instantiation_trace.rb +3 -7
- data/app/models/rails_mini_profiler/profiled_request.rb +15 -21
- data/app/models/rails_mini_profiler/render_partial_trace.rb +3 -7
- data/app/models/rails_mini_profiler/render_template_trace.rb +3 -7
- data/app/models/rails_mini_profiler/rmp_trace.rb +3 -7
- data/app/models/rails_mini_profiler/sequel_trace.rb +3 -7
- data/app/models/rails_mini_profiler/trace.rb +3 -7
- data/app/presenters/rails_mini_profiler/profiled_request_presenter.rb +15 -8
- data/app/views/layouts/rails_mini_profiler/application.html.erb +12 -1
- data/app/views/layouts/rails_mini_profiler/flamegraph.html.erb +8 -1
- data/app/views/rails_mini_profiler/badge.html.erb +2 -2
- data/app/views/rails_mini_profiler/profiled_requests/index.html.erb +58 -8
- data/app/views/rails_mini_profiler/profiled_requests/show.html.erb +1 -1
- data/app/views/rails_mini_profiler/shared/_navbar.html.erb +1 -1
- data/db/migrate/20210621185018_create_rmp.rb +6 -8
- data/lib/generators/rails_mini_profiler/install_generator.rb +0 -24
- data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb +7 -23
- data/lib/rails_mini_profiler/badge.rb +1 -23
- data/lib/rails_mini_profiler/configuration.rb +4 -28
- data/lib/rails_mini_profiler/engine.rb +4 -15
- data/lib/rails_mini_profiler/errors.rb +8 -0
- data/lib/rails_mini_profiler/guard.rb +7 -18
- data/lib/rails_mini_profiler/logger.rb +0 -5
- data/lib/rails_mini_profiler/middleware.rb +4 -4
- data/lib/rails_mini_profiler/models/base_model.rb +0 -5
- data/lib/rails_mini_profiler/models/trace.rb +9 -0
- data/lib/rails_mini_profiler/redirect.rb +1 -9
- data/lib/rails_mini_profiler/request_context.rb +7 -31
- data/lib/rails_mini_profiler/request_wrapper.rb +8 -44
- data/lib/rails_mini_profiler/storage.rb +29 -0
- data/lib/rails_mini_profiler/tracers.rb +85 -0
- data/lib/rails_mini_profiler/version.rb +1 -1
- data/lib/rails_mini_profiler.rb +9 -33
- metadata +30 -127
- data/LICENSE +0 -20
- data/app/javascript/images/check.svg +0 -3
- data/app/javascript/images/chevron.svg +0 -3
- data/app/javascript/images/filter.svg +0 -1
- data/app/javascript/images/search.svg +0 -9
- data/app/javascript/js/checklist_controller.js +0 -48
- data/app/javascript/js/enable_controller.js +0 -24
- data/app/javascript/js/filter_controller.js +0 -44
- data/app/javascript/js/search_controller.js +0 -18
- data/app/javascript/js/select_controller.js +0 -47
- data/app/javascript/packs/rails-mini-profiler.js +0 -88
- data/app/javascript/stylesheets/components/page_header/page_header.scss +0 -3
- data/app/javascript/stylesheets/components/pagination.scss +0 -55
- data/app/javascript/stylesheets/components/profiled_request_table/placeholder.scss +0 -33
- data/app/javascript/stylesheets/components/profiled_request_table/profiled_request_table.scss +0 -179
- data/app/javascript/stylesheets/flamegraph.scss +0 -10
- data/app/javascript/stylesheets/profiled_requests.scss +0 -89
- data/app/javascript/stylesheets/rails-mini-profiler.scss +0 -205
- data/app/search/rails_mini_profiler/base_search.rb +0 -67
- data/app/search/rails_mini_profiler/profiled_request_search.rb +0 -34
- data/app/views/models/_flamegraph.json.jb +0 -3
- data/app/views/models/_profiled_request.jb +0 -3
- data/app/views/models/_trace.jb +0 -3
- data/app/views/rails_mini_profiler/flamegraphs/show.json.jb +0 -3
- data/app/views/rails_mini_profiler/profiled_requests/index.json.jb +0 -3
- data/app/views/rails_mini_profiler/profiled_requests/shared/header/_header.erb +0 -20
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_placeholder.erb +0 -12
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table.erb +0 -14
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table_head.erb +0 -125
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table_row.erb +0 -21
- data/app/views/rails_mini_profiler/profiled_requests/show.json.jb +0 -5
- data/app/views/rails_mini_profiler/shared/_head.erb +0 -13
- data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.js.erb +0 -13
- data/lib/rails_mini_profiler/configuration/storage.rb +0 -47
- data/lib/rails_mini_profiler/configuration/user_interface.rb +0 -48
- data/lib/rails_mini_profiler/tracing/controller_tracer.rb +0 -15
- data/lib/rails_mini_profiler/tracing/null_trace.rb +0 -7
- data/lib/rails_mini_profiler/tracing/sequel_tracer.rb +0 -37
- data/lib/rails_mini_profiler/tracing/sequel_tracker.rb +0 -37
- data/lib/rails_mini_profiler/tracing/subscriptions.rb +0 -34
- data/lib/rails_mini_profiler/tracing/trace.rb +0 -45
- data/lib/rails_mini_profiler/tracing/trace_factory.rb +0 -37
- data/lib/rails_mini_profiler/tracing/tracer.rb +0 -31
- data/lib/rails_mini_profiler/tracing/view_tracer.rb +0 -12
- data/lib/rails_mini_profiler/tracing.rb +0 -11
- data/public/rails_mini_profiler/speedscope/LICENSE +0 -21
- data/public/rails_mini_profiler/speedscope/demangle-cpp.1768f4cc.js +0 -4
- data/public/rails_mini_profiler/speedscope/demangle-cpp.1768f4cc.js.map +0 -1
- data/public/rails_mini_profiler/speedscope/favicon-16x16.f74b3187.png +0 -0
- data/public/rails_mini_profiler/speedscope/favicon-32x32.bc503437.png +0 -0
- data/public/rails_mini_profiler/speedscope/file-format-schema.json +0 -324
- data/public/rails_mini_profiler/speedscope/import.e3a73ef4.js +0 -117
- data/public/rails_mini_profiler/speedscope/import.e3a73ef4.js.map +0 -1
- data/public/rails_mini_profiler/speedscope/index.html +0 -2
- data/public/rails_mini_profiler/speedscope/release.txt +0 -3
- data/public/rails_mini_profiler/speedscope/reset.8c46b7a1.css +0 -2
- data/public/rails_mini_profiler/speedscope/reset.8c46b7a1.css.map +0 -1
- data/public/rails_mini_profiler/speedscope/source-map.438fa06b.js +0 -24
- data/public/rails_mini_profiler/speedscope/source-map.438fa06b.js.map +0 -1
- data/public/rails_mini_profiler/speedscope/speedscope.026f36b0.js +0 -200
- data/public/rails_mini_profiler/speedscope/speedscope.026f36b0.js.map +0 -1
- data/vendor/assets/images/bookmark.svg +0 -10
- data/vendor/assets/images/chart.svg +0 -12
- data/vendor/assets/images/check.svg +0 -3
- data/vendor/assets/images/chevron.svg +0 -3
- data/vendor/assets/images/delete.svg +0 -9
- data/vendor/assets/images/filter.svg +0 -1
- data/vendor/assets/images/graph.svg +0 -11
- data/vendor/assets/images/logo.svg +0 -18
- data/vendor/assets/images/logo_variant.svg +0 -32
- data/vendor/assets/images/search.svg +0 -9
- data/vendor/assets/images/setting.svg +0 -10
- data/vendor/assets/images/show.svg +0 -11
- data/vendor/assets/javascripts/rails-mini-profiler.css +0 -1
- data/vendor/assets/javascripts/rails-mini-profiler.js +0 -1
@@ -25,13 +25,13 @@
|
|
25
25
|
transition: opacity 0.3s;
|
26
26
|
}
|
27
27
|
|
28
|
-
#
|
28
|
+
#rails-mini-profiler-badge-icon {
|
29
29
|
height: 18px;
|
30
30
|
width: 18px;
|
31
31
|
padding-bottom: 2px;
|
32
32
|
}
|
33
33
|
</style>
|
34
34
|
<a id="rails-mini-profiler-badge" href="<%= profiled_request_path(@profiled_request.id) %>" data-turbolinks="false" title="View performance data">
|
35
|
-
<%=
|
35
|
+
<%= inline_svg_tag('rails_mini_profiler/logo_variant', id: "rails-mini-profiler-badge-icon") %>
|
36
36
|
<%= (@profiled_request.duration.to_f / 100).round %>ms
|
37
37
|
</a>
|
@@ -1,9 +1,59 @@
|
|
1
|
+
<% if @profiled_requests.empty? %>
|
2
|
+
<section class="placeholder">
|
3
|
+
<%= inline_svg_tag('rails_mini_profiler/logo_variant', class: 'placeholder-image') %>
|
4
|
+
<div class="placeholder-text">
|
5
|
+
<h2> There is nothing here yet! </h2>
|
6
|
+
<p>Send some requests to your app for them to show up here</p>
|
7
|
+
</div>
|
8
|
+
</section>
|
9
|
+
<% else %>
|
10
|
+
<h1>Profiled Requests</h1>
|
11
|
+
<div class="profiled-requests-actions">
|
12
|
+
<%= form_with id: 'profiled-request-search-form', url: profiled_requests_url, method: :get do |form| %>
|
13
|
+
<%= form.search_field :path, id: 'profiled-request-search', placeholder: 'Search Path...', class: 'search-field' %>
|
14
|
+
<% end %>
|
15
|
+
<%= link_to(destroy_all_profiled_requests_url,
|
16
|
+
method: :delete,
|
17
|
+
class: 'clear-action',
|
18
|
+
data: { confirm: "This will delete all requests. Are you sure?" }) do %>
|
19
|
+
<button>Clear Requests</button>
|
20
|
+
<% end %>
|
21
|
+
</div>
|
22
|
+
<table id="profiled-requests-table" class="table">
|
23
|
+
<thead>
|
24
|
+
<tr>
|
25
|
+
<th class="text-left">Path</th>
|
26
|
+
<th class="text-left">Method</th>
|
27
|
+
<th class="text-left">Status</th>
|
28
|
+
<th class="text-left">Media Type</th>
|
29
|
+
<th class="text-right">Duration</th>
|
30
|
+
<th class="text-left"></th>
|
31
|
+
<th class="text-left"></th>
|
32
|
+
</tr>
|
33
|
+
</thead>
|
1
34
|
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
</
|
8
|
-
|
9
|
-
<
|
35
|
+
<tbody>
|
36
|
+
<% @profiled_requests.each do |profiled_request| %>
|
37
|
+
<tr data-link="<%= profiled_request_path(profiled_request.id)%>">
|
38
|
+
<td class="request-path"><%= profiled_request.request_name %></td>
|
39
|
+
<td> <%= profiled_request.request_method %> </td>
|
40
|
+
<td> <%= profiled_request.response_status %> </td>
|
41
|
+
<td> <%= profiled_request.response_media_type %> </td>
|
42
|
+
<td class="text-right"><%= profiled_request.duration %> ms</td>
|
43
|
+
<td class=""><%= profiled_request.created_at %></td>
|
44
|
+
<td class="request-buttons">
|
45
|
+
<%= link_to(profiled_request_path(profiled_request.id), title: 'Show Details') do %>
|
46
|
+
<%= inline_svg_tag('rails_mini_profiler/show.svg', options = {}) %>
|
47
|
+
<% end %>
|
48
|
+
<%= profiled_request.flamegraph_icon %>
|
49
|
+
<%= link_to(profiled_request_path(profiled_request.id), title: 'Delete Request', method: :delete) do %>
|
50
|
+
<%= inline_svg_tag('rails_mini_profiler/delete.svg') %>
|
51
|
+
<% end %>
|
52
|
+
</td>
|
53
|
+
</tr>
|
54
|
+
<% end %>
|
55
|
+
</tbody>
|
56
|
+
</table>
|
57
|
+
|
58
|
+
<br>
|
59
|
+
<% end %>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<header class="header">
|
2
2
|
<nav class="nav">
|
3
3
|
<a class="home" href="<%= profiled_requests_path %>">
|
4
|
-
<%=
|
4
|
+
<%= inline_svg_tag('rails_mini_profiler/logo', class: 'home-logo') %>
|
5
5
|
<h1 class="home-title">Rails Mini Profiler </h1>
|
6
6
|
</a>
|
7
7
|
<ul class="header-links">
|
@@ -4,10 +4,10 @@ class CreateRmp < ActiveRecord::Migration[6.0]
|
|
4
4
|
def change
|
5
5
|
create_table :rmp_profiled_requests do |t|
|
6
6
|
t.string :user_id
|
7
|
-
t.
|
8
|
-
t.
|
7
|
+
t.integer :start
|
8
|
+
t.integer :finish
|
9
9
|
t.integer :duration
|
10
|
-
t.
|
10
|
+
t.integer :allocations
|
11
11
|
t.string :request_path
|
12
12
|
t.string :request_query_string
|
13
13
|
t.string :request_method
|
@@ -19,17 +19,15 @@ class CreateRmp < ActiveRecord::Migration[6.0]
|
|
19
19
|
t.string :response_media_type
|
20
20
|
|
21
21
|
t.timestamps
|
22
|
-
|
23
|
-
t.index :created_at
|
24
22
|
end
|
25
23
|
|
26
24
|
create_table :rmp_traces do |t|
|
27
25
|
t.belongs_to :rmp_profiled_request, null: false, foreign_key: true
|
28
26
|
t.string :name
|
29
|
-
t.
|
30
|
-
t.
|
27
|
+
t.integer :start
|
28
|
+
t.integer :finish
|
31
29
|
t.integer :duration
|
32
|
-
t.
|
30
|
+
t.integer :allocations
|
33
31
|
t.json :payload
|
34
32
|
t.json :backtrace
|
35
33
|
|
@@ -1,39 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
|
-
# Generators for Rails Mini Profiler
|
5
4
|
module Generators
|
6
|
-
# A basic installation generator to help set up users apps
|
7
5
|
class InstallGenerator < Rails::Generators::Base
|
8
6
|
source_root File.expand_path('templates', __dir__)
|
9
7
|
|
10
|
-
# Install Rails Mini Profiler to your Rails app
|
11
|
-
#
|
12
|
-
# Updates the routes file to mount the engine, adds an initializer and copies a migration.
|
13
8
|
desc 'Install rails-mini-profiler'
|
14
|
-
|
15
9
|
def install
|
16
10
|
route("mount RailsMiniProfiler::Engine => '/rails_mini_profiler'")
|
17
11
|
template 'rails_mini_profiler.rb.erb', 'config/initializers/rails_mini_profiler.rb'
|
18
12
|
system('rails rails_mini_profiler:install:migrations')
|
19
|
-
webpacker_install if defined?(Webpacker::Engine)
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def webpacker_install
|
25
|
-
webpacker_config_file = Rails.root.join('config', 'webpacker.yml')
|
26
|
-
unless File.exist?(webpacker_config_file)
|
27
|
-
say "Webpacker is not installed. Run 'rails webpacker:install' and rerun installation to complete setup"
|
28
|
-
return
|
29
|
-
end
|
30
|
-
|
31
|
-
run 'yarn add @rails-mini-profiler/assets'
|
32
|
-
webpack_config = YAML.load_file(webpacker_config_file)[Rails.env]
|
33
|
-
destination = Rails.root.join(webpack_config['source_path'],
|
34
|
-
webpack_config['source_entry_path'],
|
35
|
-
'rails-mini-profiler.js')
|
36
|
-
template('rails_mini_profiler.js.erb', destination)
|
37
13
|
end
|
38
14
|
end
|
39
15
|
end
|
@@ -1,29 +1,13 @@
|
|
1
|
-
# Rails Mini Profiler Initializer (<%= RailsMiniProfiler::VERSION %>)
|
2
|
-
|
3
|
-
# Customize to your hearts content. If you remove this file, Rails Mini Profiler will use sensible defaults.
|
4
|
-
# For more information see https://github.com/hschne/rails-mini-profiler#configuration
|
5
1
|
RailsMiniProfiler.configure do |config|
|
6
2
|
# Customize when Rails Mini Profiler should run
|
7
|
-
config.enabled = proc { |env| Rails.env.development? ||
|
8
|
-
|
9
|
-
# Configure Flamegraph generation
|
10
|
-
config.flamegraph_enabled = true
|
11
|
-
# config.flamegraph_sample_rate = 0.5
|
12
|
-
|
13
|
-
# Configure endpoints to profile
|
14
|
-
config.skip_paths = []
|
3
|
+
# config.enabled = proc { |env| Rails.env.development? || request.headers[RMP_ENABLED].present? }
|
15
4
|
|
16
|
-
#
|
17
|
-
# config.
|
18
|
-
# config.storage.profiled_requests_table = :rmp_profiled_requests
|
19
|
-
# config.storage.traces_table = :rmp_traces
|
20
|
-
# config.storage.flamegraphs_table = :rmp_flamegraphs
|
5
|
+
# Disable Flamegraph generation
|
6
|
+
# config.flamegraph_enabled = false
|
21
7
|
|
22
|
-
#
|
23
|
-
|
24
|
-
# config.ui.badge_position = 'top-left'
|
25
|
-
# config.ui.page_size = 25
|
8
|
+
# Use RailsMiniProfiler::Storage::ActiveRecord to store profiles in your Database
|
9
|
+
config.storage = RailsMiniProfiler::Storage::Memory
|
26
10
|
|
27
|
-
#
|
28
|
-
config.user_provider = proc { |env| Rack::Request.new(env).ip }
|
11
|
+
# Uncomment to customize how users are detected
|
12
|
+
# config.user_provider = proc { |env| Rack::Request.new(env).ip }
|
29
13
|
end
|
@@ -1,33 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '../../app/helpers/rails_mini_profiler/application_helper'
|
4
|
-
|
5
3
|
module RailsMiniProfiler
|
6
|
-
# Wraps functionality to render an interactive badge on top of HTML responses
|
7
|
-
#
|
8
|
-
# @api private
|
9
4
|
class Badge
|
10
5
|
include InlineSvg::ActionView::Helpers
|
11
|
-
include RailsMiniProfiler::ApplicationHelper
|
12
6
|
include Engine.routes.url_helpers
|
13
7
|
|
14
|
-
# @param request_context [RequestContext] The current request context
|
15
|
-
# @param configuration [Configuration] The current configuration
|
16
8
|
def initialize(request_context, configuration: RailsMiniProfiler.configuration)
|
17
9
|
@configuration = configuration
|
18
10
|
@profiled_request = request_context.profiled_request
|
19
11
|
@original_response = request_context.response
|
20
12
|
end
|
21
13
|
|
22
|
-
# Inject the badge into the response
|
23
|
-
#
|
24
|
-
# @return [ResponseWrapper] The modified response
|
25
14
|
def render
|
26
15
|
content_type = @original_response.headers['Content-Type']
|
27
16
|
return @original_response unless content_type =~ %r{text/html}
|
28
17
|
|
29
|
-
return @original_response unless @configuration.ui.badge_enabled
|
30
|
-
|
31
18
|
modified_response = Rack::Response.new([], @original_response.status, @original_response.headers)
|
32
19
|
modified_response.write(modified_body)
|
33
20
|
modified_response.finish
|
@@ -42,9 +29,6 @@ module RailsMiniProfiler
|
|
42
29
|
|
43
30
|
private
|
44
31
|
|
45
|
-
# Modify the body of the original response
|
46
|
-
#
|
47
|
-
# @return String The modified body
|
48
32
|
def modified_body
|
49
33
|
body = @original_response.response.body
|
50
34
|
index = body.rindex(%r{</body>}i) || body.rindex(%r{</html>}i)
|
@@ -55,9 +39,6 @@ module RailsMiniProfiler
|
|
55
39
|
end
|
56
40
|
end
|
57
41
|
|
58
|
-
# Render the badge template
|
59
|
-
#
|
60
|
-
# @return String The badge HTML content to be injected
|
61
42
|
def badge_content
|
62
43
|
html = IO.read(File.expand_path('../../app/views/rails_mini_profiler/badge.html.erb', __dir__))
|
63
44
|
@position = css_position
|
@@ -65,11 +46,8 @@ module RailsMiniProfiler
|
|
65
46
|
template.result(binding)
|
66
47
|
end
|
67
48
|
|
68
|
-
# Transform the configuration position into CSS style positions
|
69
|
-
#
|
70
|
-
# @return String The badge position as CSS style
|
71
49
|
def css_position
|
72
|
-
case
|
50
|
+
case RailsMiniProfiler.configuration.badge_position
|
73
51
|
when 'top-right'
|
74
52
|
'top: 5px; right: 5px;'
|
75
53
|
when 'bottom-left'
|
@@ -1,36 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'rails_mini_profiler/configuration/storage'
|
4
|
-
require 'rails_mini_profiler/configuration/user_interface'
|
5
|
-
|
6
3
|
module RailsMiniProfiler
|
7
|
-
# The main Rails Mini Profiler configuration object
|
8
|
-
#
|
9
|
-
# @!attribute [r] logger
|
10
|
-
# @return [Logger] the current logger
|
11
|
-
# @!attribute enabled
|
12
|
-
# @return [Boolean] if the profiler is enabled
|
13
|
-
# @!attribute flamegraph_enabled
|
14
|
-
# @return [Boolean] if Flamegraph recording is enabled
|
15
|
-
# @!attribute flamegraph_sample_rate
|
16
|
-
# @return [Float] the sample rate in samples per millisecond
|
17
|
-
# @!attribute skip_paths
|
18
|
-
# @return [Array<String>] a list of regex patterns for paths to skip
|
19
|
-
# @!attribute storage
|
20
|
-
# @return [Storage] the storage configuration
|
21
|
-
# @!attribute ui
|
22
|
-
# @return [UserInterface] the ui configuration
|
23
|
-
# @!attribute user_provider
|
24
|
-
# @return [Proc] a proc to identify a user based on a rack env
|
25
4
|
class Configuration
|
26
5
|
attr_reader :logger
|
27
6
|
|
28
7
|
attr_accessor :enabled,
|
8
|
+
:badge_enabled,
|
9
|
+
:badge_position,
|
29
10
|
:flamegraph_enabled,
|
30
11
|
:flamegraph_sample_rate,
|
31
12
|
:skip_paths,
|
32
13
|
:storage,
|
33
|
-
:ui,
|
34
14
|
:user_provider
|
35
15
|
|
36
16
|
def initialize(**kwargs)
|
@@ -38,22 +18,18 @@ module RailsMiniProfiler
|
|
38
18
|
kwargs.each { |key, value| instance_variable_set("@#{key}", value) }
|
39
19
|
end
|
40
20
|
|
41
|
-
# Reset the configuration to default values
|
42
21
|
def reset
|
43
22
|
@enabled = proc { |_env| Rails.env.development? || Rails.env.test? }
|
23
|
+
@badge_enabled = true
|
24
|
+
@badge_position = 'top-left'
|
44
25
|
@flamegraph_enabled = true
|
45
26
|
@flamegraph_sample_rate = 0.5
|
46
27
|
@logger = RailsMiniProfiler::Logger.new(Rails.logger)
|
47
28
|
@skip_paths = []
|
48
29
|
@storage = Storage.new
|
49
|
-
@ui = UserInterface.new
|
50
30
|
@user_provider = proc { |env| Rack::Request.new(env).ip }
|
51
31
|
end
|
52
32
|
|
53
|
-
# Set the logger
|
54
|
-
#
|
55
|
-
# @param logger [Logger]
|
56
|
-
# The logger to be used. If set to nil, the Rails default logger is used and the log level set to fatal
|
57
33
|
def logger=(logger)
|
58
34
|
if logger.nil?
|
59
35
|
@logger.level = Logger::FATAL
|
@@ -1,9 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
|
-
# The Rails Mini Profiler engine
|
5
|
-
#
|
6
|
-
# Injects a a custom [Middleware] into an existing Rails app to record request profiling information.
|
7
4
|
class Engine < ::Rails::Engine
|
8
5
|
isolate_namespace RailsMiniProfiler
|
9
6
|
|
@@ -11,6 +8,10 @@ module RailsMiniProfiler
|
|
11
8
|
app.middleware.use(RailsMiniProfiler::Middleware)
|
12
9
|
end
|
13
10
|
|
11
|
+
initializer 'rails_mini_profiler.assets.precompile', group: :all do |app|
|
12
|
+
app.config.assets.precompile += %w[rails_mini_profiler.js rails_mini_profiler/application.css]
|
13
|
+
end
|
14
|
+
|
14
15
|
config.generators do |g|
|
15
16
|
g.test_framework :rspec
|
16
17
|
end
|
@@ -18,17 +19,5 @@ module RailsMiniProfiler
|
|
18
19
|
initializer 'rails_mini_profiler_add_static assets' do |app|
|
19
20
|
app.middleware.insert_before(ActionDispatch::Static, ActionDispatch::Static, "#{root}/public")
|
20
21
|
end
|
21
|
-
|
22
|
-
# If sprockets is not being used then there is no need to hook into asset compilation. Calling config.assets
|
23
|
-
# without Sprockets installed breaks compilation.
|
24
|
-
if defined?(Sprockets::Rails)
|
25
|
-
initializer 'rails_mini_profiler.assets.precompile', group: :all do |app|
|
26
|
-
app.config.assets.precompile += %w[
|
27
|
-
rails_mini_profiler.js
|
28
|
-
rails_mini_profiler/application.css
|
29
|
-
vendor/assets/images
|
30
|
-
]
|
31
|
-
end
|
32
|
-
end
|
33
22
|
end
|
34
23
|
end
|
@@ -1,22 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
|
-
# Encapsulates guard conditions on whether or not to run certain parts of the profiler.
|
5
4
|
class Guard
|
6
|
-
# @param request_context [RequestContext] the current request context
|
7
|
-
# @param configuration [Configuration] the current configuration
|
8
5
|
def initialize(request_context, configuration: RailsMiniProfiler.configuration)
|
9
6
|
@request_context = request_context
|
10
7
|
@request = request_context.request
|
11
8
|
@configuration = configuration
|
12
9
|
end
|
13
10
|
|
14
|
-
# Whether or not to profile
|
15
|
-
#
|
16
|
-
# Profiling is disabled the profiler has been flat out disabled in the configuration or if the current request path
|
17
|
-
# matches on of the ignored paths.
|
18
|
-
#
|
19
|
-
# @return [Boolean] false if no profiling should be done
|
20
11
|
def profile?
|
21
12
|
return false unless enabled?
|
22
13
|
|
@@ -25,28 +16,26 @@ module RailsMiniProfiler
|
|
25
16
|
true
|
26
17
|
end
|
27
18
|
|
19
|
+
def store?
|
20
|
+
return false unless @request_context.user
|
21
|
+
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
28
25
|
private
|
29
26
|
|
30
|
-
# Is the path of the current request an ignored one?
|
31
|
-
#
|
32
|
-
# @return [Boolean] true if the path is ignored. Per default, paths going to the engine itself are ignored, as are
|
33
|
-
# asset requests, and the paths the user has configured.
|
34
27
|
def ignored_path?
|
35
28
|
return true if /#{Engine.routes.find_script_name({})}/.match?(@request.path)
|
36
29
|
|
37
30
|
return true if /assets/.match?(@request.path)
|
38
31
|
|
39
32
|
ignored_paths = @configuration.skip_paths
|
33
|
+
|
40
34
|
return true if Regexp.union(ignored_paths).match?(@request.path)
|
41
35
|
|
42
36
|
false
|
43
37
|
end
|
44
38
|
|
45
|
-
# Is the profiler enabled?
|
46
|
-
#
|
47
|
-
# Takes into account the current request env to decide if the profiler is enabled.
|
48
|
-
#
|
49
|
-
# @return [Boolean] false if the profiler is disabled
|
50
39
|
def enabled?
|
51
40
|
enabled = @configuration.enabled
|
52
41
|
return enabled unless enabled.respond_to?(:call)
|
@@ -1,11 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
|
-
# Construct a new custom logger to log from within the engine
|
5
4
|
module Logger
|
6
|
-
# Extends a logger with additional formatting
|
7
|
-
#
|
8
|
-
# @return [Logger] a customized logger
|
9
5
|
def self.new(logger)
|
10
6
|
logger = logger.dup
|
11
7
|
|
@@ -15,7 +11,6 @@ module RailsMiniProfiler
|
|
15
11
|
logger.extend(self)
|
16
12
|
end
|
17
13
|
|
18
|
-
# Custom formatter to add a RailsMiniProfiler tag to log messages
|
19
14
|
module Formatter
|
20
15
|
def call(severity, timestamp, progname, msg)
|
21
16
|
super(severity, timestamp, progname, "[RailsMiniProfiler] #{msg}")
|
@@ -5,11 +5,11 @@ module RailsMiniProfiler
|
|
5
5
|
def initialize(app)
|
6
6
|
@app = app
|
7
7
|
@config = RailsMiniProfiler.configuration
|
8
|
-
|
8
|
+
Tracers.setup! { |trace| track_trace(trace) }
|
9
9
|
end
|
10
10
|
|
11
11
|
def call(env)
|
12
|
-
request = RequestWrapper.new(env
|
12
|
+
request = RequestWrapper.new(env)
|
13
13
|
request_context = RequestContext.new(request)
|
14
14
|
return @app.call(env) unless Guard.new(request_context).profile?
|
15
15
|
|
@@ -33,8 +33,8 @@ module RailsMiniProfiler
|
|
33
33
|
def track_trace(event)
|
34
34
|
return if traces.nil?
|
35
35
|
|
36
|
-
trace =
|
37
|
-
traces.append(trace)
|
36
|
+
trace = Tracers.build_trace(event)
|
37
|
+
traces.append(trace)
|
38
38
|
end
|
39
39
|
|
40
40
|
private
|
@@ -1,12 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
|
-
# Thin wrappers around request/response classes
|
5
|
-
#
|
6
|
-
# @api private
|
7
4
|
module Models
|
8
|
-
# A pseudo model to be used to wrap profiling information. We can't use regular models, as their connecting
|
9
|
-
# to the database results in problems when profiling.
|
10
5
|
class BaseModel
|
11
6
|
include ActiveModel::Model
|
12
7
|
|
@@ -1,25 +1,17 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
|
-
# Renders a redirect response if the user should be redirected from the original request
|
5
4
|
class Redirect
|
6
5
|
include Engine.routes.url_helpers
|
7
6
|
|
8
|
-
# @param request_context [RequestContext] the current request context
|
9
7
|
def initialize(request_context)
|
10
8
|
@request = request_context.request
|
11
9
|
@profiled_request = request_context.profiled_request
|
12
10
|
end
|
13
11
|
|
14
|
-
# Renders a redirect to a specific resource under certain conditions
|
15
|
-
#
|
16
|
-
# When the user requests a Flamegraph using a parameter for a specific request, they are being served a redirect.
|
17
|
-
#
|
18
|
-
# @return [Boolean] false if no redirect happens
|
19
|
-
# @return [Array] response with status 302 and the new location to redirect to
|
20
12
|
def render
|
21
13
|
params = CGI.parse(@request.query_string).transform_values(&:first).with_indifferent_access
|
22
|
-
return redirect_to(flamegraph_path(@profiled_request.id)) if params[:rmp_flamegraph]
|
14
|
+
return redirect_to(flamegraph_path(@profiled_request.id)) if params[:rmp_flamegraph]
|
23
15
|
|
24
16
|
false
|
25
17
|
end
|
@@ -1,27 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module RailsMiniProfiler
|
4
|
-
# A working context for the duration of a request, as it runs through Rails Mini Profiler's middleware
|
5
|
-
#
|
6
|
-
# Contains all information that is being gathered while profiling is active. At the end of the request processing,
|
7
|
-
# the request context is converted into a models which are then stored in the host apps database.
|
8
|
-
#
|
9
|
-
# @!attribute [r] request
|
10
|
-
# @return [RequestWrapper] the request as sent to the application
|
11
|
-
# @!attribute response
|
12
|
-
# @return [ResponseWrapper] the response as rendered by the application
|
13
|
-
# @!attribute profiled_request
|
14
|
-
# @return [ProfiledRequest] the profiling data as gathered during profiling
|
15
|
-
# @!attribute traces
|
16
|
-
# @return [Array<Models::Trace>] trace wrappers gathered during profiling
|
17
|
-
# @!attribute flamegraph
|
18
|
-
# @return [Flamegraph] a Flamegraph, if recorded
|
19
4
|
class RequestContext
|
20
5
|
attr_reader :request
|
21
6
|
|
22
7
|
attr_accessor :response, :profiled_request, :traces, :flamegraph
|
23
8
|
|
24
|
-
# @param request [RequestWrapper] the request as sent to the application
|
25
9
|
def initialize(request)
|
26
10
|
@request = request
|
27
11
|
@env = request.env
|
@@ -29,16 +13,16 @@ module RailsMiniProfiler
|
|
29
13
|
@complete = false
|
30
14
|
end
|
31
15
|
|
32
|
-
|
33
|
-
|
34
|
-
|
16
|
+
def user_id
|
17
|
+
@user_id ||= User.current_user
|
18
|
+
end
|
19
|
+
|
35
20
|
def authorized?
|
36
21
|
@authorized ||= User.get(@env).present?
|
37
22
|
end
|
38
23
|
|
39
|
-
# Completes profiling, setting all data and preparing for saving it.
|
40
24
|
def complete_profiling!
|
41
|
-
profiled_request.user_id =
|
25
|
+
profiled_request.user_id = user_id
|
42
26
|
profiled_request.request = @request
|
43
27
|
profiled_request.response = @response
|
44
28
|
total_time = traces.find { |trace| trace.name == 'rails_mini_profiler.total_time' }
|
@@ -46,12 +30,9 @@ module RailsMiniProfiler
|
|
46
30
|
@complete = true
|
47
31
|
end
|
48
32
|
|
49
|
-
# Save profiling data in the database.
|
50
|
-
#
|
51
|
-
# This will store the profiled request, as well as any attached traces and Flamgraph.
|
52
33
|
def save_results!
|
53
34
|
ActiveRecord::Base.transaction do
|
54
|
-
profiled_request.flamegraph =
|
35
|
+
profiled_request.flamegraph = Flamegraph.new(data: flamegraph) if flamegraph.present?
|
55
36
|
profiled_request.save
|
56
37
|
insert_traces unless traces.empty?
|
57
38
|
end
|
@@ -73,12 +54,7 @@ module RailsMiniProfiler
|
|
73
54
|
|
74
55
|
timestamp = Time.zone.now
|
75
56
|
inserts = traces.map do |trace|
|
76
|
-
{
|
77
|
-
rmp_profiled_request_id: profiled_request.id,
|
78
|
-
created_at: timestamp,
|
79
|
-
updated_at: timestamp,
|
80
|
-
**trace.to_h.symbolize_keys # Symbolize keys needed for Ruby 2.6
|
81
|
-
}
|
57
|
+
{ rmp_profiled_request_id: profiled_request.id, **trace.to_h, created_at: timestamp, updated_at: timestamp }
|
82
58
|
end
|
83
59
|
RailsMiniProfiler::Trace.insert_all(inserts)
|
84
60
|
end
|