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.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +29 -111
  3. data/Rakefile +18 -0
  4. data/app/{javascript/images → assets/images/rails_mini_profiler}/bookmark.svg +0 -0
  5. data/app/{javascript/images → assets/images/rails_mini_profiler}/chart.svg +0 -0
  6. data/app/{javascript/images → assets/images/rails_mini_profiler}/delete.svg +0 -0
  7. data/app/{javascript/images → assets/images/rails_mini_profiler}/graph.svg +0 -0
  8. data/app/{javascript/images → assets/images/rails_mini_profiler}/logo.svg +0 -0
  9. data/app/{javascript/images → assets/images/rails_mini_profiler}/logo_variant.svg +2 -2
  10. data/app/assets/images/rails_mini_profiler/search.svg +10 -0
  11. data/app/{javascript/images → assets/images/rails_mini_profiler}/setting.svg +0 -0
  12. data/app/{javascript/images → assets/images/rails_mini_profiler}/show.svg +0 -0
  13. data/app/assets/javascripts/rails_mini_profiler.js +76 -1
  14. data/app/assets/stylesheets/rails_mini_profiler/application.css +149 -1
  15. data/app/assets/stylesheets/rails_mini_profiler/flamegraph.css +14 -0
  16. data/app/{javascript/stylesheets/flashes.scss → assets/stylesheets/rails_mini_profiler/flashes.css} +5 -3
  17. data/app/{javascript/stylesheets/navbar.scss → assets/stylesheets/rails_mini_profiler/navbar.css} +14 -8
  18. data/app/assets/stylesheets/rails_mini_profiler/profiled_requests.css +180 -0
  19. data/app/{javascript/stylesheets/traces.scss → assets/stylesheets/rails_mini_profiler/traces.css} +22 -17
  20. data/app/controllers/rails_mini_profiler/application_controller.rb +4 -9
  21. data/app/controllers/rails_mini_profiler/profiled_requests_controller.rb +10 -23
  22. data/app/helpers/rails_mini_profiler/application_helper.rb +0 -11
  23. data/app/models/rails_mini_profiler/application_record.rb +1 -1
  24. data/app/models/rails_mini_profiler/controller_trace.rb +3 -7
  25. data/app/models/rails_mini_profiler/flamegraph.rb +0 -4
  26. data/app/models/rails_mini_profiler/instantiation_trace.rb +3 -7
  27. data/app/models/rails_mini_profiler/profiled_request.rb +15 -21
  28. data/app/models/rails_mini_profiler/render_partial_trace.rb +3 -7
  29. data/app/models/rails_mini_profiler/render_template_trace.rb +3 -7
  30. data/app/models/rails_mini_profiler/rmp_trace.rb +3 -7
  31. data/app/models/rails_mini_profiler/sequel_trace.rb +3 -7
  32. data/app/models/rails_mini_profiler/trace.rb +3 -7
  33. data/app/presenters/rails_mini_profiler/profiled_request_presenter.rb +15 -8
  34. data/app/views/layouts/rails_mini_profiler/application.html.erb +12 -1
  35. data/app/views/layouts/rails_mini_profiler/flamegraph.html.erb +8 -1
  36. data/app/views/rails_mini_profiler/badge.html.erb +2 -2
  37. data/app/views/rails_mini_profiler/profiled_requests/index.html.erb +58 -8
  38. data/app/views/rails_mini_profiler/profiled_requests/show.html.erb +1 -1
  39. data/app/views/rails_mini_profiler/shared/_navbar.html.erb +1 -1
  40. data/db/migrate/20210621185018_create_rmp.rb +6 -8
  41. data/lib/generators/rails_mini_profiler/install_generator.rb +0 -24
  42. data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb +7 -23
  43. data/lib/rails_mini_profiler/badge.rb +1 -23
  44. data/lib/rails_mini_profiler/configuration.rb +4 -28
  45. data/lib/rails_mini_profiler/engine.rb +4 -15
  46. data/lib/rails_mini_profiler/errors.rb +8 -0
  47. data/lib/rails_mini_profiler/guard.rb +7 -18
  48. data/lib/rails_mini_profiler/logger.rb +0 -5
  49. data/lib/rails_mini_profiler/middleware.rb +4 -4
  50. data/lib/rails_mini_profiler/models/base_model.rb +0 -5
  51. data/lib/rails_mini_profiler/models/trace.rb +9 -0
  52. data/lib/rails_mini_profiler/redirect.rb +1 -9
  53. data/lib/rails_mini_profiler/request_context.rb +7 -31
  54. data/lib/rails_mini_profiler/request_wrapper.rb +8 -44
  55. data/lib/rails_mini_profiler/storage.rb +29 -0
  56. data/lib/rails_mini_profiler/tracers.rb +85 -0
  57. data/lib/rails_mini_profiler/version.rb +1 -1
  58. data/lib/rails_mini_profiler.rb +9 -33
  59. metadata +30 -127
  60. data/LICENSE +0 -20
  61. data/app/javascript/images/check.svg +0 -3
  62. data/app/javascript/images/chevron.svg +0 -3
  63. data/app/javascript/images/filter.svg +0 -1
  64. data/app/javascript/images/search.svg +0 -9
  65. data/app/javascript/js/checklist_controller.js +0 -48
  66. data/app/javascript/js/enable_controller.js +0 -24
  67. data/app/javascript/js/filter_controller.js +0 -44
  68. data/app/javascript/js/search_controller.js +0 -18
  69. data/app/javascript/js/select_controller.js +0 -47
  70. data/app/javascript/packs/rails-mini-profiler.js +0 -88
  71. data/app/javascript/stylesheets/components/page_header/page_header.scss +0 -3
  72. data/app/javascript/stylesheets/components/pagination.scss +0 -55
  73. data/app/javascript/stylesheets/components/profiled_request_table/placeholder.scss +0 -33
  74. data/app/javascript/stylesheets/components/profiled_request_table/profiled_request_table.scss +0 -179
  75. data/app/javascript/stylesheets/flamegraph.scss +0 -10
  76. data/app/javascript/stylesheets/profiled_requests.scss +0 -89
  77. data/app/javascript/stylesheets/rails-mini-profiler.scss +0 -205
  78. data/app/search/rails_mini_profiler/base_search.rb +0 -67
  79. data/app/search/rails_mini_profiler/profiled_request_search.rb +0 -34
  80. data/app/views/models/_flamegraph.json.jb +0 -3
  81. data/app/views/models/_profiled_request.jb +0 -3
  82. data/app/views/models/_trace.jb +0 -3
  83. data/app/views/rails_mini_profiler/flamegraphs/show.json.jb +0 -3
  84. data/app/views/rails_mini_profiler/profiled_requests/index.json.jb +0 -3
  85. data/app/views/rails_mini_profiler/profiled_requests/shared/header/_header.erb +0 -20
  86. data/app/views/rails_mini_profiler/profiled_requests/shared/table/_placeholder.erb +0 -12
  87. data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table.erb +0 -14
  88. data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table_head.erb +0 -125
  89. data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table_row.erb +0 -21
  90. data/app/views/rails_mini_profiler/profiled_requests/show.json.jb +0 -5
  91. data/app/views/rails_mini_profiler/shared/_head.erb +0 -13
  92. data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.js.erb +0 -13
  93. data/lib/rails_mini_profiler/configuration/storage.rb +0 -47
  94. data/lib/rails_mini_profiler/configuration/user_interface.rb +0 -48
  95. data/lib/rails_mini_profiler/tracing/controller_tracer.rb +0 -15
  96. data/lib/rails_mini_profiler/tracing/null_trace.rb +0 -7
  97. data/lib/rails_mini_profiler/tracing/sequel_tracer.rb +0 -37
  98. data/lib/rails_mini_profiler/tracing/sequel_tracker.rb +0 -37
  99. data/lib/rails_mini_profiler/tracing/subscriptions.rb +0 -34
  100. data/lib/rails_mini_profiler/tracing/trace.rb +0 -45
  101. data/lib/rails_mini_profiler/tracing/trace_factory.rb +0 -37
  102. data/lib/rails_mini_profiler/tracing/tracer.rb +0 -31
  103. data/lib/rails_mini_profiler/tracing/view_tracer.rb +0 -12
  104. data/lib/rails_mini_profiler/tracing.rb +0 -11
  105. data/public/rails_mini_profiler/speedscope/LICENSE +0 -21
  106. data/public/rails_mini_profiler/speedscope/demangle-cpp.1768f4cc.js +0 -4
  107. data/public/rails_mini_profiler/speedscope/demangle-cpp.1768f4cc.js.map +0 -1
  108. data/public/rails_mini_profiler/speedscope/favicon-16x16.f74b3187.png +0 -0
  109. data/public/rails_mini_profiler/speedscope/favicon-32x32.bc503437.png +0 -0
  110. data/public/rails_mini_profiler/speedscope/file-format-schema.json +0 -324
  111. data/public/rails_mini_profiler/speedscope/import.e3a73ef4.js +0 -117
  112. data/public/rails_mini_profiler/speedscope/import.e3a73ef4.js.map +0 -1
  113. data/public/rails_mini_profiler/speedscope/index.html +0 -2
  114. data/public/rails_mini_profiler/speedscope/release.txt +0 -3
  115. data/public/rails_mini_profiler/speedscope/reset.8c46b7a1.css +0 -2
  116. data/public/rails_mini_profiler/speedscope/reset.8c46b7a1.css.map +0 -1
  117. data/public/rails_mini_profiler/speedscope/source-map.438fa06b.js +0 -24
  118. data/public/rails_mini_profiler/speedscope/source-map.438fa06b.js.map +0 -1
  119. data/public/rails_mini_profiler/speedscope/speedscope.026f36b0.js +0 -200
  120. data/public/rails_mini_profiler/speedscope/speedscope.026f36b0.js.map +0 -1
  121. data/vendor/assets/images/bookmark.svg +0 -10
  122. data/vendor/assets/images/chart.svg +0 -12
  123. data/vendor/assets/images/check.svg +0 -3
  124. data/vendor/assets/images/chevron.svg +0 -3
  125. data/vendor/assets/images/delete.svg +0 -9
  126. data/vendor/assets/images/filter.svg +0 -1
  127. data/vendor/assets/images/graph.svg +0 -11
  128. data/vendor/assets/images/logo.svg +0 -18
  129. data/vendor/assets/images/logo_variant.svg +0 -32
  130. data/vendor/assets/images/search.svg +0 -9
  131. data/vendor/assets/images/setting.svg +0 -10
  132. data/vendor/assets/images/show.svg +0 -11
  133. data/vendor/assets/javascripts/rails-mini-profiler.css +0 -1
  134. 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
