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.
Files changed (146) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +20 -0
  3. data/README.md +302 -0
  4. data/app/assets/config/rails_mini_profiler_manifest.js +1 -0
  5. data/app/assets/javascripts/rails_mini_profiler.js +15 -0
  6. data/app/assets/stylesheets/rails_mini_profiler/application.css +16 -0
  7. data/app/controllers/rails_mini_profiler/application_controller.rb +33 -0
  8. data/app/controllers/rails_mini_profiler/flamegraphs_controller.rb +23 -0
  9. data/app/controllers/rails_mini_profiler/profiled_requests_controller.rb +68 -0
  10. data/app/helpers/rails_mini_profiler/application_helper.rb +23 -0
  11. data/app/helpers/rails_mini_profiler/profiled_requests_helper.rb +16 -0
  12. data/app/javascript/images/bookmark.svg +10 -0
  13. data/app/javascript/images/chart.svg +12 -0
  14. data/app/javascript/images/check.svg +3 -0
  15. data/app/javascript/images/chevron.svg +3 -0
  16. data/app/javascript/images/delete.svg +9 -0
  17. data/app/javascript/images/filter.svg +1 -0
  18. data/app/javascript/images/graph.svg +11 -0
  19. data/app/javascript/images/logo.svg +18 -0
  20. data/app/javascript/images/logo_variant.svg +32 -0
  21. data/app/javascript/images/search.svg +9 -0
  22. data/app/javascript/images/setting.svg +10 -0
  23. data/app/javascript/images/show.svg +11 -0
  24. data/app/javascript/js/checklist_controller.js +48 -0
  25. data/app/javascript/js/enable_controller.js +24 -0
  26. data/app/javascript/js/filter_controller.js +44 -0
  27. data/app/javascript/js/search_controller.js +18 -0
  28. data/app/javascript/js/select_controller.js +47 -0
  29. data/app/javascript/packs/rails-mini-profiler.js +88 -0
  30. data/app/javascript/stylesheets/components/page_header/page_header.scss +3 -0
  31. data/app/javascript/stylesheets/components/pagination.scss +55 -0
  32. data/app/javascript/stylesheets/components/profiled_request_table/placeholder.scss +33 -0
  33. data/app/javascript/stylesheets/components/profiled_request_table/profiled_request_table.scss +179 -0
  34. data/app/javascript/stylesheets/flamegraph.scss +10 -0
  35. data/app/javascript/stylesheets/flashes.scss +15 -0
  36. data/app/javascript/stylesheets/navbar.scss +44 -0
  37. data/app/javascript/stylesheets/profiled_requests.scss +89 -0
  38. data/app/javascript/stylesheets/rails-mini-profiler.scss +205 -0
  39. data/app/javascript/stylesheets/traces.scss +82 -0
  40. data/app/models/rails_mini_profiler/application_record.rb +17 -0
  41. data/app/models/rails_mini_profiler/controller_trace.rb +37 -0
  42. data/app/models/rails_mini_profiler/flamegraph.rb +37 -0
  43. data/app/models/rails_mini_profiler/instantiation_trace.rb +37 -0
  44. data/app/models/rails_mini_profiler/profiled_request.rb +65 -0
  45. data/app/models/rails_mini_profiler/render_partial_trace.rb +37 -0
  46. data/app/models/rails_mini_profiler/render_template_trace.rb +37 -0
  47. data/app/models/rails_mini_profiler/rmp_trace.rb +35 -0
  48. data/app/models/rails_mini_profiler/sequel_trace.rb +37 -0
  49. data/app/models/rails_mini_profiler/trace.rb +46 -0
  50. data/app/presenters/rails_mini_profiler/base_presenter.rb +25 -0
  51. data/app/presenters/rails_mini_profiler/controller_trace_presenter.rb +18 -0
  52. data/app/presenters/rails_mini_profiler/instantiation_trace_presenter.rb +14 -0
  53. data/app/presenters/rails_mini_profiler/profiled_request_presenter.rb +38 -0
  54. data/app/presenters/rails_mini_profiler/render_partial_trace_presenter.rb +11 -0
  55. data/app/presenters/rails_mini_profiler/render_template_trace_presenter.rb +15 -0
  56. data/app/presenters/rails_mini_profiler/rmp_trace_presenter.rb +9 -0
  57. data/app/presenters/rails_mini_profiler/sequel_trace_presenter.rb +69 -0
  58. data/app/presenters/rails_mini_profiler/trace_presenter.rb +61 -0
  59. data/app/search/rails_mini_profiler/base_search.rb +67 -0
  60. data/app/search/rails_mini_profiler/profiled_request_search.rb +34 -0
  61. data/app/views/layouts/rails_mini_profiler/application.html.erb +15 -0
  62. data/app/views/layouts/rails_mini_profiler/flamegraph.html.erb +11 -0
  63. data/app/views/models/_flamegraph.json.jb +3 -0
  64. data/app/views/models/_profiled_request.jb +3 -0
  65. data/app/views/models/_trace.jb +3 -0
  66. data/app/views/rails_mini_profiler/badge.html.erb +37 -0
  67. data/app/views/rails_mini_profiler/flamegraphs/show.html.erb +13 -0
  68. data/app/views/rails_mini_profiler/flamegraphs/show.json.jb +3 -0
  69. data/app/views/rails_mini_profiler/profiled_requests/index.html.erb +9 -0
  70. data/app/views/rails_mini_profiler/profiled_requests/index.json.jb +3 -0
  71. data/app/views/rails_mini_profiler/profiled_requests/shared/_trace.html.erb +40 -0
  72. data/app/views/rails_mini_profiler/profiled_requests/shared/header/_header.erb +20 -0
  73. data/app/views/rails_mini_profiler/profiled_requests/shared/table/_placeholder.erb +12 -0
  74. data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table.erb +14 -0
  75. data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table_head.erb +125 -0
  76. data/app/views/rails_mini_profiler/profiled_requests/shared/table/_table_row.erb +21 -0
  77. data/app/views/rails_mini_profiler/profiled_requests/show.html.erb +40 -0
  78. data/app/views/rails_mini_profiler/profiled_requests/show.json.jb +5 -0
  79. data/app/views/rails_mini_profiler/shared/_flashes.html.erb +8 -0
  80. data/app/views/rails_mini_profiler/shared/_head.erb +13 -0
  81. data/app/views/rails_mini_profiler/shared/_navbar.html.erb +15 -0
  82. data/config/routes.rb +11 -0
  83. data/db/migrate/20210621185018_create_rmp.rb +46 -0
  84. data/lib/generators/rails_mini_profiler/USAGE +2 -0
  85. data/lib/generators/rails_mini_profiler/install_generator.rb +40 -0
  86. data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.js.erb +13 -0
  87. data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb +29 -0
  88. data/lib/rails_mini_profiler/badge.rb +84 -0
  89. data/lib/rails_mini_profiler/configuration/storage.rb +47 -0
  90. data/lib/rails_mini_profiler/configuration/user_interface.rb +48 -0
  91. data/lib/rails_mini_profiler/configuration.rb +65 -0
  92. data/lib/rails_mini_profiler/engine.rb +34 -0
  93. data/lib/rails_mini_profiler/flamegraph_guard.rb +47 -0
  94. data/lib/rails_mini_profiler/guard.rb +57 -0
  95. data/lib/rails_mini_profiler/logger.rb +25 -0
  96. data/lib/rails_mini_profiler/middleware.rb +74 -0
  97. data/lib/rails_mini_profiler/models/base_model.rb +23 -0
  98. data/lib/rails_mini_profiler/redirect.rb +33 -0
  99. data/lib/rails_mini_profiler/request_context.rb +86 -0
  100. data/lib/rails_mini_profiler/request_wrapper.rb +69 -0
  101. data/lib/rails_mini_profiler/response_wrapper.rb +32 -0
  102. data/lib/rails_mini_profiler/tracing/controller_tracer.rb +15 -0
  103. data/lib/rails_mini_profiler/tracing/null_trace.rb +7 -0
  104. data/lib/rails_mini_profiler/tracing/sequel_tracer.rb +37 -0
  105. data/lib/rails_mini_profiler/tracing/sequel_tracker.rb +37 -0
  106. data/lib/rails_mini_profiler/tracing/subscriptions.rb +34 -0
  107. data/lib/rails_mini_profiler/tracing/trace.rb +45 -0
  108. data/lib/rails_mini_profiler/tracing/trace_factory.rb +37 -0
  109. data/lib/rails_mini_profiler/tracing/tracer.rb +31 -0
  110. data/lib/rails_mini_profiler/tracing/view_tracer.rb +12 -0
  111. data/lib/rails_mini_profiler/tracing.rb +11 -0
  112. data/lib/rails_mini_profiler/user.rb +40 -0
  113. data/lib/rails_mini_profiler/version.rb +5 -0
  114. data/lib/rails_mini_profiler.rb +79 -0
  115. data/lib/tasks/rails_mini_profiler_tasks.rake +8 -0
  116. data/public/rails_mini_profiler/speedscope/LICENSE +21 -0
  117. data/public/rails_mini_profiler/speedscope/demangle-cpp.1768f4cc.js +4 -0
  118. data/public/rails_mini_profiler/speedscope/demangle-cpp.1768f4cc.js.map +1 -0
  119. data/public/rails_mini_profiler/speedscope/favicon-16x16.f74b3187.png +0 -0
  120. data/public/rails_mini_profiler/speedscope/favicon-32x32.bc503437.png +0 -0
  121. data/public/rails_mini_profiler/speedscope/file-format-schema.json +324 -0
  122. data/public/rails_mini_profiler/speedscope/import.e3a73ef4.js +117 -0
  123. data/public/rails_mini_profiler/speedscope/import.e3a73ef4.js.map +1 -0
  124. data/public/rails_mini_profiler/speedscope/index.html +2 -0
  125. data/public/rails_mini_profiler/speedscope/release.txt +3 -0
  126. data/public/rails_mini_profiler/speedscope/reset.8c46b7a1.css +2 -0
  127. data/public/rails_mini_profiler/speedscope/reset.8c46b7a1.css.map +1 -0
  128. data/public/rails_mini_profiler/speedscope/source-map.438fa06b.js +24 -0
  129. data/public/rails_mini_profiler/speedscope/source-map.438fa06b.js.map +1 -0
  130. data/public/rails_mini_profiler/speedscope/speedscope.026f36b0.js +200 -0
  131. data/public/rails_mini_profiler/speedscope/speedscope.026f36b0.js.map +1 -0
  132. data/vendor/assets/images/bookmark.svg +10 -0
  133. data/vendor/assets/images/chart.svg +12 -0
  134. data/vendor/assets/images/check.svg +3 -0
  135. data/vendor/assets/images/chevron.svg +3 -0
  136. data/vendor/assets/images/delete.svg +9 -0
  137. data/vendor/assets/images/filter.svg +1 -0
  138. data/vendor/assets/images/graph.svg +11 -0
  139. data/vendor/assets/images/logo.svg +18 -0
  140. data/vendor/assets/images/logo_variant.svg +32 -0
  141. data/vendor/assets/images/search.svg +9 -0
  142. data/vendor/assets/images/setting.svg +10 -0
  143. data/vendor/assets/images/show.svg +11 -0
  144. data/vendor/assets/javascripts/rails-mini-profiler.css +1 -0
  145. data/vendor/assets/javascripts/rails-mini-profiler.js +1 -0
  146. metadata +248 -0
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class BasePresenter < SimpleDelegator
5
+ def initialize(model, view, **_kwargs)
6
+ @h = view
7
+ super(model)
8
+ end
9
+
10
+ attr_reader :h
11
+
12
+ alias model __getobj__
13
+
14
+ # To avoid having to address the view context explicitly we try to delegate to it
15
+ def method_missing(method, *args, &block)
16
+ h.public_send(method, *args, &block)
17
+ rescue NoMethodError
18
+ super
19
+ end
20
+
21
+ def respond_to_missing?(method_name, *args)
22
+ h.respond_to?(method_name, *args) || super
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class ControllerTracePresenter < TracePresenter
5
+ def label
6
+ 'Action Controller'
7
+ end
8
+
9
+ def payload
10
+ content_tag('div') do
11
+ content_tag('pre', class: 'trace-payload') do
12
+ content_tag(:div, "View Time: #{model.view_runtime} ms, DB Time: #{model.db_runtime} ms",
13
+ class: 'sequel-trace-query')
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class InstantiationTracePresenter < TracePresenter
5
+ def label
6
+ "#{model.class_name} Instantiation"
7
+ end
8
+
9
+ def description
10
+ record_string = 'Record'.pluralize(model.record_count)
11
+ "Instantiated #{model.record_count} #{model.class_name} #{record_string}"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class ProfiledRequestPresenter < BasePresenter
5
+ def request_name
6
+ model.request_path
7
+ end
8
+
9
+ def duration
10
+ formatted_duration(model.duration)
11
+ end
12
+
13
+ def allocations
14
+ formatted_allocations(model.allocations)
15
+ end
16
+
17
+ def created_at
18
+ from_time = Time.now
19
+ created_at = model.created_at.in_time_zone(Time.zone)
20
+ distance = if from_time - created_at < 5.minutes
21
+ 'Now'
22
+ else
23
+ "#{distance_of_time_in_words(from_time, created_at)} ago"
24
+ end
25
+ time_tag(created_at) { content_tag('span', distance) }
26
+ end
27
+
28
+ def flamegraph_button
29
+ return nil unless RailsMiniProfiler.configuration.flamegraph_enabled
30
+
31
+ return nil unless model.flamegraph.present?
32
+
33
+ link_to(flamegraph_path(model.id), title: 'Show Flamegraph', class: 'flamegraph-button') do
34
+ content_tag('button', 'Flamegraph')
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class RenderPartialTracePresenter < TracePresenter
5
+ def label
6
+ root = Rails.root.to_s.split('/').to_set
7
+ identifier = model.identifier.split('/').to_set
8
+ (root ^ identifier).drop(2).join('/').reverse.truncate(30).reverse
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class RenderTemplateTracePresenter < TracePresenter
5
+ def label
6
+ root = Rails.root.to_s.split('/').to_set
7
+ identifier = model.identifier.split('/').to_set
8
+ (root ^ identifier).drop(2).join('/').reverse.truncate(30).reverse
9
+ end
10
+
11
+ def description
12
+ "Render #{label}"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class RmpTracePresenter < TracePresenter
5
+ def label
6
+ 'Total Time'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class SequelTracePresenter < TracePresenter
5
+ def label
6
+ sql_description
7
+ end
8
+
9
+ alias description label
10
+
11
+ def payload
12
+ return nil if transaction?
13
+
14
+ content_tag('div') do
15
+ content_tag('pre', class: 'trace-payload') do
16
+ content_tag(:div, model.sql, class: 'sequel-trace-query')
17
+ end + binding_content
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def transaction?
24
+ model.payload['name'] == 'TRANSACTION'
25
+ end
26
+
27
+ def schema?
28
+ model.payload['name'] == 'SCHEMA'
29
+ end
30
+
31
+ def sql_description
32
+ if transaction?
33
+ transaction_description
34
+ elsif schema?
35
+ 'Load Schema'
36
+ elsif model.payload['name'].present?
37
+ model.payload['name']
38
+ else
39
+ model.payload['sql'].truncate(15)
40
+ end
41
+ end
42
+
43
+ def transaction_description
44
+ # The raw SQL is something like 'BEGIN TRANSACTION', and we just turn it into 'Begin Transaction', which is less
45
+ # loud and nicer to look at.
46
+ model.sql.split.map(&:capitalize).join(' ')
47
+ end
48
+
49
+ def binding_content
50
+ return nil if simple_binds.empty?
51
+
52
+ content = simple_binds.collect do |hash|
53
+ flat = hash.to_a.flatten
54
+ "#{flat.first}=#{flat.second}"
55
+ end
56
+ content_tag(:pre, content.join(', '), class: 'sequel-trace-binds')
57
+ end
58
+
59
+ def simple_binds
60
+ return [] if model.binds.nil? || model.binds.empty?
61
+
62
+ model.binds.each_with_object({}) do |hash, object|
63
+ name = hash['name']
64
+ value = hash['value']
65
+ object[name] = value
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class TracePresenter < BasePresenter
5
+ def initialize(trace, view, profiled_request:)
6
+ super(trace, view)
7
+ @profiled_request = profiled_request
8
+ end
9
+
10
+ def label
11
+ ''
12
+ end
13
+
14
+ def description
15
+ label
16
+ end
17
+
18
+ def payload
19
+ nil
20
+ end
21
+
22
+ def backtrace
23
+ return if model.backtrace.empty?
24
+
25
+ model.backtrace.first
26
+ end
27
+
28
+ def type
29
+ # Turn this class name into a dasherized version for use in assigning CSS classes. E.g. 'RmpTracePresenter'
30
+ # becomes 'rmp-trace'
31
+ self.class.name.demodulize.delete_suffix('Presenter')
32
+ .underscore
33
+ .dasherize
34
+ end
35
+
36
+ def duration
37
+ formatted_duration(model.duration)
38
+ end
39
+
40
+ def duration_percent
41
+ (model.duration.to_f / @profiled_request.duration * 100).round
42
+ end
43
+
44
+ def allocations
45
+ formatted_allocations(model.allocations)
46
+ end
47
+
48
+ def allocations_percent
49
+ (model.allocations.to_f / @profiled_request.allocations * 100).round
50
+ end
51
+
52
+ def from_start
53
+ (model.start - @profiled_request.start).to_f / 100
54
+ end
55
+
56
+ def from_start_percent
57
+ ((model.start - @profiled_request.start).to_f /
58
+ (@profiled_request.finish - @profiled_request.start)).to_f * 100
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class BaseSearch
5
+ def initialize(params = nil, **kwargs)
6
+ config = self.class.config
7
+ options = params&.to_h || {}
8
+ options = options.merge(kwargs)
9
+ @scope = options.delete(:scope) || (config[:scope] && instance_eval(&config[:scope]))
10
+ @options = (options.delete(:options) || config[:options]).stringify_keys
11
+ @params = options.stringify_keys.slice(*@options.keys)
12
+ end
13
+
14
+ def results
15
+ @results ||= apply
16
+ end
17
+
18
+ def results?
19
+ results.any?
20
+ end
21
+
22
+ class << self
23
+ def scope(&block)
24
+ config[:scope] = block
25
+ end
26
+
27
+ def option(name, options = {}, &block)
28
+ name = name.to_s
29
+ handler = options[:with] || block
30
+
31
+ config[:options][name] = normalize_search_handler(handler, name)
32
+
33
+ define_method(name) { @search.param name }
34
+ end
35
+
36
+ def results(**kwargs)
37
+ new(**kwargs).results
38
+ end
39
+
40
+ def config
41
+ @config ||= { options: {} }
42
+ end
43
+
44
+ private
45
+
46
+ def normalize_search_handler(handler, name)
47
+ case handler
48
+ when Symbol
49
+ ->(scope, value) { method(handler).call scope, value }
50
+ when Proc
51
+ handler
52
+ else
53
+ ->(scope, value) { scope.where name => value unless value.blank? }
54
+ end
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def apply
61
+ @params.inject(@scope) do |scope, (name, value)|
62
+ new_scope = instance_exec scope, value, &@options[name]
63
+ new_scope || scope
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RailsMiniProfiler
4
+ class ProfiledRequestSearch < BaseSearch
5
+ option(:id) do |scope, value|
6
+ scope.where(id: value)
7
+ end
8
+
9
+ option(:path) do |scope, value|
10
+ scope.where('request_path LIKE ?', "%#{value}%")
11
+ end
12
+
13
+ option(:method) do |scope, value|
14
+ scope.where(request_method: value)
15
+ end
16
+
17
+ option(:media_type) do |scope, value|
18
+ scope.where(response_media_type: value)
19
+ end
20
+
21
+ option(:status) do |scope, value|
22
+ value = value.map(&:to_i)
23
+ min = value.min
24
+ max = value.max + 100
25
+ scope.where('response_status >= :lower', lower: min)
26
+ .where('response_status < :upper', upper: max)
27
+ end
28
+
29
+ option(:duration) do |scope, value|
30
+ value = value.tr('>', '').to_i * 100
31
+ scope.where('duration > :duration', duration: value)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <%= render 'rails_mini_profiler/shared/head' %>
4
+ <body>
5
+
6
+ <%= render 'rails_mini_profiler/shared/navbar' %>
7
+ <main>
8
+ <section class="main-section">
9
+ <%= render 'rails_mini_profiler/shared/flashes' %>
10
+ <%= yield %>
11
+ </section>
12
+ </main>
13
+
14
+ </body>
15
+ </html>
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <%= render 'rails_mini_profiler/shared/head' %>
4
+ <body>
5
+
6
+ <main>
7
+ <%= yield %>
8
+ </main>
9
+
10
+ </body>
11
+ </html>
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ flamegraph
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ profiled_request.attributes
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ trace.attributes
@@ -0,0 +1,37 @@
1
+ <style>
2
+ #rails-mini-profiler-badge {
3
+ position: absolute;
4
+ <%= @position %>
5
+ display: flex;
6
+ margin: 0;
7
+ padding: .2em .2em;
8
+ line-height: normal;
9
+ align-items: center;
10
+ z-index: 2147483641;
11
+ overflow: auto;
12
+ border-radius: 5px;
13
+ text-decoration: none;
14
+ opacity: 60%;
15
+ background-color: #fff;
16
+ color: #555;
17
+ -moz-box-shadow: 0 1px 15px #555;
18
+ -webkit-box-shadow: 0 1px 15px #555;
19
+ box-shadow: 0 1px 15px #555;
20
+ font-size: 14px;
21
+ }
22
+
23
+ #rails-mini-profiler-badge:hover {
24
+ opacity: 100%;
25
+ transition: opacity 0.3s;
26
+ }
27
+
28
+ #logo-variant {
29
+ height: 18px;
30
+ width: 18px;
31
+ padding-bottom: 2px;
32
+ }
33
+ </style>
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') %>
36
+ <%= (@profiled_request.duration.to_f / 100).round %>ms
37
+ </a>