rails_mini_profiler 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 +7 -0
- data/LICENSE +20 -0
- data/README.md +302 -0
- data/app/assets/config/rails_mini_profiler_manifest.js +1 -0
- data/app/assets/javascripts/rails_mini_profiler.js +15 -0
- data/app/assets/stylesheets/rails_mini_profiler/application.css +16 -0
- data/app/controllers/rails_mini_profiler/application_controller.rb +33 -0
- data/app/controllers/rails_mini_profiler/flamegraphs_controller.rb +23 -0
- data/app/controllers/rails_mini_profiler/profiled_requests_controller.rb +68 -0
- data/app/helpers/rails_mini_profiler/application_helper.rb +23 -0
- data/app/helpers/rails_mini_profiler/profiled_requests_helper.rb +16 -0
- data/app/javascript/images/bookmark.svg +10 -0
- data/app/javascript/images/chart.svg +12 -0
- data/app/javascript/images/check.svg +3 -0
- data/app/javascript/images/chevron.svg +3 -0
- data/app/javascript/images/delete.svg +9 -0
- data/app/javascript/images/filter.svg +1 -0
- data/app/javascript/images/graph.svg +11 -0
- data/app/javascript/images/logo.svg +18 -0
- data/app/javascript/images/logo_variant.svg +32 -0
- data/app/javascript/images/search.svg +9 -0
- data/app/javascript/images/setting.svg +10 -0
- data/app/javascript/images/show.svg +11 -0
- data/app/javascript/js/checklist_controller.js +48 -0
- data/app/javascript/js/enable_controller.js +24 -0
- data/app/javascript/js/filter_controller.js +44 -0
- data/app/javascript/js/search_controller.js +18 -0
- data/app/javascript/js/select_controller.js +47 -0
- data/app/javascript/packs/rails-mini-profiler.js +88 -0
- data/app/javascript/stylesheets/components/page_header/page_header.scss +3 -0
- data/app/javascript/stylesheets/components/pagination.scss +55 -0
- data/app/javascript/stylesheets/components/profiled_request_table/placeholder.scss +33 -0
- data/app/javascript/stylesheets/components/profiled_request_table/profiled_request_table.scss +179 -0
- data/app/javascript/stylesheets/flamegraph.scss +10 -0
- data/app/javascript/stylesheets/flashes.scss +15 -0
- data/app/javascript/stylesheets/navbar.scss +44 -0
- data/app/javascript/stylesheets/profiled_requests.scss +89 -0
- data/app/javascript/stylesheets/rails-mini-profiler.scss +205 -0
- data/app/javascript/stylesheets/traces.scss +82 -0
- data/app/models/rails_mini_profiler/application_record.rb +17 -0
- data/app/models/rails_mini_profiler/controller_trace.rb +37 -0
- data/app/models/rails_mini_profiler/flamegraph.rb +37 -0
- data/app/models/rails_mini_profiler/instantiation_trace.rb +37 -0
- data/app/models/rails_mini_profiler/profiled_request.rb +65 -0
- data/app/models/rails_mini_profiler/render_partial_trace.rb +37 -0
- data/app/models/rails_mini_profiler/render_template_trace.rb +37 -0
- data/app/models/rails_mini_profiler/rmp_trace.rb +35 -0
- data/app/models/rails_mini_profiler/sequel_trace.rb +37 -0
- data/app/models/rails_mini_profiler/trace.rb +46 -0
- data/app/presenters/rails_mini_profiler/base_presenter.rb +25 -0
- data/app/presenters/rails_mini_profiler/controller_trace_presenter.rb +18 -0
- data/app/presenters/rails_mini_profiler/instantiation_trace_presenter.rb +14 -0
- data/app/presenters/rails_mini_profiler/profiled_request_presenter.rb +38 -0
- data/app/presenters/rails_mini_profiler/render_partial_trace_presenter.rb +11 -0
- data/app/presenters/rails_mini_profiler/render_template_trace_presenter.rb +15 -0
- data/app/presenters/rails_mini_profiler/rmp_trace_presenter.rb +9 -0
- data/app/presenters/rails_mini_profiler/sequel_trace_presenter.rb +69 -0
- data/app/presenters/rails_mini_profiler/trace_presenter.rb +61 -0
- data/app/search/rails_mini_profiler/base_search.rb +67 -0
- data/app/search/rails_mini_profiler/profiled_request_search.rb +34 -0
- data/app/views/layouts/rails_mini_profiler/application.html.erb +15 -0
- data/app/views/layouts/rails_mini_profiler/flamegraph.html.erb +11 -0
- data/app/views/models/_flamegraph.json.jb +3 -0
- data/app/views/models/_profiled_request.jb +3 -0
- data/app/views/models/_trace.jb +3 -0
- data/app/views/rails_mini_profiler/badge.html.erb +37 -0
- data/app/views/rails_mini_profiler/flamegraphs/show.html.erb +13 -0
- data/app/views/rails_mini_profiler/flamegraphs/show.json.jb +3 -0
- data/app/views/rails_mini_profiler/profiled_requests/index.html.erb +9 -0
- data/app/views/rails_mini_profiler/profiled_requests/index.json.jb +3 -0
- data/app/views/rails_mini_profiler/profiled_requests/shared/_trace.html.erb +40 -0
- data/app/views/rails_mini_profiler/profiled_requests/shared/header/_header.erb +20 -0
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_placeholder.erb +12 -0
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table.erb +14 -0
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table_head.erb +125 -0
- data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table_row.erb +21 -0
- data/app/views/rails_mini_profiler/profiled_requests/show.html.erb +40 -0
- data/app/views/rails_mini_profiler/profiled_requests/show.json.jb +5 -0
- data/app/views/rails_mini_profiler/shared/_flashes.html.erb +8 -0
- data/app/views/rails_mini_profiler/shared/_head.erb +13 -0
- data/app/views/rails_mini_profiler/shared/_navbar.html.erb +15 -0
- data/config/routes.rb +11 -0
- data/db/migrate/20210621185018_create_rmp.rb +46 -0
- data/lib/generators/rails_mini_profiler/USAGE +2 -0
- data/lib/generators/rails_mini_profiler/install_generator.rb +40 -0
- data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.js.erb +13 -0
- data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb +29 -0
- data/lib/rails_mini_profiler/badge.rb +84 -0
- data/lib/rails_mini_profiler/configuration/storage.rb +47 -0
- data/lib/rails_mini_profiler/configuration/user_interface.rb +48 -0
- data/lib/rails_mini_profiler/configuration.rb +65 -0
- data/lib/rails_mini_profiler/engine.rb +34 -0
- data/lib/rails_mini_profiler/flamegraph_guard.rb +47 -0
- data/lib/rails_mini_profiler/guard.rb +57 -0
- data/lib/rails_mini_profiler/logger.rb +25 -0
- data/lib/rails_mini_profiler/middleware.rb +74 -0
- data/lib/rails_mini_profiler/models/base_model.rb +23 -0
- data/lib/rails_mini_profiler/redirect.rb +33 -0
- data/lib/rails_mini_profiler/request_context.rb +86 -0
- data/lib/rails_mini_profiler/request_wrapper.rb +69 -0
- data/lib/rails_mini_profiler/response_wrapper.rb +32 -0
- data/lib/rails_mini_profiler/tracing/controller_tracer.rb +15 -0
- data/lib/rails_mini_profiler/tracing/null_trace.rb +7 -0
- data/lib/rails_mini_profiler/tracing/sequel_tracer.rb +37 -0
- data/lib/rails_mini_profiler/tracing/sequel_tracker.rb +37 -0
- data/lib/rails_mini_profiler/tracing/subscriptions.rb +34 -0
- data/lib/rails_mini_profiler/tracing/trace.rb +45 -0
- data/lib/rails_mini_profiler/tracing/trace_factory.rb +37 -0
- data/lib/rails_mini_profiler/tracing/tracer.rb +31 -0
- data/lib/rails_mini_profiler/tracing/view_tracer.rb +12 -0
- data/lib/rails_mini_profiler/tracing.rb +11 -0
- data/lib/rails_mini_profiler/user.rb +40 -0
- data/lib/rails_mini_profiler/version.rb +5 -0
- data/lib/rails_mini_profiler.rb +79 -0
- data/lib/tasks/rails_mini_profiler_tasks.rake +8 -0
- data/public/rails_mini_profiler/speedscope/LICENSE +21 -0
- data/public/rails_mini_profiler/speedscope/demangle-cpp.1768f4cc.js +4 -0
- data/public/rails_mini_profiler/speedscope/demangle-cpp.1768f4cc.js.map +1 -0
- 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 +324 -0
- data/public/rails_mini_profiler/speedscope/import.e3a73ef4.js +117 -0
- data/public/rails_mini_profiler/speedscope/import.e3a73ef4.js.map +1 -0
- data/public/rails_mini_profiler/speedscope/index.html +2 -0
- data/public/rails_mini_profiler/speedscope/release.txt +3 -0
- data/public/rails_mini_profiler/speedscope/reset.8c46b7a1.css +2 -0
- data/public/rails_mini_profiler/speedscope/reset.8c46b7a1.css.map +1 -0
- data/public/rails_mini_profiler/speedscope/source-map.438fa06b.js +24 -0
- data/public/rails_mini_profiler/speedscope/source-map.438fa06b.js.map +1 -0
- data/public/rails_mini_profiler/speedscope/speedscope.026f36b0.js +200 -0
- data/public/rails_mini_profiler/speedscope/speedscope.026f36b0.js.map +1 -0
- data/vendor/assets/images/bookmark.svg +10 -0
- data/vendor/assets/images/chart.svg +12 -0
- data/vendor/assets/images/check.svg +3 -0
- data/vendor/assets/images/chevron.svg +3 -0
- data/vendor/assets/images/delete.svg +9 -0
- data/vendor/assets/images/filter.svg +1 -0
- data/vendor/assets/images/graph.svg +11 -0
- data/vendor/assets/images/logo.svg +18 -0
- data/vendor/assets/images/logo_variant.svg +32 -0
- data/vendor/assets/images/search.svg +9 -0
- data/vendor/assets/images/setting.svg +10 -0
- data/vendor/assets/images/show.svg +11 -0
- data/vendor/assets/javascripts/rails-mini-profiler.css +1 -0
- data/vendor/assets/javascripts/rails-mini-profiler.js +1 -0
- metadata +248 -0
@@ -0,0 +1,13 @@
|
|
1
|
+
import "@rails-mini-profiler/assets"
|
2
|
+
|
3
|
+
// Import styles
|
4
|
+
import "@rails-mini-profiler/assets/dist/rails-mini-profiler.css";
|
5
|
+
|
6
|
+
// Import images
|
7
|
+
//
|
8
|
+
// You may simplify this when using a glob loader (e.g glob-import-loader)
|
9
|
+
<%- Dir.chdir(RailsMiniProfiler::Engine.root.join('app/javascript/images')) do -%>
|
10
|
+
<%- Dir.glob('**/*').each do |file| -%>
|
11
|
+
import "@rails-mini-profiler/assets/dist/images/<%= file %>";
|
12
|
+
<%- end -%>
|
13
|
+
<%- end -%>
|
@@ -0,0 +1,29 @@
|
|
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
|
+
RailsMiniProfiler.configure do |config|
|
6
|
+
# 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 = []
|
15
|
+
|
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
|
21
|
+
|
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
|
26
|
+
|
27
|
+
# Customize how users are detected
|
28
|
+
config.user_provider = proc { |env| Rack::Request.new(env).ip }
|
29
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../app/helpers/rails_mini_profiler/application_helper'
|
4
|
+
|
5
|
+
module RailsMiniProfiler
|
6
|
+
# Wraps functionality to render an interactive badge on top of HTML responses
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
class Badge
|
10
|
+
include InlineSvg::ActionView::Helpers
|
11
|
+
include RailsMiniProfiler::ApplicationHelper
|
12
|
+
include Engine.routes.url_helpers
|
13
|
+
|
14
|
+
# @param request_context [RequestContext] The current request context
|
15
|
+
# @param configuration [Configuration] The current configuration
|
16
|
+
def initialize(request_context, configuration: RailsMiniProfiler.configuration)
|
17
|
+
@configuration = configuration
|
18
|
+
@profiled_request = request_context.profiled_request
|
19
|
+
@original_response = request_context.response
|
20
|
+
end
|
21
|
+
|
22
|
+
# Inject the badge into the response
|
23
|
+
#
|
24
|
+
# @return [ResponseWrapper] The modified response
|
25
|
+
def render
|
26
|
+
content_type = @original_response.headers['Content-Type']
|
27
|
+
return @original_response unless content_type =~ %r{text/html}
|
28
|
+
|
29
|
+
return @original_response unless @configuration.ui.badge_enabled
|
30
|
+
|
31
|
+
modified_response = Rack::Response.new([], @original_response.status, @original_response.headers)
|
32
|
+
modified_response.write(modified_body)
|
33
|
+
modified_response.finish
|
34
|
+
|
35
|
+
response = @original_response.response
|
36
|
+
response.close if response.respond_to?(:close)
|
37
|
+
|
38
|
+
ResponseWrapper.new(@original_response.status,
|
39
|
+
@original_response.headers,
|
40
|
+
modified_response)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
# Modify the body of the original response
|
46
|
+
#
|
47
|
+
# @return String The modified body
|
48
|
+
def modified_body
|
49
|
+
body = @original_response.response.body
|
50
|
+
index = body.rindex(%r{</body>}i) || body.rindex(%r{</html>}i)
|
51
|
+
if index
|
52
|
+
body.dup.insert(index, badge_content)
|
53
|
+
else
|
54
|
+
body
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Render the badge template
|
59
|
+
#
|
60
|
+
# @return String The badge HTML content to be injected
|
61
|
+
def badge_content
|
62
|
+
html = IO.read(File.expand_path('../../app/views/rails_mini_profiler/badge.html.erb', __dir__))
|
63
|
+
@position = css_position
|
64
|
+
template = ERB.new(html)
|
65
|
+
template.result(binding)
|
66
|
+
end
|
67
|
+
|
68
|
+
# Transform the configuration position into CSS style positions
|
69
|
+
#
|
70
|
+
# @return String The badge position as CSS style
|
71
|
+
def css_position
|
72
|
+
case @configuration.ui.badge_position
|
73
|
+
when 'top-right'
|
74
|
+
'top: 5px; right: 5px;'
|
75
|
+
when 'bottom-left'
|
76
|
+
'bottom: 5px; left: 5px;'
|
77
|
+
when 'bottom-right'
|
78
|
+
'bottom: 5px; right: 5px;'
|
79
|
+
else
|
80
|
+
'top: 5px; left: 5px;'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMiniProfiler
|
4
|
+
# Configure how profiling data is stored within your Rails app.
|
5
|
+
#
|
6
|
+
# @!attribute database
|
7
|
+
# @return [Symbol] which database to connect to
|
8
|
+
# @!attribute profiled_requests_table
|
9
|
+
# @return [Symbol] where to store profiled requests
|
10
|
+
# @!attribute traces_table
|
11
|
+
# @return [Symbol] where to store traces
|
12
|
+
# @!attribute flamegraphs_table
|
13
|
+
# @return [Symbol] where to store flamegraphs
|
14
|
+
class Storage
|
15
|
+
class << self
|
16
|
+
# Construct a new configuration instance
|
17
|
+
#
|
18
|
+
# @return [Storage] a new storage configuration
|
19
|
+
def configuration
|
20
|
+
@configuration ||= new
|
21
|
+
end
|
22
|
+
|
23
|
+
# Configure how profiling data is stored
|
24
|
+
#
|
25
|
+
# @yieldreturn [Storage] a new storage configuration object
|
26
|
+
def configure
|
27
|
+
yield(configuration)
|
28
|
+
configuration
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :database, :profiled_requests_table, :traces_table, :flamegraphs_table
|
33
|
+
|
34
|
+
def initialize(**kwargs)
|
35
|
+
defaults!
|
36
|
+
kwargs.each { |key, value| instance_variable_set("@#{key}", value) }
|
37
|
+
end
|
38
|
+
|
39
|
+
# Reset the configuration to default values
|
40
|
+
def defaults!
|
41
|
+
@database = nil
|
42
|
+
@profiled_requests_table = 'rmp_profiled_requests'
|
43
|
+
@flamegraphs_table = 'rmp_flamegraphs'
|
44
|
+
@traces_table = 'rmp_traces'
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMiniProfiler
|
4
|
+
# Configure various aspects about Rails Mini Profilers UI.
|
5
|
+
#
|
6
|
+
# @!attribute badge_enabled
|
7
|
+
# @see Badge
|
8
|
+
# @return [Boolean] if the badge should be enabled
|
9
|
+
# @!attribute badge_position
|
10
|
+
# @see Badge
|
11
|
+
# @return [String] the position of the interactive HTML badge
|
12
|
+
# @!attribute page_size
|
13
|
+
# @return [Integer] how many items to render per page in list views
|
14
|
+
class UserInterface
|
15
|
+
class << self
|
16
|
+
# Construct a new UI configuration instance
|
17
|
+
#
|
18
|
+
# @return [UserInterface] a new storage configuration
|
19
|
+
def configuration
|
20
|
+
@configuration ||= new
|
21
|
+
end
|
22
|
+
|
23
|
+
# Configure how profiling data is shown to the user
|
24
|
+
#
|
25
|
+
# @yieldreturn [UserInterface] a new UI configuration object
|
26
|
+
def configure
|
27
|
+
yield(configuration)
|
28
|
+
configuration
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
attr_accessor :badge_enabled,
|
33
|
+
:badge_position,
|
34
|
+
:page_size
|
35
|
+
|
36
|
+
def initialize(**kwargs)
|
37
|
+
defaults!
|
38
|
+
kwargs.each { |key, value| instance_variable_set("@#{key}", value) }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Reset the configuration to default values
|
42
|
+
def defaults!
|
43
|
+
@badge_enabled = true
|
44
|
+
@badge_position = 'top-left'
|
45
|
+
@page_size = 25
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_mini_profiler/configuration/storage'
|
4
|
+
require 'rails_mini_profiler/configuration/user_interface'
|
5
|
+
|
6
|
+
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
|
+
class Configuration
|
26
|
+
attr_reader :logger
|
27
|
+
|
28
|
+
attr_accessor :enabled,
|
29
|
+
:flamegraph_enabled,
|
30
|
+
:flamegraph_sample_rate,
|
31
|
+
:skip_paths,
|
32
|
+
:storage,
|
33
|
+
:ui,
|
34
|
+
:user_provider
|
35
|
+
|
36
|
+
def initialize(**kwargs)
|
37
|
+
reset
|
38
|
+
kwargs.each { |key, value| instance_variable_set("@#{key}", value) }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Reset the configuration to default values
|
42
|
+
def reset
|
43
|
+
@enabled = proc { |_env| Rails.env.development? || Rails.env.test? }
|
44
|
+
@flamegraph_enabled = true
|
45
|
+
@flamegraph_sample_rate = 0.5
|
46
|
+
@logger = RailsMiniProfiler::Logger.new(Rails.logger)
|
47
|
+
@skip_paths = []
|
48
|
+
@storage = Storage.new
|
49
|
+
@ui = UserInterface.new
|
50
|
+
@user_provider = proc { |env| Rack::Request.new(env).ip }
|
51
|
+
end
|
52
|
+
|
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
|
+
def logger=(logger)
|
58
|
+
if logger.nil?
|
59
|
+
@logger.level = Logger::FATAL
|
60
|
+
else
|
61
|
+
@logger = logger
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
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
|
+
class Engine < ::Rails::Engine
|
8
|
+
isolate_namespace RailsMiniProfiler
|
9
|
+
|
10
|
+
initializer 'rails_mini_profiler.add_middleware' do |app|
|
11
|
+
app.middleware.use(RailsMiniProfiler::Middleware)
|
12
|
+
end
|
13
|
+
|
14
|
+
config.generators do |g|
|
15
|
+
g.test_framework :rspec
|
16
|
+
end
|
17
|
+
|
18
|
+
initializer 'rails_mini_profiler_add_static assets' do |app|
|
19
|
+
app.middleware.insert_before(ActionDispatch::Static, ActionDispatch::Static, "#{root}/public")
|
20
|
+
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
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMiniProfiler
|
4
|
+
class FlamegraphGuard
|
5
|
+
def initialize(request_context, configuration: RailsMiniProfiler.configuration)
|
6
|
+
@request_context = request_context
|
7
|
+
@request = request_context.request
|
8
|
+
@configuration = configuration
|
9
|
+
end
|
10
|
+
|
11
|
+
def record(&block)
|
12
|
+
return block.call unless enabled?
|
13
|
+
|
14
|
+
sample_rate = @configuration.flamegraph_sample_rate
|
15
|
+
if StackProf.running?
|
16
|
+
RailsMiniProfiler.logger.error('Stackprof is already running, cannot record Flamegraph')
|
17
|
+
return block.call
|
18
|
+
end
|
19
|
+
|
20
|
+
result = nil
|
21
|
+
flamegraph = StackProf.run(mode: :wall, raw: true, aggregate: false, interval: (sample_rate * 1000).to_i) do
|
22
|
+
result = block.call
|
23
|
+
end
|
24
|
+
|
25
|
+
unless flamegraph
|
26
|
+
RailsMiniProfiler.logger.error('Failed to record Flamegraph, possibly due to concurrent requests')
|
27
|
+
return result
|
28
|
+
end
|
29
|
+
|
30
|
+
@request_context.flamegraph = flamegraph.to_json
|
31
|
+
result
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def enabled?
|
37
|
+
defined?(StackProf) && StackProf.respond_to?(:run) && config_enabled?
|
38
|
+
end
|
39
|
+
|
40
|
+
def config_enabled?
|
41
|
+
params = CGI.parse(@request.query_string).transform_values(&:first).with_indifferent_access
|
42
|
+
return params[:rmp_flamegraph] if params[:rmp_flamegraph]
|
43
|
+
|
44
|
+
RailsMiniProfiler.configuration.flamegraph_enabled
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMiniProfiler
|
4
|
+
# Encapsulates guard conditions on whether or not to run certain parts of the profiler.
|
5
|
+
class Guard
|
6
|
+
# @param request_context [RequestContext] the current request context
|
7
|
+
# @param configuration [Configuration] the current configuration
|
8
|
+
def initialize(request_context, configuration: RailsMiniProfiler.configuration)
|
9
|
+
@request_context = request_context
|
10
|
+
@request = request_context.request
|
11
|
+
@configuration = configuration
|
12
|
+
end
|
13
|
+
|
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
|
+
def profile?
|
21
|
+
return false unless enabled?
|
22
|
+
|
23
|
+
return false if ignored_path?
|
24
|
+
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
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
|
+
def ignored_path?
|
35
|
+
return true if /#{Engine.routes.find_script_name({})}/.match?(@request.path)
|
36
|
+
|
37
|
+
return true if /assets/.match?(@request.path)
|
38
|
+
|
39
|
+
ignored_paths = @configuration.skip_paths
|
40
|
+
return true if Regexp.union(ignored_paths).match?(@request.path)
|
41
|
+
|
42
|
+
false
|
43
|
+
end
|
44
|
+
|
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
|
+
def enabled?
|
51
|
+
enabled = @configuration.enabled
|
52
|
+
return enabled unless enabled.respond_to?(:call)
|
53
|
+
|
54
|
+
enabled.call(@request.env)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMiniProfiler
|
4
|
+
# Construct a new custom logger to log from within the engine
|
5
|
+
module Logger
|
6
|
+
# Extends a logger with additional formatting
|
7
|
+
#
|
8
|
+
# @return [Logger] a customized logger
|
9
|
+
def self.new(logger)
|
10
|
+
logger = logger.dup
|
11
|
+
|
12
|
+
logger.formatter = logger.formatter ? logger.formatter.dup : ActiveSupport::Logger::SimpleFormatter.new
|
13
|
+
|
14
|
+
logger.formatter.extend Formatter
|
15
|
+
logger.extend(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Custom formatter to add a RailsMiniProfiler tag to log messages
|
19
|
+
module Formatter
|
20
|
+
def call(severity, timestamp, progname, msg)
|
21
|
+
super(severity, timestamp, progname, "[RailsMiniProfiler] #{msg}")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|