rack-mini-profiler 1.1.6 → 2.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/README.md +48 -27
- data/lib/enable_rails_patches.rb +5 -0
- data/lib/html/includes.css +4 -9
- data/lib/html/includes.js +40 -26
- data/lib/html/includes.tmpl +2 -2
- data/lib/html/vendor.js +1 -1
- data/lib/mini_profiler/asset_version.rb +1 -1
- data/lib/mini_profiler/profiler.rb +29 -12
- data/lib/mini_profiler/storage/redis_store.rb +2 -2
- data/lib/mini_profiler/timer_struct/custom.rb +1 -0
- data/lib/mini_profiler/timer_struct/request.rb +53 -11
- data/lib/mini_profiler/timer_struct/sql.rb +2 -0
- data/lib/mini_profiler/version.rb +1 -1
- data/lib/mini_profiler_rails/railtie.rb +75 -7
- data/lib/mini_profiler_rails/railtie_methods.rb +61 -0
- data/lib/patches/db/activerecord.rb +1 -12
- data/lib/patches/net_patches.rb +18 -8
- data/lib/patches/sql_patches.rb +12 -4
- data/lib/prepend_net_http_patch.rb +5 -0
- data/lib/rack-mini-profiler.rb +0 -1
- data/rack-mini-profiler.gemspec +6 -3
- metadata +66 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e54608bc4885796e11d6e4fac9cc56fe478f60c5cd43d53637451ef3524f086
|
4
|
+
data.tar.gz: 6a87a58c7821a279ce08b66432de9a199a6f775f897610e03e12d497eb7ccc46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3730c9e4610fd90cc0fac86c1cddcf6181e15cef5932ba86f8f8cbca1df77c02ba7847c2e1868b48e51299b6c51224fe533818c3cc245dd02a2da11b2298569c
|
7
|
+
data.tar.gz: 98f54eed006f7f13840481b777dbe4add5f9983c5ed367f8046a942a584a5ad3eb4ea5ae6e3aef7e4aa0760b37c78ac5dd6ee5bcd45e42091a943dfabdb343b1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 2.0.4 - 2020-08-04
|
4
|
+
|
5
|
+
- [FIX] webpacker may exist with no config, allow for that
|
6
|
+
|
7
|
+
## 2.0.3 - 2020-07-29
|
8
|
+
|
9
|
+
- [FIX] support for deprecation free Redis 4.2
|
10
|
+
- [FEATURE] skip /packs when serving static assets
|
11
|
+
- [FEATURE] allow Net::HTTP patch to be applied with either prerpend or alias
|
12
|
+
|
13
|
+
## 2.0.2 - 2020-05-25
|
14
|
+
|
15
|
+
- [FIX] client timings were not showing up when you clicked show trivial
|
16
|
+
|
17
|
+
## 2.0.1 - 2020-03-17
|
18
|
+
|
19
|
+
- [REVERT] Prepend Net::HTTP patch instead of class_eval and aliasing (#429) (technique clashes with New Relic and Skylight agents)
|
20
|
+
|
21
|
+
## 2.0.0 - 2020-03-11
|
22
|
+
|
23
|
+
- [FEATURE] Prepend Net::HTTP patch instead of class_eval and aliasing (#429)
|
24
|
+
- [FEATURE] Stop patching Rails and use `ActiveSupport::Notifications` by default (see README.md for details)
|
25
|
+
|
3
26
|
## 1.1.6 - 2020-01-30
|
4
27
|
|
5
28
|
- [FIX] edge condition on page transition function could lead to exceptions
|
data/README.md
CHANGED
@@ -29,7 +29,7 @@ If you feel like taking on any of this start an issue and update us on your prog
|
|
29
29
|
|
30
30
|
## Installation
|
31
31
|
|
32
|
-
Install/add to Gemfile in Ruby 2.
|
32
|
+
Install/add to Gemfile in Ruby 2.4+
|
33
33
|
|
34
34
|
```ruby
|
35
35
|
gem 'rack-mini-profiler'
|
@@ -51,6 +51,36 @@ gem 'stackprof'
|
|
51
51
|
|
52
52
|
All you have to do is to include the Gem and you're good to go in development. See notes below for use in production.
|
53
53
|
|
54
|
+
#### Upgrading to version 2.0.0
|
55
|
+
|
56
|
+
Prior to version 2.0.0, Mini Profiler patched various Rails methods to get the information it needed such as template rendering time. Starting from version 2.0.0, Mini Profiler doesn't patch any Rails methods by default and relies on `ActiveSupport::Notifications` to get the information it needs from Rails. If you want Mini Profiler to keep using its patches in version 2.0.0 and later, change the gem line in your `Gemfile` to the following:
|
57
|
+
|
58
|
+
If you want to manually require Mini Profiler:
|
59
|
+
```ruby
|
60
|
+
gem 'rack-mini-profiler', require: ['enable_rails_patches']
|
61
|
+
```
|
62
|
+
|
63
|
+
If you don't want to manually require Mini Profiler:
|
64
|
+
```ruby
|
65
|
+
gem 'rack-mini-profiler', require: ['enable_rails_patches', 'rack-mini-profiler']
|
66
|
+
```
|
67
|
+
|
68
|
+
#### `Net::HTTP` stack level too deep errors
|
69
|
+
|
70
|
+
If you start seeing `SystemStackError: stack level too deep` errors from `Net::HTTP` after installing Mini Profiler, this means there is another patch for `Net::HTTP#request` that conflicts with Mini Profiler's patch in your application. To fix this, change `rack-mini-profiler` gem line in your `Gemfile` to the following:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
gem 'rack-mini-profiler', require: ['prepend_net_http_patch', 'rack-mini-profiler']
|
74
|
+
```
|
75
|
+
|
76
|
+
If you currently have `require: false`, remove the `'rack-mini-profiler'` string from the `require` array above so the gem line becomes like this:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
gem 'rack-mini-profiler', require: ['prepend_net_http_patch']
|
80
|
+
```
|
81
|
+
|
82
|
+
This conflict happens when a ruby method is patched twice, once using module prepend, and once using method aliasing. See this [ruby issue](https://bugs.ruby-lang.org/issues/11120) for details. The fix is to apply all patches the same way. Mini Profiler by default will apply its patch using method aliasing, but you can change that to module prepend by adding `require: ['prepend_net_http_patch']` to the gem line as shown above.
|
83
|
+
|
54
84
|
#### Rails and manual initialization
|
55
85
|
|
56
86
|
In case you need to make sure rack_mini_profiler is initialized after all other gems, or you want to execute some code before rack_mini_profiler required:
|
@@ -315,7 +345,7 @@ Option|Default|Description
|
|
315
345
|
pre_authorize_cb|Rails: dev only<br>Rack: always on|A lambda callback that returns true to make mini_profiler visible on a given request.
|
316
346
|
position|`'top-left'`|Display mini_profiler on `'top-right'`, `'top-left'`, `'bottom-right'` or `'bottom-left'`.
|
317
347
|
skip_paths|`[]`|Paths that skip profiling.
|
318
|
-
skip_schema_queries|Rails dev: `
|
348
|
+
skip_schema_queries|Rails dev: `true`<br>Othwerwise: `false`|`true` to skip schema queries.
|
319
349
|
auto_inject|`true`|`true` to inject the miniprofiler script in the page.
|
320
350
|
backtrace_ignores|`[]`|Regexes of lines to be removed from backtraces.
|
321
351
|
backtrace_includes|Rails: `[/^\/?(app\|config\|lib\|test)/]`<br>Rack: `[]`|Regexes of lines to keep in backtraces.
|
@@ -331,32 +361,13 @@ html_container|`body`|The HTML container (as a jQuery selector) to inject the mi
|
|
331
361
|
show_total_sql_count|`false`|Displays the total number of SQL executions.
|
332
362
|
enable_advanced_debugging_tools|`false`|Enables sensitive debugging tools that can be used via the UI. In production we recommend keeping this disabled as memory and environment debugging tools can expose contents of memory that may contain passwords.
|
333
363
|
|
334
|
-
###
|
335
|
-
|
336
|
-
If you are using `Rack::Deflate` with rails and rack-mini-profiler in its default configuration,
|
337
|
-
`Rack::MiniProfiler` will be injected (as always) at position 0 in the middleware stack. This
|
338
|
-
will result in it attempting to inject html into the already-compressed response body. To fix this,
|
339
|
-
the middleware ordering must be overriden.
|
340
|
-
|
341
|
-
To do this, first add `, require: false` to the gemfile entry for rack-mini-profiler.
|
342
|
-
This will prevent the railtie from running. Then, customize the initialization
|
343
|
-
in the initializer like so:
|
344
|
-
|
345
|
-
```ruby
|
346
|
-
require 'rack-mini-profiler'
|
347
|
-
|
348
|
-
Rack::MiniProfilerRails.initialize!(Rails.application)
|
349
|
-
|
350
|
-
Rails.application.middleware.delete(Rack::MiniProfiler)
|
351
|
-
Rails.application.middleware.insert_after(Rack::Deflater, Rack::MiniProfiler)
|
352
|
-
```
|
353
|
-
|
354
|
-
Deleting the middleware and then reinserting it is a bit inelegant, but
|
355
|
-
a sufficient and costless solution. It is possible that rack-mini-profiler might
|
356
|
-
support this scenario more directly if it is found that
|
357
|
-
there is significant need for this confriguration or that
|
358
|
-
the above recipe causes problems.
|
364
|
+
### Using MiniProfiler with `Rack::Deflate` middleware
|
359
365
|
|
366
|
+
If you are using `Rack::Deflate` with Rails and `rack-mini-profiler` in its default configuration,
|
367
|
+
`Rack::MiniProfiler` will be injected (as always) at position 0 in the middleware stack,
|
368
|
+
which means it will run after `Rack::Deflate` on response processing. To prevent attempting to inject
|
369
|
+
HTML in already compressed response body MiniProfiler will suppress compression by setting
|
370
|
+
`identity` encoding in `Accept-Encoding` request header.
|
360
371
|
|
361
372
|
## Special query strings
|
362
373
|
|
@@ -393,6 +404,16 @@ if JSON.const_defined?(:Pure)
|
|
393
404
|
end
|
394
405
|
```
|
395
406
|
|
407
|
+
## Development
|
408
|
+
|
409
|
+
If you want to contribute to this project, that's great, thank you! You can run the following rake task:
|
410
|
+
|
411
|
+
```
|
412
|
+
$ bundle exec rake client_dev
|
413
|
+
```
|
414
|
+
|
415
|
+
which will start a local Sinatra server at `http://localhost:9292` where you'll be able to preview your changes. Refreshing the page should be enough to see any changes you make to files in the `lib/html` directory.
|
416
|
+
|
396
417
|
## Running the Specs
|
397
418
|
|
398
419
|
```
|
data/lib/html/includes.css
CHANGED
@@ -207,8 +207,7 @@
|
|
207
207
|
top: 0px; }
|
208
208
|
.profiler-results.profiler-top.profiler-left {
|
209
209
|
left: 0px; }
|
210
|
-
.profiler-results.profiler-top.profiler-left.profiler-no-controls .profiler-totals,
|
211
|
-
.profiler-results.profiler-top.profiler-left.profiler-no-controls .profiler-result:last-child .profiler-button,
|
210
|
+
.profiler-results.profiler-top.profiler-left.profiler-no-controls .profiler-totals, .profiler-results.profiler-top.profiler-left.profiler-no-controls .profiler-result:last-child .profiler-button,
|
212
211
|
.profiler-results.profiler-top.profiler-left .profiler-controls {
|
213
212
|
-webkit-border-bottom-right-radius: 10px;
|
214
213
|
-moz-border-radius-bottomright: 10px;
|
@@ -218,8 +217,7 @@
|
|
218
217
|
border-right: 1px solid #888; }
|
219
218
|
.profiler-results.profiler-top.profiler-right {
|
220
219
|
right: 0px; }
|
221
|
-
.profiler-results.profiler-top.profiler-right.profiler-no-controls .profiler-totals,
|
222
|
-
.profiler-results.profiler-top.profiler-right.profiler-no-controls .profiler-result:last-child .profiler-button,
|
220
|
+
.profiler-results.profiler-top.profiler-right.profiler-no-controls .profiler-totals, .profiler-results.profiler-top.profiler-right.profiler-no-controls .profiler-result:last-child .profiler-button,
|
223
221
|
.profiler-results.profiler-top.profiler-right .profiler-controls {
|
224
222
|
-webkit-border-bottom-left-radius: 10px;
|
225
223
|
-moz-border-radius-bottomleft: 10px;
|
@@ -231,8 +229,7 @@
|
|
231
229
|
bottom: 0px; }
|
232
230
|
.profiler-results.profiler-bottom.profiler-left {
|
233
231
|
left: 0px; }
|
234
|
-
.profiler-results.profiler-bottom.profiler-left.profiler-no-controls .profiler-totals,
|
235
|
-
.profiler-results.profiler-bottom.profiler-left.profiler-no-controls .profiler-result:first-child .profiler-button,
|
232
|
+
.profiler-results.profiler-bottom.profiler-left.profiler-no-controls .profiler-totals, .profiler-results.profiler-bottom.profiler-left.profiler-no-controls .profiler-result:first-child .profiler-button,
|
236
233
|
.profiler-results.profiler-bottom.profiler-left .profiler-controls {
|
237
234
|
-webkit-border-top-right-radius: 10px;
|
238
235
|
-moz-border-radius-topright: 10px;
|
@@ -242,8 +239,7 @@
|
|
242
239
|
border-right: 1px solid #888; }
|
243
240
|
.profiler-results.profiler-bottom.profiler-right {
|
244
241
|
right: 0px; }
|
245
|
-
.profiler-results.profiler-bottom.profiler-right.profiler-no-controls .profiler-totals,
|
246
|
-
.profiler-results.profiler-bottom.profiler-right.profiler-no-controls .profiler-result:first-child .profiler-button,
|
242
|
+
.profiler-results.profiler-bottom.profiler-right.profiler-no-controls .profiler-totals, .profiler-results.profiler-bottom.profiler-right.profiler-no-controls .profiler-result:first-child .profiler-button,
|
247
243
|
.profiler-results.profiler-bottom.profiler-right .profiler-controls {
|
248
244
|
-webkit-border-bottom-top-radius: 10px;
|
249
245
|
-moz-border-radius-topleft: 10px;
|
@@ -349,7 +345,6 @@
|
|
349
345
|
@media print {
|
350
346
|
.profiler-results {
|
351
347
|
display: none; } }
|
352
|
-
|
353
348
|
.profiler-queries-bg {
|
354
349
|
z-index: 2147483642;
|
355
350
|
display: none;
|
data/lib/html/includes.js
CHANGED
@@ -108,18 +108,8 @@ var MiniProfiler = (function() {
|
|
108
108
|
// ie is buggy strip out functions
|
109
109
|
var copy = {
|
110
110
|
navigation: {},
|
111
|
-
timing:
|
111
|
+
timing: clientPerformance.timing.toJSON()
|
112
112
|
};
|
113
|
-
var timing = extend({}, clientPerformance.timing);
|
114
|
-
|
115
|
-
for (p in timing) {
|
116
|
-
if (
|
117
|
-
timing.hasOwnProperty(p) &&
|
118
|
-
!(typeof timing[p] === "function")
|
119
|
-
) {
|
120
|
-
copy.timing[p] = timing[p];
|
121
|
-
}
|
122
|
-
}
|
123
113
|
|
124
114
|
if (clientPerformance.navigation) {
|
125
115
|
copy.navigation.redirectCount =
|
@@ -147,10 +137,13 @@ var MiniProfiler = (function() {
|
|
147
137
|
(function() {
|
148
138
|
var request = new XMLHttpRequest();
|
149
139
|
var url = options.path + "results";
|
150
|
-
var params =
|
151
|
-
|
152
|
-
|
153
|
-
|
140
|
+
var params = {
|
141
|
+
id: id,
|
142
|
+
clientPerformance: clientPerformance,
|
143
|
+
clientProbes: clientProbes,
|
144
|
+
popup: 1
|
145
|
+
};
|
146
|
+
var queryParam = toQueryString(params);
|
154
147
|
request.open("POST", url, true);
|
155
148
|
|
156
149
|
request.onload = function() {
|
@@ -172,24 +165,45 @@ var MiniProfiler = (function() {
|
|
172
165
|
"Content-Type",
|
173
166
|
"application/x-www-form-urlencoded"
|
174
167
|
);
|
175
|
-
request.send(
|
168
|
+
request.send(queryParam);
|
176
169
|
})();
|
177
170
|
}
|
178
171
|
}
|
179
172
|
};
|
180
173
|
|
181
|
-
var
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
174
|
+
var toQueryString = function toQueryString(data, parentKey) {
|
175
|
+
var result = [];
|
176
|
+
for (var key in data) {
|
177
|
+
var val = data[key];
|
178
|
+
var newKey = !parentKey ? key : parentKey + "[" + key + "]";
|
179
|
+
if (
|
180
|
+
typeof val === "object" &&
|
181
|
+
!Array.isArray(val) &&
|
182
|
+
val !== null &&
|
183
|
+
val !== undefined
|
184
|
+
) {
|
185
|
+
result[result.length] = toQueryString(val, newKey);
|
186
|
+
} else {
|
187
|
+
if (Array.isArray(val)) {
|
188
|
+
val.forEach(function(v) {
|
189
|
+
result[result.length] =
|
190
|
+
encodeURIComponent(newKey + "[]") + "=" + encodeURIComponent(v);
|
191
|
+
});
|
192
|
+
} else if (val === null || val === undefined) {
|
193
|
+
result[result.length] = encodeURIComponent(newKey) + "=";
|
194
|
+
} else {
|
195
|
+
result[result.length] =
|
196
|
+
encodeURIComponent(newKey) +
|
197
|
+
"=" +
|
198
|
+
encodeURIComponent(val.toString());
|
199
|
+
}
|
189
200
|
}
|
190
201
|
}
|
191
|
-
|
192
|
-
|
202
|
+
return result
|
203
|
+
.filter(function(element) {
|
204
|
+
return element && element.length > 0;
|
205
|
+
})
|
206
|
+
.join("&");
|
193
207
|
};
|
194
208
|
|
195
209
|
var renderTemplate = function renderTemplate(json) {
|
data/lib/html/includes.tmpl
CHANGED
@@ -128,8 +128,8 @@
|
|
128
128
|
{{? it.custom_link}}
|
129
129
|
<a href="{{= it.custom_link }}" class="profiler-custom-link" target="_blank">{{= it.custom_link_name }}</a>
|
130
130
|
{{?}}
|
131
|
-
{{? it.has_trivial_timings}}
|
132
|
-
<a class="profiler-toggle-trivial" data-show-on-load="{{= it.has_all_trivial_timings }}" title="toggles any rows with < {{= it.trivial_duration_threshold_milliseconds }} ms">
|
131
|
+
{{? it.page.has_trivial_timings}}
|
132
|
+
<a class="profiler-toggle-trivial" data-show-on-load="{{= it.page.has_all_trivial_timings }}" title="toggles any rows with < {{= it.page.trivial_duration_threshold_milliseconds }} ms">
|
133
133
|
show trivial
|
134
134
|
</a>
|
135
135
|
{{?}}
|
data/lib/html/vendor.js
CHANGED
@@ -11,7 +11,7 @@ var out=' <div class="profiler-result"> <div class="profiler-button ';if(it.has_
|
|
11
11
|
}
|
12
12
|
MiniProfiler.templates["linksTemplate"] = function anonymous(it
|
13
13
|
) {
|
14
|
-
var out=' <a href="'+( MiniProfiler.shareUrl(it.page.id) )+'" class="profiler-share-profiler-results" target="_blank">share</a> <a href="'+( MiniProfiler.moreUrl(it.timing.name) )+'" class="profiler-more-actions">more</a> ';if(it.custom_link){out+=' <a href="'+( it.custom_link )+'" class="profiler-custom-link" target="_blank">'+( it.custom_link_name )+'</a> ';}out+=' ';if(it.has_trivial_timings){out+=' <a class="profiler-toggle-trivial" data-show-on-load="'+( it.has_all_trivial_timings )+'" title="toggles any rows with < '+( it.trivial_duration_threshold_milliseconds )+' ms"> show trivial </a> ';}return out;
|
14
|
+
var out=' <a href="'+( MiniProfiler.shareUrl(it.page.id) )+'" class="profiler-share-profiler-results" target="_blank">share</a> <a href="'+( MiniProfiler.moreUrl(it.timing.name) )+'" class="profiler-more-actions">more</a> ';if(it.custom_link){out+=' <a href="'+( it.custom_link )+'" class="profiler-custom-link" target="_blank">'+( it.custom_link_name )+'</a> ';}out+=' ';if(it.page.has_trivial_timings){out+=' <a class="profiler-toggle-trivial" data-show-on-load="'+( it.page.has_all_trivial_timings )+'" title="toggles any rows with < '+( it.page.trivial_duration_threshold_milliseconds )+' ms"> show trivial </a> ';}return out;
|
15
15
|
}
|
16
16
|
MiniProfiler.templates["timingTemplate"] = function anonymous(it
|
17
17
|
) {
|
@@ -5,6 +5,11 @@ module Rack
|
|
5
5
|
class << self
|
6
6
|
|
7
7
|
include Rack::MiniProfiler::ProfilingMethods
|
8
|
+
attr_accessor :subscribe_sql_active_record
|
9
|
+
|
10
|
+
def patch_rails?
|
11
|
+
!!defined?(Rack::MINI_PROFILER_ENABLE_RAILS_PATCHES)
|
12
|
+
end
|
8
13
|
|
9
14
|
def generate_id
|
10
15
|
rand(36**20).to_s(36)
|
@@ -67,6 +72,17 @@ module Rack
|
|
67
72
|
This feature is disabled by default, to enable set the enable_advanced_debugging_tools option to true in Mini Profiler config.
|
68
73
|
TEXT
|
69
74
|
end
|
75
|
+
|
76
|
+
def binds_to_params(binds)
|
77
|
+
return if binds.nil? || config.max_sql_param_length == 0
|
78
|
+
# map ActiveRecord::Relation::QueryAttribute to [name, value]
|
79
|
+
params = binds.map { |c| c.kind_of?(Array) ? [c.first, c.last] : [c.name, c.value] }
|
80
|
+
if (skip = config.skip_sql_param_names)
|
81
|
+
params.map { |(n, v)| n =~ skip ? [n, nil] : [n, v] }
|
82
|
+
else
|
83
|
+
params
|
84
|
+
end
|
85
|
+
end
|
70
86
|
end
|
71
87
|
|
72
88
|
#
|
@@ -136,7 +152,7 @@ module Rack
|
|
136
152
|
resources_env = env.dup
|
137
153
|
resources_env['PATH_INFO'] = file_name
|
138
154
|
|
139
|
-
rack_file = Rack::File.new(MiniProfiler.resources_root, 'Cache-Control' =>
|
155
|
+
rack_file = Rack::File.new(MiniProfiler.resources_root, 'Cache-Control' => "max-age:#{cache_control_value}")
|
140
156
|
rack_file.call(resources_env)
|
141
157
|
end
|
142
158
|
|
@@ -292,6 +308,15 @@ module Rack
|
|
292
308
|
status, headers, body = @app.call(env)
|
293
309
|
end
|
294
310
|
end
|
311
|
+
elsif path == '/rack-mini-profiler/requests'
|
312
|
+
blank_page_html = <<~HTML
|
313
|
+
<html>
|
314
|
+
<head></head>
|
315
|
+
<body></body>
|
316
|
+
</html>
|
317
|
+
HTML
|
318
|
+
|
319
|
+
status, headers, body = [200, { 'Content-Type' => 'text/html' }, [blank_page_html.dup]]
|
295
320
|
else
|
296
321
|
status, headers, body = @app.call(env)
|
297
322
|
end
|
@@ -348,17 +373,6 @@ module Rack
|
|
348
373
|
return client_settings.handle_cookie(self.flamegraph(flamegraph))
|
349
374
|
end
|
350
375
|
|
351
|
-
if path == '/rack-mini-profiler/requests'
|
352
|
-
blank_page_html = <<~HTML
|
353
|
-
<html>
|
354
|
-
<head></head>
|
355
|
-
<body></body>
|
356
|
-
</html>
|
357
|
-
HTML
|
358
|
-
|
359
|
-
status, headers, body = [200, { 'Content-Type' => 'text/html' }, [blank_page_html.dup]]
|
360
|
-
end
|
361
|
-
|
362
376
|
begin
|
363
377
|
@storage.save(page_struct)
|
364
378
|
# no matter what it is, it should be unviewed, otherwise we will miss POST
|
@@ -657,5 +671,8 @@ Append the following to your query string:
|
|
657
671
|
current.inject_js = false
|
658
672
|
end
|
659
673
|
|
674
|
+
def cache_control_value
|
675
|
+
86400
|
676
|
+
end
|
660
677
|
end
|
661
678
|
end
|
@@ -33,7 +33,7 @@ module Rack
|
|
33
33
|
|
34
34
|
def set_unviewed(user, id)
|
35
35
|
key = user_key(user)
|
36
|
-
if redis.exists
|
36
|
+
if redis.call([:exists, prefixed_id(id)]) == 1
|
37
37
|
expire_at = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i + redis.ttl(prefixed_id(id))
|
38
38
|
redis.zadd(key, expire_at, id)
|
39
39
|
end
|
@@ -44,7 +44,7 @@ module Rack
|
|
44
44
|
key = user_key(user)
|
45
45
|
redis.del(key)
|
46
46
|
ids.each do |id|
|
47
|
-
if redis.exists
|
47
|
+
if redis.call([:exists, prefixed_id(id)]) == 1
|
48
48
|
expire_at = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i + redis.ttl(prefixed_id(id))
|
49
49
|
redis.zadd(key, expire_at, id)
|
50
50
|
end
|
@@ -11,7 +11,7 @@ module Rack
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
attr_accessor :children_duration
|
14
|
+
attr_accessor :children_duration, :start, :parent
|
15
15
|
|
16
16
|
def initialize(name, page, parent)
|
17
17
|
start_millis = (Process.clock_gettime(Process::CLOCK_MONOTONIC) * 1000).to_i - page[:started]
|
@@ -62,10 +62,6 @@ module Rack
|
|
62
62
|
self[:start_milliseconds]
|
63
63
|
end
|
64
64
|
|
65
|
-
def start
|
66
|
-
@start
|
67
|
-
end
|
68
|
-
|
69
65
|
def depth
|
70
66
|
self[:depth]
|
71
67
|
end
|
@@ -91,6 +87,20 @@ module Rack
|
|
91
87
|
end
|
92
88
|
end
|
93
89
|
|
90
|
+
def move_child(child, destination)
|
91
|
+
if index = self[:children].index(child)
|
92
|
+
self[:children].slice!(index)
|
93
|
+
self[:has_children] = self[:children].size > 0
|
94
|
+
|
95
|
+
destination[:children].push(child)
|
96
|
+
destination[:has_children] = true
|
97
|
+
|
98
|
+
child[:parent_timing_id] = destination[:id]
|
99
|
+
child.parent = destination
|
100
|
+
child.adjust_depth
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
94
104
|
def add_sql(query, elapsed_ms, page, params = nil, skip_backtrace = false, full_backtrace = false)
|
95
105
|
TimerStruct::Sql.new(query, elapsed_ms, page, self, params, skip_backtrace, full_backtrace).tap do |timer|
|
96
106
|
self[:sql_timings].push(timer)
|
@@ -102,6 +112,19 @@ module Rack
|
|
102
112
|
end
|
103
113
|
end
|
104
114
|
|
115
|
+
def move_sql(sql, destination)
|
116
|
+
if index = self[:sql_timings].index(sql)
|
117
|
+
self[:sql_timings].slice!(index)
|
118
|
+
self[:has_sql_timings] = self[:sql_timings].size > 0
|
119
|
+
self[:sql_timings_duration_milliseconds] -= sql[:duration_milliseconds]
|
120
|
+
destination[:sql_timings].push(sql)
|
121
|
+
destination[:has_sql_timings] = true
|
122
|
+
destination[:sql_timings_duration_milliseconds] += sql[:duration_milliseconds]
|
123
|
+
sql[:parent_timing_id] = destination[:id]
|
124
|
+
sql.parent = destination
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
105
128
|
def add_custom(type, elapsed_ms, page)
|
106
129
|
TimerStruct::Custom.new(type, elapsed_ms, page, self).tap do |timer|
|
107
130
|
timer[:parent_timing_id] = self[:id]
|
@@ -119,18 +142,37 @@ module Rack
|
|
119
142
|
end
|
120
143
|
end
|
121
144
|
|
145
|
+
def move_custom(type, custom, destination)
|
146
|
+
if index = self[:custom_timings][type]&.index(custom)
|
147
|
+
custom[:parent_timing_id] = destination[:id]
|
148
|
+
custom.parent = destination
|
149
|
+
self[:custom_timings][type].slice!(index)
|
150
|
+
if self[:custom_timings][type].size == 0
|
151
|
+
self[:custom_timings].delete(type)
|
152
|
+
self[:custom_timing_stats].delete(type)
|
153
|
+
else
|
154
|
+
self[:custom_timing_stats][type][:count] -= 1
|
155
|
+
self[:custom_timing_stats][type][:duration] -= custom[:duration_milliseconds]
|
156
|
+
end
|
157
|
+
destination[:custom_timings][type] ||= []
|
158
|
+
destination[:custom_timings][type].push(custom)
|
159
|
+
destination[:custom_timing_stats][type] ||= { count: 0, duration: 0.0 }
|
160
|
+
destination[:custom_timing_stats][type][:count] += 1
|
161
|
+
destination[:custom_timing_stats][type][:duration] += custom[:duration_milliseconds]
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
122
165
|
def record_time(milliseconds = nil)
|
123
166
|
milliseconds ||= (Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start) * 1000
|
124
167
|
self[:duration_milliseconds] = milliseconds
|
125
168
|
self[:is_trivial] = true if milliseconds < self[:trivial_duration_threshold_milliseconds]
|
126
|
-
self[:duration_without_children_milliseconds] = milliseconds -
|
127
|
-
|
128
|
-
if @parent
|
129
|
-
@parent.children_duration += milliseconds
|
130
|
-
end
|
131
|
-
|
169
|
+
self[:duration_without_children_milliseconds] = milliseconds - self[:children].sum(&:duration_ms)
|
132
170
|
end
|
133
171
|
|
172
|
+
def adjust_depth
|
173
|
+
self[:depth] = self.parent ? self.parent[:depth] + 1 : 0
|
174
|
+
self[:children].each(&:adjust_depth)
|
175
|
+
end
|
134
176
|
end
|
135
177
|
end
|
136
178
|
end
|
@@ -1,8 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
+
require_relative './railtie_methods'
|
4
5
|
|
5
6
|
module Rack::MiniProfilerRails
|
7
|
+
extend Rack::MiniProfilerRailsMethods
|
6
8
|
|
7
9
|
# call direct if needed to do a defer init
|
8
10
|
def self.initialize!(app)
|
@@ -28,6 +30,8 @@ module Rack::MiniProfilerRails
|
|
28
30
|
|
29
31
|
if serves_static_assets?(app)
|
30
32
|
c.skip_paths << app.config.assets.prefix
|
33
|
+
wp_assets_path = get_webpacker_assets_path()
|
34
|
+
c.skip_paths << wp_assets_path if wp_assets_path
|
31
35
|
end
|
32
36
|
|
33
37
|
unless Rails.env.development? || Rails.env.test?
|
@@ -55,17 +59,81 @@ module Rack::MiniProfilerRails
|
|
55
59
|
|
56
60
|
# Install the Middleware
|
57
61
|
app.middleware.insert(0, Rack::MiniProfiler)
|
62
|
+
c.enable_advanced_debugging_tools = Rails.env.development?
|
63
|
+
|
64
|
+
if ::Rack::MiniProfiler.patch_rails?
|
65
|
+
# Attach to various Rails methods
|
66
|
+
ActiveSupport.on_load(:action_controller) do
|
67
|
+
::Rack::MiniProfiler.profile_method(ActionController::Base, :process) { |action| "Executing action: #{action}" }
|
68
|
+
end
|
69
|
+
|
70
|
+
ActiveSupport.on_load(:action_view) do
|
71
|
+
::Rack::MiniProfiler.profile_method(ActionView::Template, :render) { |x, y| "Rendering: #{@virtual_path}" }
|
72
|
+
end
|
73
|
+
else
|
74
|
+
subscribe("start_processing.action_controller") do |name, start, finish, id, payload|
|
75
|
+
next if !should_measure?
|
76
|
+
|
77
|
+
current = Rack::MiniProfiler.current
|
78
|
+
description = "Executing action: #{payload[:action]}"
|
79
|
+
Thread.current[get_key(payload)] = current.current_timer
|
80
|
+
Rack::MiniProfiler.current.current_timer = current.current_timer.add_child(description)
|
81
|
+
end
|
82
|
+
|
83
|
+
subscribe("process_action.action_controller") do |name, start, finish, id, payload|
|
84
|
+
next if !should_measure?
|
85
|
+
|
86
|
+
key = get_key(payload)
|
87
|
+
parent_timer = Thread.current[key]
|
88
|
+
next if !parent_timer
|
89
|
+
|
90
|
+
Thread.current[key] = nil
|
91
|
+
Rack::MiniProfiler.current.current_timer.record_time
|
92
|
+
Rack::MiniProfiler.current.current_timer = parent_timer
|
93
|
+
end
|
94
|
+
|
95
|
+
subscribe("render_partial.action_view") do |name, start, finish, id, payload|
|
96
|
+
render_notification_handler(shorten_identifier(payload[:identifier]), finish, start)
|
97
|
+
end
|
58
98
|
|
59
|
-
|
60
|
-
|
61
|
-
|
99
|
+
subscribe("render_template.action_view") do |name, start, finish, id, payload|
|
100
|
+
render_notification_handler(shorten_identifier(payload[:identifier]), finish, start)
|
101
|
+
end
|
102
|
+
|
103
|
+
if Rack::MiniProfiler.subscribe_sql_active_record
|
104
|
+
# we don't want to subscribe if we've already patched a DB driver
|
105
|
+
# otherwise we would end up with 2 records for every query
|
106
|
+
subscribe("sql.active_record") do |name, start, finish, id, payload|
|
107
|
+
next if !should_measure?
|
108
|
+
next if payload[:name] =~ /SCHEMA/ && Rack::MiniProfiler.config.skip_schema_queries
|
109
|
+
|
110
|
+
Rack::MiniProfiler.record_sql(
|
111
|
+
payload[:sql],
|
112
|
+
(finish - start) * 1000,
|
113
|
+
Rack::MiniProfiler.binds_to_params(payload[:binds])
|
114
|
+
)
|
115
|
+
end
|
116
|
+
end
|
62
117
|
end
|
63
|
-
|
64
|
-
|
118
|
+
@already_initialized = true
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.subscribe(event, &blk)
|
122
|
+
if ActiveSupport::Notifications.respond_to?(:monotonic_subscribe)
|
123
|
+
ActiveSupport::Notifications.monotonic_subscribe(event) { |*args| blk.call(*args) }
|
124
|
+
else
|
125
|
+
ActiveSupport::Notifications.subscribe(event) do |name, start, finish, id, payload|
|
126
|
+
blk.call(name, start.to_f, finish.to_f, id, payload)
|
127
|
+
end
|
65
128
|
end
|
129
|
+
end
|
66
130
|
|
67
|
-
|
68
|
-
|
131
|
+
def self.get_key(payload)
|
132
|
+
"mini_profiler_parent_timer_#{payload[:controller]}_#{payload[:action]}".to_sym
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.shorten_identifier(identifier)
|
136
|
+
identifier.split('/').last(2).join('/')
|
69
137
|
end
|
70
138
|
|
71
139
|
def self.serves_static_assets?(app)
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rack::MiniProfilerRailsMethods
|
4
|
+
def render_notification_handler(name, finish, start, name_as_description: false)
|
5
|
+
return if !should_measure?
|
6
|
+
|
7
|
+
description = name_as_description ? name : "Rendering: #{name}"
|
8
|
+
current = Rack::MiniProfiler.current.current_timer
|
9
|
+
node = current.add_child(description)
|
10
|
+
duration = finish - start
|
11
|
+
duration_ms = duration * 1000
|
12
|
+
node.start -= duration
|
13
|
+
node[:start_milliseconds] -= duration_ms
|
14
|
+
node.record_time(duration_ms)
|
15
|
+
|
16
|
+
children_duration = 0
|
17
|
+
to_be_moved = { requests: [], sql: [], custom: {} }
|
18
|
+
current.children.each do |child|
|
19
|
+
next if child == node
|
20
|
+
if should_move?(child, node)
|
21
|
+
to_be_moved[:requests] << child
|
22
|
+
children_duration += child[:duration_milliseconds]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
node[:duration_without_children_milliseconds] = duration_ms - children_duration
|
26
|
+
to_be_moved[:requests].each { |req| current.move_child(req, node) }
|
27
|
+
|
28
|
+
current.sql_timings.each do |sql|
|
29
|
+
to_be_moved[:sql] << sql if should_move?(sql, node)
|
30
|
+
end
|
31
|
+
to_be_moved[:sql].each { |sql| current.move_sql(sql, node) }
|
32
|
+
|
33
|
+
current.custom_timings.each do |type, timings|
|
34
|
+
to_be_moved[:custom] = []
|
35
|
+
timings.each do |custom|
|
36
|
+
to_be_moved[:custom] << custom if should_move?(custom, node)
|
37
|
+
end
|
38
|
+
to_be_moved[:custom].each { |custom| current.move_custom(type, custom, node) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def should_measure?
|
43
|
+
current = Rack::MiniProfiler.current
|
44
|
+
current && current.measure
|
45
|
+
end
|
46
|
+
|
47
|
+
def should_move?(child, node)
|
48
|
+
start = :start_milliseconds
|
49
|
+
duration = :duration_milliseconds
|
50
|
+
child[start] >= node[start] &&
|
51
|
+
child[start] + child[duration] <= node[start] + node[duration]
|
52
|
+
end
|
53
|
+
|
54
|
+
def get_webpacker_assets_path
|
55
|
+
if defined?(Webpacker) && Webpacker.config.config_path.exist?
|
56
|
+
Webpacker.config.public_output_path.to_s.gsub(Webpacker.config.public_path.to_s, "")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
extend self
|
61
|
+
end
|
@@ -15,17 +15,6 @@ module Rack
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def binds_to_params(binds)
|
19
|
-
return if binds.nil? || Rack::MiniProfiler.config.max_sql_param_length == 0
|
20
|
-
# map ActiveRecord::Relation::QueryAttribute to [name, value]
|
21
|
-
params = binds.map { |c| c.kind_of?(Array) ? [c.first, c.last] : [c.name, c.value] }
|
22
|
-
if (skip = Rack::MiniProfiler.config.skip_sql_param_names)
|
23
|
-
params.map { |(n, v)| n =~ skip ? [n, nil] : [n, v] }
|
24
|
-
else
|
25
|
-
params
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
18
|
def log_with_miniprofiler(*args, &block)
|
30
19
|
return log_without_miniprofiler(*args, &block) unless SqlPatches.should_measure?
|
31
20
|
|
@@ -37,7 +26,7 @@ module Rack
|
|
37
26
|
return rval if Rack::MiniProfiler.config.skip_schema_queries && name =~ (/SCHEMA/)
|
38
27
|
|
39
28
|
elapsed_time = SqlPatches.elapsed_time(start)
|
40
|
-
Rack::MiniProfiler.record_sql(sql, elapsed_time, binds_to_params(binds))
|
29
|
+
Rack::MiniProfiler.record_sql(sql, elapsed_time, Rack::MiniProfiler.binds_to_params(binds))
|
41
30
|
rval
|
42
31
|
end
|
43
32
|
end
|
data/lib/patches/net_patches.rb
CHANGED
@@ -2,15 +2,25 @@
|
|
2
2
|
|
3
3
|
if (defined?(Net) && defined?(Net::HTTP))
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
request
|
8
|
-
|
9
|
-
|
5
|
+
if defined?(Rack::MINI_PROFILER_PREPEND_NET_HTTP_PATCH)
|
6
|
+
module NetHTTPWithMiniProfiler
|
7
|
+
def request(request, *args, &block)
|
8
|
+
Rack::MiniProfiler.step("Net::HTTP #{request.method} #{request.path}") do
|
9
|
+
super
|
10
|
+
end
|
10
11
|
end
|
11
12
|
end
|
12
|
-
|
13
|
-
|
13
|
+
Net::HTTP.prepend(NetHTTPWithMiniProfiler)
|
14
|
+
else
|
15
|
+
Net::HTTP.class_eval do
|
16
|
+
def request_with_mini_profiler(*args, &block)
|
17
|
+
request = args[0]
|
18
|
+
Rack::MiniProfiler.step("Net::HTTP #{request.method} #{request.path}") do
|
19
|
+
request_without_mini_profiler(*args, &block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
alias request_without_mini_profiler request
|
23
|
+
alias request request_with_mini_profiler
|
24
|
+
end
|
14
25
|
end
|
15
|
-
|
16
26
|
end
|
data/lib/patches/sql_patches.rb
CHANGED
@@ -23,18 +23,26 @@ class SqlPatches
|
|
23
23
|
((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time).to_f * 1000).round(1)
|
24
24
|
end
|
25
25
|
|
26
|
+
def self.patch_rails?
|
27
|
+
::Rack::MiniProfiler.patch_rails?
|
28
|
+
end
|
29
|
+
|
26
30
|
def self.sql_patches
|
27
31
|
patches = []
|
28
32
|
|
29
33
|
patches << 'mysql2' if defined?(Mysql2::Client) && Mysql2::Client.class == Class
|
30
34
|
patches << 'pg' if defined?(PG::Result) && PG::Result.class == Class
|
31
35
|
patches << 'oracle_enhanced' if defined?(ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter) && ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class == Class &&
|
32
|
-
SqlPatches.correct_version?('~> 1.5.0', ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter)
|
36
|
+
SqlPatches.correct_version?('~> 1.5.0', ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter) &&
|
37
|
+
patch_rails?
|
33
38
|
# if the adapters were directly patched, don't patch again
|
34
|
-
|
39
|
+
if !patches.empty?
|
40
|
+
Rack::MiniProfiler.subscribe_sql_active_record = false
|
41
|
+
return patches
|
42
|
+
end
|
35
43
|
patches << 'sequel' if defined?(Sequel::Database) && Sequel::Database.class == Class
|
36
|
-
patches << 'activerecord' if defined?(ActiveRecord) && ActiveRecord.class == Module
|
37
|
-
|
44
|
+
patches << 'activerecord' if defined?(ActiveRecord) && ActiveRecord.class == Module && patch_rails?
|
45
|
+
Rack::MiniProfiler.subscribe_sql_active_record = patches.empty? && !patch_rails?
|
38
46
|
patches
|
39
47
|
end
|
40
48
|
|
data/lib/rack-mini-profiler.rb
CHANGED
data/rack-mini-profiler.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.authors = ["Sam Saffron", "Robin Ward", "Aleks Totic"]
|
12
12
|
s.description = "Profiling toolkit for Rack applications with Rails integration. Client Side profiling, DB profiling and Server profiling."
|
13
13
|
s.email = "sam.saffron@gmail.com"
|
14
|
-
s.homepage = "
|
14
|
+
s.homepage = "https://miniprofiler.com"
|
15
15
|
s.license = "MIT"
|
16
16
|
s.files = [
|
17
17
|
'rack-mini-profiler.gemspec',
|
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
"CHANGELOG.md"
|
22
22
|
]
|
23
23
|
s.add_runtime_dependency 'rack', '>= 1.2.0'
|
24
|
-
s.required_ruby_version = '>= 2.
|
24
|
+
s.required_ruby_version = '>= 2.4.0'
|
25
25
|
|
26
26
|
s.metadata = {
|
27
27
|
'source_code_uri' => 'https://github.com/MiniProfiler/rack-mini-profiler',
|
@@ -30,7 +30,6 @@ Gem::Specification.new do |s|
|
|
30
30
|
|
31
31
|
s.add_development_dependency 'rake', '< 11'
|
32
32
|
s.add_development_dependency 'rack-test'
|
33
|
-
s.add_development_dependency 'activerecord', '~> 3.0'
|
34
33
|
s.add_development_dependency 'dalli'
|
35
34
|
s.add_development_dependency 'rspec', '~> 3.6.0'
|
36
35
|
s.add_development_dependency 'redis'
|
@@ -39,6 +38,10 @@ Gem::Specification.new do |s|
|
|
39
38
|
s.add_development_dependency 'rubocop'
|
40
39
|
s.add_development_dependency 'mini_racer'
|
41
40
|
s.add_development_dependency 'nokogiri'
|
41
|
+
s.add_development_dependency 'rubocop-discourse'
|
42
|
+
s.add_development_dependency 'listen'
|
43
|
+
s.add_development_dependency 'webpacker', '~> 5.1'
|
44
|
+
s.add_development_dependency 'rails', '~> 5.1'
|
42
45
|
|
43
46
|
s.require_paths = ["lib"]
|
44
47
|
end
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-mini-profiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
- Robin Ward
|
9
9
|
- Aleks Totic
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-
|
13
|
+
date: 2020-08-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|
@@ -54,20 +54,6 @@ dependencies:
|
|
54
54
|
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '0'
|
57
|
-
- !ruby/object:Gem::Dependency
|
58
|
-
name: activerecord
|
59
|
-
requirement: !ruby/object:Gem::Requirement
|
60
|
-
requirements:
|
61
|
-
- - "~>"
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
version: '3.0'
|
64
|
-
type: :development
|
65
|
-
prerelease: false
|
66
|
-
version_requirements: !ruby/object:Gem::Requirement
|
67
|
-
requirements:
|
68
|
-
- - "~>"
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
version: '3.0'
|
71
57
|
- !ruby/object:Gem::Dependency
|
72
58
|
name: dalli
|
73
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -180,6 +166,62 @@ dependencies:
|
|
180
166
|
- - ">="
|
181
167
|
- !ruby/object:Gem::Version
|
182
168
|
version: '0'
|
169
|
+
- !ruby/object:Gem::Dependency
|
170
|
+
name: rubocop-discourse
|
171
|
+
requirement: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: '0'
|
176
|
+
type: :development
|
177
|
+
prerelease: false
|
178
|
+
version_requirements: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
- !ruby/object:Gem::Dependency
|
184
|
+
name: listen
|
185
|
+
requirement: !ruby/object:Gem::Requirement
|
186
|
+
requirements:
|
187
|
+
- - ">="
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
type: :development
|
191
|
+
prerelease: false
|
192
|
+
version_requirements: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '0'
|
197
|
+
- !ruby/object:Gem::Dependency
|
198
|
+
name: webpacker
|
199
|
+
requirement: !ruby/object:Gem::Requirement
|
200
|
+
requirements:
|
201
|
+
- - "~>"
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
version: '5.1'
|
204
|
+
type: :development
|
205
|
+
prerelease: false
|
206
|
+
version_requirements: !ruby/object:Gem::Requirement
|
207
|
+
requirements:
|
208
|
+
- - "~>"
|
209
|
+
- !ruby/object:Gem::Version
|
210
|
+
version: '5.1'
|
211
|
+
- !ruby/object:Gem::Dependency
|
212
|
+
name: rails
|
213
|
+
requirement: !ruby/object:Gem::Requirement
|
214
|
+
requirements:
|
215
|
+
- - "~>"
|
216
|
+
- !ruby/object:Gem::Version
|
217
|
+
version: '5.1'
|
218
|
+
type: :development
|
219
|
+
prerelease: false
|
220
|
+
version_requirements: !ruby/object:Gem::Requirement
|
221
|
+
requirements:
|
222
|
+
- - "~>"
|
223
|
+
- !ruby/object:Gem::Version
|
224
|
+
version: '5.1'
|
183
225
|
description: Profiling toolkit for Rack applications with Rails integration. Client
|
184
226
|
Side profiling, DB profiling and Server profiling.
|
185
227
|
email: sam.saffron@gmail.com
|
@@ -191,6 +233,7 @@ extra_rdoc_files:
|
|
191
233
|
files:
|
192
234
|
- CHANGELOG.md
|
193
235
|
- README.md
|
236
|
+
- lib/enable_rails_patches.rb
|
194
237
|
- lib/generators/rack_profiler/USAGE
|
195
238
|
- lib/generators/rack_profiler/install_generator.rb
|
196
239
|
- lib/generators/rack_profiler/templates/rack_profiler.rb
|
@@ -223,6 +266,7 @@ files:
|
|
223
266
|
- lib/mini_profiler/timer_struct/sql.rb
|
224
267
|
- lib/mini_profiler/version.rb
|
225
268
|
- lib/mini_profiler_rails/railtie.rb
|
269
|
+
- lib/mini_profiler_rails/railtie_methods.rb
|
226
270
|
- lib/patches/db/activerecord.rb
|
227
271
|
- lib/patches/db/mongo.rb
|
228
272
|
- lib/patches/db/moped.rb
|
@@ -237,15 +281,16 @@ files:
|
|
237
281
|
- lib/patches/db/sequel.rb
|
238
282
|
- lib/patches/net_patches.rb
|
239
283
|
- lib/patches/sql_patches.rb
|
284
|
+
- lib/prepend_net_http_patch.rb
|
240
285
|
- lib/rack-mini-profiler.rb
|
241
286
|
- rack-mini-profiler.gemspec
|
242
|
-
homepage:
|
287
|
+
homepage: https://miniprofiler.com
|
243
288
|
licenses:
|
244
289
|
- MIT
|
245
290
|
metadata:
|
246
291
|
source_code_uri: https://github.com/MiniProfiler/rack-mini-profiler
|
247
292
|
changelog_uri: https://github.com/MiniProfiler/rack-mini-profiler/blob/master/CHANGELOG.md
|
248
|
-
post_install_message:
|
293
|
+
post_install_message:
|
249
294
|
rdoc_options: []
|
250
295
|
require_paths:
|
251
296
|
- lib
|
@@ -253,7 +298,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
253
298
|
requirements:
|
254
299
|
- - ">="
|
255
300
|
- !ruby/object:Gem::Version
|
256
|
-
version: 2.
|
301
|
+
version: 2.4.0
|
257
302
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
258
303
|
requirements:
|
259
304
|
- - ">="
|
@@ -261,7 +306,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
261
306
|
version: '0'
|
262
307
|
requirements: []
|
263
308
|
rubygems_version: 3.0.3
|
264
|
-
signing_key:
|
309
|
+
signing_key:
|
265
310
|
specification_version: 4
|
266
311
|
summary: Profiles loading speed for rack applications.
|
267
312
|
test_files: []
|