- #logo-variant {
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
- <%= inline_svg('logo_variant.svg') %>
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
- <div
3
- data-controller="filters selectable"
4
- data-action="search-controller:submit@window->filters#apply">
5
- <%= render "rails_mini_profiler/profiled_requests/shared/header/header" %>
6
- <%= render "rails_mini_profiler/profiled_requests/shared/table/table" %>
7
- </div>
8
- <%== pagy_nav(@pagy) if @pagy.pages > 1 %>
9
- <br>
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,4 +1,4 @@
1
- <section class="page-header">
1
+ <section class="request-details">
2
2
  <h1> <%= @profiled_request.request_path %> </h1>
3
3
 
4
4
  <ul class="request-details-data">
@@ -1,7 +1,7 @@
1
1
  <header class="header">
2
2
  <nav class="nav">
3
3
  <a class="home" href="<%= profiled_requests_path %>">
4
- <%= inline_svg('logo.svg', class: 'home-logo') %>
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.bigint :start
8
- t.bigint :finish
7
+ t.integer :start
8
+ t.integer :finish
9
9
  t.integer :duration
10
- t.bigint :allocations
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.bigint :start
30
- t.bigint :finish
27
+ t.integer :start
28
+ t.integer :finish
31
29
  t.integer :duration
32
- t.bigint :allocations
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? || env['HTTP_RMP_ENABLED'].present? }
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
- # Configure how Rails Mini Profiler stores profiling information
17
- # config.storage.database = :rmp_database
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
- # Configure the Rails Mini Profiler User Interface
23
- # config.ui.badge_enabled = true
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
- # Customize how users are detected
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 @configuration.ui.badge_position
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
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ RailsMiniProfilerError = Class.new(StandardError)
5
+
6
+ # Storage errors
7
+ StorageError = Class.new(RailsMiniProfilerError)
8
+ 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
- Tracing::Subscriptions.setup! { |trace| track_trace(trace) }
8
+ Tracers.setup! { |trace| track_trace(trace) }
9
9
  end
10
10
 
11
11
  def call(env)
12
- request = RequestWrapper.new(env: 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 = RailsMiniProfiler::Tracing::TraceFactory.create(event)
37
- traces.append(trace) unless trace.is_a?(RailsMiniProfiler::Tracing::NullTrace)
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
 
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ module Models
5
+ class Trace < BaseModel
6
+ attr_accessor :id, :name, :start, :finish, :duration, :payload, :backtrace, :allocations, :created_at, :updated_at
7
+ end
8
+ end
9
+ end
@@ -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].present?
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
- # If a user is currently authorized
33
- #
34
- # @return [Boolean] true if the user is authorized
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 = User.current_user
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 = RailsMiniProfiler::Flamegraph.new(data: flamegraph) if flamegraph.present?
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