rails_mini_profiler 0.1.2 → 0.3.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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -10
  3. data/app/assets/javascripts/rails_mini_profiler.js +1 -78
  4. data/app/assets/stylesheets/rails_mini_profiler/application.css +1 -171
  5. data/app/controllers/rails_mini_profiler/profiled_requests_controller.rb +10 -1
  6. data/app/helpers/rails_mini_profiler/application_helper.rb +9 -0
  7. data/app/{assets/images/rails_mini_profiler → javascript/images}/bookmark.svg +0 -0
  8. data/app/{assets/images/rails_mini_profiler → javascript/images}/chart.svg +0 -0
  9. data/app/{assets/images/rails_mini_profiler → javascript/images}/delete.svg +0 -0
  10. data/app/{assets/images/rails_mini_profiler → javascript/images}/graph.svg +0 -0
  11. data/app/{assets/images/rails_mini_profiler → javascript/images}/logo.svg +0 -0
  12. data/app/{assets/images/rails_mini_profiler → javascript/images}/logo_variant.svg +0 -0
  13. data/app/{assets/images/rails_mini_profiler → javascript/images}/search.svg +0 -0
  14. data/app/{assets/images/rails_mini_profiler → javascript/images}/setting.svg +0 -0
  15. data/app/{assets/images/rails_mini_profiler → javascript/images}/show.svg +0 -0
  16. data/app/javascript/packs/rails-mini-profiler.js +80 -0
  17. data/app/javascript/stylesheets/flamegraph.scss +9 -0
  18. data/app/{assets/stylesheets/rails_mini_profiler/flashes.css → javascript/stylesheets/flashes.scss} +0 -0
  19. data/app/{assets/stylesheets/rails_mini_profiler/navbar.css → javascript/stylesheets/navbar.scss} +2 -2
  20. data/app/{assets/stylesheets/rails_mini_profiler/profiled_requests.css → javascript/stylesheets/profiled_requests.scss} +1 -7
  21. data/app/javascript/stylesheets/rails-mini-profiler.scss +175 -0
  22. data/app/{assets/stylesheets/rails_mini_profiler/traces.css → javascript/stylesheets/traces.scss} +0 -5
  23. data/app/models/rails_mini_profiler/application_record.rb +1 -1
  24. data/app/presenters/rails_mini_profiler/profiled_request_presenter.rb +2 -2
  25. data/app/views/layouts/rails_mini_profiler/application.html.erb +1 -8
  26. data/app/views/layouts/rails_mini_profiler/flamegraph.html.erb +1 -8
  27. data/app/views/rails_mini_profiler/badge.html.erb +1 -1
  28. data/app/views/rails_mini_profiler/profiled_requests/index.html.erb +3 -3
  29. data/app/views/rails_mini_profiler/shared/_head.erb +13 -0
  30. data/app/views/rails_mini_profiler/shared/_navbar.html.erb +1 -1
  31. data/lib/generators/rails_mini_profiler/install_generator.rb +18 -0
  32. data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.js.erb +13 -0
  33. data/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb +18 -7
  34. data/lib/rails_mini_profiler.rb +29 -3
  35. data/lib/rails_mini_profiler/badge.rb +21 -1
  36. data/lib/rails_mini_profiler/configuration.rb +24 -0
  37. data/lib/rails_mini_profiler/engine.rb +8 -1
  38. data/lib/rails_mini_profiler/guard.rb +18 -7
  39. data/lib/rails_mini_profiler/logger.rb +5 -0
  40. data/lib/rails_mini_profiler/models/base_model.rb +5 -0
  41. data/lib/rails_mini_profiler/models/trace.rb +28 -0
  42. data/lib/rails_mini_profiler/redirect.rb +8 -0
  43. data/lib/rails_mini_profiler/request_context.rb +24 -5
  44. data/lib/rails_mini_profiler/storage.rb +18 -0
  45. data/lib/rails_mini_profiler/tracers.rb +1 -1
  46. data/lib/rails_mini_profiler/version.rb +4 -1
  47. data/vendor/assets/images/bookmark.svg +10 -0
  48. data/vendor/assets/images/chart.svg +12 -0
  49. data/vendor/assets/images/delete.svg +9 -0
  50. data/vendor/assets/images/graph.svg +11 -0
  51. data/vendor/assets/images/logo.svg +18 -0
  52. data/vendor/assets/images/logo_variant.svg +32 -0
  53. data/vendor/assets/images/search.svg +10 -0
  54. data/vendor/assets/images/setting.svg +10 -0
  55. data/vendor/assets/images/show.svg +11 -0
  56. data/vendor/assets/javascripts/rails-mini-profiler.css +1 -0
  57. data/vendor/assets/javascripts/rails-mini-profiler.js +1 -0
  58. metadata +31 -21
  59. data/app/assets/fonts/rails_mini_profiler/LICENSE.txt +0 -202
  60. data/app/assets/fonts/rails_mini_profiler/OpenSans-Bold.ttf +0 -0
  61. data/app/assets/fonts/rails_mini_profiler/OpenSans-Regular.ttf +0 -0
  62. data/app/assets/fonts/rails_mini_profiler/OpenSans-SemiBold.ttf +0 -0
  63. data/app/assets/stylesheets/rails_mini_profiler/flamegraph.css +0 -14
  64. data/lib/rails_mini_profiler/errors.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2cfffb82f9bb40f94f74222a07283bb1bb4ae1add55d5b21b58b048ad28b1fca
