rails_mini_profiler 0 → 0.1.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 +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
|