4
- data.tar.gz: c7e17ebdf05e9967a62d764feb89784ce12656bd96988ae93263326712063165
3
+ metadata.gz: c0dfb74da2ecab593753e57b0b23c131ffb7857d5c22ce167185a8ba29aa013b
4
+ data.tar.gz: cc0d40ee213af658df6475062054814be1dcbec8471e894dd7fc13c8633dd734
5
5
  SHA512:
6
- metadata.gz: 3c8d7992579cacaff26496e4b35eeceb9b68baa1f2bee127679f927a78f26ee97405c4d301b24063ba9492b01a613ae1dea55f70286676bb4fd65b69e5dd1702
7
- data.tar.gz: 98a474c2122eec0a4d5c8a497358ffde9eb08f213a043773f0fdd490204771a5a1105113bd44ea40e9a9bfa154094d38d9c198f7234f3787daf0cfb90e2d4f18
6
+ metadata.gz: f21f840089c68cd189c75bd00428d3f9f23a9b84a9c3e48de1fe2236d798ece02e7869a0bc4b265a6bb26018c347cc73d0e089d64d96bcf163ecf5bcda157f7e
7
+ data.tar.gz: 8185fec8a94783a448f7340e395e3278d3eecc4b801acfd3b321a1ff2255c5d902037ecff71001b78e74371f94eabb76efed986d15a9decc307feec0a45779f2
data/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
  [![Gem Version](https://badge.fury.io/rb/rails_mini_profiler.svg)](https://badge.fury.io/rb/rails_mini_profiler)
10
10
  [![Main](https://github.com/hschne/rails-mini-profiler/actions/workflows/main.yml/badge.svg)](https://github.com/hschne/rails-mini-profiler/actions/workflows/main.yml)
11
- [![Main](https://img.shields.io/github/license/hschne/rails-mini-profiler)](https://img.shields.io/github/license/hschne/rails-mini-profiler)
11
+ [![License](https://img.shields.io/github/license/hschne/rails-mini-profiler)](https://img.shields.io/github/license/hschne/rails-mini-profiler)
12
12
 
13
13
  [![Maintainability](https://api.codeclimate.com/v1/badges/1fcc2f4d01ab5bf7a260/maintainability)](https://codeclimate.com/github/hschne/rails-mini-profiler/maintainability)
14
14
  [![Test Coverage](https://api.codeclimate.com/v1/badges/1fcc2f4d01ab5bf7a260/test_coverage)](https://codeclimate.com/github/hschne/rails-mini-profiler/test_coverage)
@@ -91,17 +91,20 @@ By clicking on individual traces you can find out detailed information.
91
91
 
92
92
  ### Flamegraphs
93
93
 
94
- Rails Mini Profiler per default records Flamegraphs for every profiled request for convenience. Note that Flamegraphs recording
95
- incur a significant performance penalty, and can take up a lot of space.
94
+ Rails Mini Profiler automatically records Flamegraphs for profiled requests. To enable this feature, add [Stackprof](https://github.com/tmm1/stackprof)
95
+ to your Gemfile:
96
96
 
97
- To change the default behavior see [Configuration](#Configuration).
97
+ ```ruby
98
+ gem 'stackprof'
99
+ ```
100
+
101
+ For convenience, Flamegraphs are recorded for every request. This may incur a significant performance penalty. To change the default behavior see [Configuration](#Configuration).
98
102
 
99
- Flamegraphs are rendered using [Speedscope](https://github.com/jlfwong/speedscope). If Flamegraphs are not rendering
100
- you may have to amend your content security policy. See [Troubleshooting](#Troubleshooting)
103
+ Flamegraphs are rendered using [Speedscope](https://github.com/jlfwong/speedscope). See [Troubleshooting](#Troubleshooting) if Flamegraphs are not rendering correctly.
101
104
 
102
105
  ## Configuration
103
106
 
104
- You can set the following configuration options in Rails Mini Profiler:
107
+ Rails Mini Profiler provides a wide array of configuration options. You can find details below. For an example configuration check `initializers/rails_mini_profiler.rb` (or [the template file](https://github.com/hschne/rails-mini-profiler/blob/main/lib/generators/rails_mini_profiler/templates/rails_mini_profiler.rb.erb)).
105
108
 
106
109
  | Option | Default | Description |
107
110
  | ------------------------ | ---------------------------- | ----------------------------------------------------------------------------------------------- |
@@ -136,7 +139,7 @@ traces and requests are stored.
136
139
 
137
140
  Rails Mini Profiler does not offer an automatic way to clean up old profiling information. It is recommended you add a sweeper job to clean up old profiled requests periodically (e.g. using [clockwork](https://github.com/adamwiggins/clockwork). For example, with ActiveJob:
138
141
 
139
- ```
142
+ ```ruby
140
143
  # Clockwork
141
144
  every(1.month, 'purge rails mini profiler' do
142
145
  ProfiledRequestCleanupJob.perform_later
@@ -166,8 +169,6 @@ You may also explicitly set the user from the application itself:
166
169
 
167
170
  ```ruby
168
171
  class ApplicationController < ActionController::Base
169
- ...
170
-
171
172
  before_action do
172
173
  RailsMiniProfiler::User.authorize(current_user.id)
173
174
  end
@@ -243,6 +244,14 @@ end
243
244
 
244
245
  **Note: Sprockets and flash are currently required for some of Rails Mini Profiler's UI features. These modifications may no longer be needed in the future.
245
246
 
247
+ ### No Flamegraphs are being recored?
248
+
249
+ Make sure you have added [StackProf](https://github.com/tmm1/stackprof) to your Gemfile.
250
+
251
+ ```ruby
252
+ gem 'stackprof'
253
+ ```
254
+
246
255
  ### Flamegraphs are not rendering?
247
256
 
248
257
  Flamegraphs are loaded into [Speedscope](https://github.com/jlfwong/speedscope) using an Iframe and URI Encoded blobs (see [source](https://github.com/hschne/rails-mini-profiler/blob/main/app/views/rails_mini_profiler/flamegraphs/show.html.erb))
@@ -12,81 +12,4 @@
12
12
  //
13
13
  //= require rails-ujs
14
14
  //= require_tree .
15
- //= require popper
16
- //= require tippy
17
-
18
- function setupRequestSearch() {
19
- const profiledRequestNameSearch = document.getElementById('profiled-request-search')
20
- if (profiledRequestNameSearch) {
21
- profiledRequestNameSearch.addEventListener('keyup', function (event) {
22
- if (event.key === 'Enter') {
23
- event.preventDefault()
24
- document.getElementById('profiled-request-search-form').submit()
25
- }
26
- })
27
- }
28
- }
29
-
30
- function setupTraceSearch() {
31
- const traceNameSearch = document.getElementById('trace-search')
32
- if (traceNameSearch) {
33
- traceNameSearch.addEventListener('keyup', function (event) {
34
- if (event.key === 'Enter') {
35
- event.preventDefault()
36
- document.getElementById('trace-form').submit()
37
- }
38
- })
39
- }
40
- }
41
-
42
- function setupRequestTable() {
43
- const profiledRequestTable = document.getElementById('profiled-requests-table');
44
- if (profiledRequestTable) {
45
- const rows = profiledRequestTable.getElementsByTagName('tr')
46
- for (let i = 0; i < rows.length; i++) {
47
- const currentRow = profiledRequestTable.rows[i]
48
- const link = currentRow.dataset.link
49
- const createClickHandler = function (currentRow) {
50
- return function () {
51
- window.location.href = link
52
- }
53
- }
54
- currentRow.onclick = createClickHandler(currentRow)
55
- }
56
- }
57
- }
58
-
59
- function setupTraceBars () {
60
- const traceBars = document.querySelectorAll('.trace-bar')
61
- traceBars.forEach((bar) => {
62
- const popover = bar.children[0]
63
- tippy(bar, {
64
- trigger: 'click',
65
- content: popover,
66
- theme: 'rmp',
67
- maxWidth: '700px',
68
- placement: 'bottom',
69
- interactive: true,
70
- onShow (instance) {
71
- instance.popper.querySelector('.popover-close').addEventListener('click', () => {
72
- instance.hide()
73
- })
74
- },
75
- onHide (instance) {
76
- instance.popper.querySelector('.popover-close').removeEventListener('click', () => {
77
- instance.hide()
78
- })
79
- },
80
- })
81
- })
82
- }
83
-
84
-
85
- // Trace Bar Popovers
86
- document.addEventListener('DOMContentLoaded', () => {
87
- setupRequestTable();
88
- setupRequestSearch();
89
- setupTraceBars();
90
- setupTraceSearch();
91
- }, false)
92
-
15
+ //= require rails-mini-profiler
@@ -12,175 +12,5 @@
12
12
  *
13
13
  *= require_tree .
14
14
  *= require_self
15
+ *= require rails-mini-profiler
15
16
  */
16
-
17
- @font-face {
18
- font-family: 'Open Sans';
19
- font-weight: 400;
20
- font-style: normal;
21
- src: url('OpenSans-Regular.ttf') format("truetype");
22
- }
23
-
24
- @font-face {
25
- font-family: 'Open Sans';
26
- font-weight: 600;
27
- font-style: normal;
28
- src: url('OpenSans-SemiBold.ttf') format("truetype");
29
- }
30
-
31
- @font-face {
32
- font-family: 'Open Sans';
33
- font-weight: 700;
34
- font-style: normal;
35
- src: url('OpenSans-Bold.ttf') format("truetype");
36
- }
37
-
38
- html {
39
- width: 100%;
40
- height: 100%;
41
- margin: 0;
42
- padding: 0;
43
-
44
- --grey-50: #F9FAFB;
45
- --grey-100: #F3F4F6;
46
- --grey-200: #E5E7EB;
47
- --grey-400: #9CA3AF;
48
- --grey-500: #6B7280;
49
- --grey-700: #374151;
50
- --grey-900: #111827;
51
-
52
- --red-400: #F87171;
53
- --red-500: #EF4444;
54
- --red-600: #DC2626;
55
-
56
- --yellow-400: #FBBF24;
57
- --yellow-500: #F59E0B;
58
-
59
- --green-300: #6EE7B7;
60
- --green-400: #34D399;
61
- --green-500: #10B981;
62
-
63
- --blue-400: #60A5FA;
64
- --blue-500: #3B82F6;
65
-
66
- --main-width: 1056px;
67
-
68
- --primary: var(--red-600);
69
-
70
- --border-color: var(--grey-200);
71
- --text-color: var(--grey-900);
72
-
73
- font-family: 'Open Sans', monospace;
74
-
75
- }
76
-
77
- body {
78
- width: 100%;
79
- height: 100%;
80
- margin: 0;
81
- padding: 0;
82
-
83
- color: var(--text-color)
84
- }
85
-
86
- h1 {
87
- padding: 2rem 0 1rem;
88
- }
89
-
90
- button {
91
- border: none;
92
- border-radius: .25rem;
93
- padding: 0.5em .5em;
94
- text-align: center;
95
- text-decoration: none;
96
- display: inline-block;
97
- font-size: 1rem;
98
- cursor: pointer;
99
- }
100
-
101
- button:hover {
102
- box-shadow: 0 .25rem .25rem 0 var(--grey-50);
103
- }
104
-
105
- /* --------------------------------------- */
106
-
107
- .text-left {
108
- text-align: left;
109
- }
110
-
111
- .text-right {
112
- text-align: right;
113
- }
114
-
115
- /* --------------------------------------- */
116
-
117
- .pill {
118
- margin: .2rem 0;
119
- padding: .1rem .4rem;
120
- border-radius: 5px;
121
-
122
- font-size: .9rem;
123
- font-weight: 600;
124
- letter-spacing: .1rem;
125
-
126
- background: var(--grey-200);
127
- }
128
-
129
- /* --------------------------------------- */
130
-
131
- .popover {
132
- display: flex;
133
- flex-direction: column;
134
- width: 600px;
135
- padding: 1em;
136
- color: black;
137
- }
138
-
139
- .popover-header {
140
- display: flex;
141
- padding-bottom: 1em;
142
- flex-direction: row;
143
- justify-content: space-between;
144
- align-items: center;
145
- }
146
-
147
- .popover-description {
148
- margin: 0;
149
- padding: 0;
150
- }
151
-
152
- .popover-close {
153
- background: transparent;
154
- padding: 0;
155
- font-weight: 700;
156
- font-size: 20px;
157
- color: var(--grey-400);
158
- }
159
-
160
- .popover-body {
161
- padding: 1em 0;
162
- }
163
-
164
- .popover-footer {
165
- border-top: 1px solid var(--grey-50);
166
- }
167
-
168
- .tippy-box[data-theme~='rmp'] {
169
- background: white;
170
- box-shadow: 8px 0 30px 4px rgba(0, 0, 0, .2), 8px 4px 10px 0 rgba(0, 0, 0, .05);
171
- border-radius: 3px;
172
-
173
- transition: all cubic-bezier(.19,1,.22,1) .2s;
174
- }
175
- .tippy-box[data-theme~='rmp'][data-placement^='top'] > .tippy-arrow::before {
176
- border-top-color: white;
177
- }
178
- .tippy-box[data-theme~='rmp'][data-placement^='bottom'] > .tippy-arrow::before {
179
- border-bottom-color: white;
180
- }
181
- .tippy-box[data-theme~='rmp'][data-placement^='left'] > .tippy-arrow::before {
182
- border-left-color: white;
183
- }
184
- .tippy-box[data-theme~='rmp'][data-placement^='right'] > .tippy-arrow::before {
185
- border-right-color: white;
186
- }
@@ -16,7 +16,7 @@ module RailsMiniProfiler
16
16
 
17
17
  def show
18
18
  @traces = @profiled_request.traces
19
- @traces = @traces.where('payload LIKE ?', "%#{params[:search]}%") if params[:search]
19
+ @traces = @traces.where("#{payload_column} LIKE ?", "%#{params[:search]}%") if params[:search]
20
20
  @traces = @traces
21
21
  .order(:start)
22
22
  .map { |trace| present(trace, profiled_request: @profiled_request) }
@@ -51,5 +51,14 @@ module RailsMiniProfiler
51
51
  def configuration
52
52
  @configuration ||= RailsMiniProfiler.configuration
53
53
  end
54
+
55
+ def payload_column
56
+ if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
57
+ # Cast json field to text to have access to the LIKE operator
58
+ 'payload::text'
59
+ else
60
+ 'payload'
61
+ end
62
+ end
54
63
  end
55
64
  end
@@ -8,5 +8,14 @@ module RailsMiniProfiler
8
8
  yield(presenter) if block_given?
9
9
  presenter
10
10
  end
11
+
12
+ def inline_svg(path, options = {})
13
+ if defined?(Webpacker::Engine)
14
+ path = "media/images/#{path}"
15
+ inline_svg_pack_tag(path, options)
16
+ else
17
+ inline_svg_tag(path, options)
18
+ end
19
+ end
11
20
  end
12
21
  end
@@ -0,0 +1,80 @@
1
+ import '../stylesheets/rails-mini-profiler.scss'
2
+
3
+ import tippy from 'tippy.js'
4
+ import 'tippy.js/dist/tippy.css'
5
+
6
+ function setupRequestSearch() {
7
+ const profiledRequestNameSearch = document.getElementById('profiled-request-search')
8
+ if (profiledRequestNameSearch) {
9
+ profiledRequestNameSearch.addEventListener('keyup', function (event) {
10
+ if (event.key === 'Enter') {
11
+ event.preventDefault()
12
+ document.getElementById('profiled-request-search-form').submit()
13
+ }
14
+ })
15
+ }
16
+ }
17
+
18
+ function setupTraceSearch() {
19
+ const traceNameSearch = document.getElementById('trace-search')
20
+ if (traceNameSearch) {
21
+ traceNameSearch.addEventListener('keyup', function (event) {
22
+ if (event.key === 'Enter') {
23
+ event.preventDefault()
24
+ document.getElementById('trace-form').submit()
25
+ }
26
+ })
27
+ }
28
+ }
29
+
30
+ function setupRequestTable() {
31
+ const profiledRequestTable = document.getElementById('profiled-requests-table');
32
+ if (profiledRequestTable) {
33
+ const rows = profiledRequestTable.getElementsByTagName('tr')
34
+ for (let i = 0; i < rows.length; i++) {
35
+ const currentRow = profiledRequestTable.rows[i]
36
+ const link = currentRow.dataset.link
37
+ const createClickHandler = function () {
38
+ return function () {
39
+ window.location.href = link
40
+ }
41
+ }
42
+ currentRow.onclick = createClickHandler(currentRow)
43
+ }
44
+ }
45
+ }
46
+
47
+ function setupTraceBars () {
48
+ const traceBars = document.querySelectorAll('.trace-bar')
49
+ traceBars.forEach((bar) => {
50
+ const popover = bar.children[0]
51
+ tippy(bar, {
52
+ trigger: 'click',
53
+ content: popover,
54
+ theme: 'rmp',
55
+ maxWidth: '700px',
56
+ placement: 'bottom',
57
+ interactive: true,
58
+ onShow (instance) {
59
+ instance.popper.querySelector('.popover-close').addEventListener('click', () => {
60
+ instance.hide()
61
+ })
62
+ },
63
+ onHide (instance) {
64
+ instance.popper.querySelector('.popover-close').removeEventListener('click', () => {
65
+ instance.hide()
66
+ })
67
+ },
68
+ })
69
+ })
70
+ }
71
+
72
+
73
+ // Trace Bar Popovers
74
+ document.addEventListener('DOMContentLoaded', () => {
75
+ setupRequestTable();
76
+ setupRequestSearch();
77
+ setupTraceBars();
78
+ setupTraceSearch();
79
+ }, false)
80
+