rack-mini-profiler 2.3.1 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +9 -5
- data/lib/html/includes.js +4 -1
- data/lib/html/includes.tmpl +3 -0
- data/lib/html/vendor.js +1 -1
- data/lib/mini_profiler/asset_version.rb +1 -1
- data/lib/mini_profiler/client_settings.rb +3 -3
- data/lib/mini_profiler/config.rb +16 -0
- data/lib/mini_profiler/profiler.rb +71 -42
- data/lib/mini_profiler/storage/abstract_store.rb +1 -1
- data/lib/mini_profiler/timer_struct/page.rb +9 -3
- data/lib/mini_profiler/version.rb +1 -1
- data/lib/mini_profiler_rails/railtie.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2984e9dec3cda4d5b86a4ed3b8300725207ba826b6a064402b23dcf04b0d5a51
|
4
|
+
data.tar.gz: 4a05074c124ac23085c08f4ae5389b71ef7b85687c40c5e5594dee4884d87632
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b29d4a47e99d03489251752bfe57a2b64235400b5ffb9f867738bfb9d165f63ddeeb559fc4edf9a60c91fe2d579b04ee473db1b2c7846ab823580d8b9b5e88c1
|
7
|
+
data.tar.gz: 3a0768401c048801bf4adb22792fbdb2643d5b5e0174f92149df96c8ae2ab79d0c504e9e2146d72cc45068df6b88ebc675ef11431d47c17a5b929f375a1e6d74
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -171,6 +171,10 @@ To generate [flamegraphs](http://samsaffron.com/archive/2013/03/19/flame-graphs-
|
|
171
171
|
* add the [**stackprof**](https://rubygems.org/gems/stackprof) gem to your Gemfile
|
172
172
|
* visit a page in your app with `?pp=flamegraph`
|
173
173
|
|
174
|
+
To store flamegraph data for later viewing, append the `?pp=async-flamegraph` parameter. The request will return as normal.
|
175
|
+
Flamegraph data for this request, and all subsequent requests made by this page (based on the `REFERER` header) will be stored.
|
176
|
+
'flamegraph' links will appear for these requests in the MiniProfiler UI.
|
177
|
+
|
174
178
|
### Memory Profiling
|
175
179
|
|
176
180
|
Memory allocations can be measured (using the [memory_profiler](https://github.com/SamSaffron/memory_profiler) gem)
|
@@ -197,7 +201,7 @@ There are two additional `pp` options that can be used to analyze memory which d
|
|
197
201
|
|
198
202
|
In a complex web application, it's possible for a request to trigger rare conditions that result in poor performance. Mini Profiler ships with a feature to help detect those rare conditions and fix them. It works by enabling invisible profiling on one request every N requests, and saving the performance metrics that are collected during the request (a.k.a snapshot of the request) so that they can be viewed later. To turn this feature on, set the `snapshot_every_n_requests` config to a value larger than 0. The larger the value is, the less frequently requests are profiled.
|
199
203
|
|
200
|
-
Mini Profiler will exclude requests that are made to
|
204
|
+
Mini Profiler will exclude requests that are made to skipped paths (see `skip_paths` config below) from being sampled. Additionally, if profiling is enabled for a request that later finishes with a non-2xx status code, Mini Profiler will discard the snapshot and not save it (this behavior may change in the future).
|
201
205
|
|
202
206
|
After enabling snapshots sampling, you can see the snapshots that have been collected at `/mini-profiler-resources/snapshots` (or if you changed the `base_url_path` config, substitute `mini-profiler-resources` with your value of the config). You'll see on that page a table where each row represents a group of snapshots with the duration of the worst snapshot in that group. The worst snapshot in a group is defined as the snapshot whose request took longer than all of the snapshots in the same group. Snapshots grouped by HTTP method and path of the request, and if your application is a Rails app, Mini Profiler will try to convert the path to `controller#action` and group by that instead of request path. Clicking on a group will display the snapshots of that group sorted from worst to best. From there, you can click on a snapshot's ID to see the snapshot with all the performance metrics that were collected.
|
203
207
|
|
@@ -235,21 +239,21 @@ rack-mini-profiler is designed with production profiling in mind. To enable that
|
|
235
239
|
|
236
240
|
Note:
|
237
241
|
|
238
|
-
Out-of-the-box we will initialize the `authorization_mode` to `:
|
242
|
+
Out-of-the-box we will initialize the `authorization_mode` to `:allow_authorized` in production. However, in some cases we may not be able to do it:
|
239
243
|
|
240
|
-
- If you are running in development or test we will not enable
|
244
|
+
- If you are running in development or test we will not enable the explicit authorization mode
|
241
245
|
- If you use `require: false` on rack_mini_profiler we are unlikely to be able to run the railtie
|
242
246
|
- If you are running outside of rails we will not run the railtie
|
243
247
|
|
244
248
|
In those cases use:
|
245
249
|
|
246
250
|
```ruby
|
247
|
-
Rack::MiniProfiler.config.authorization_mode = :
|
251
|
+
Rack::MiniProfiler.config.authorization_mode = :allow_authorized
|
248
252
|
```
|
249
253
|
|
250
254
|
When deciding to fully profile a page mini profiler consults with the `authorization_mode`
|
251
255
|
|
252
|
-
By default in production we attempt to set the authorization mode to `:
|
256
|
+
By default in production we attempt to set the authorization mode to `:allow_authorized` meaning that end user will only be able to see requests where somewhere `Rack::MiniProfiler.authorize_request` is invoked.
|
253
257
|
|
254
258
|
In development we run in the `:allow_all` authorization mode meaning every request is profiled and displayed to the end user.
|
255
259
|
|
data/lib/html/includes.js
CHANGED
@@ -401,7 +401,7 @@ var _MiniProfiler = (function() {
|
|
401
401
|
var px = button.offsetTop - 1,
|
402
402
|
// position next to the button we clicked
|
403
403
|
windowHeight = window.innerHeight,
|
404
|
-
maxHeight = windowHeight - 40; // make sure the popup doesn't extend below the fold
|
404
|
+
maxHeight = windowHeight - px - 40; // make sure the popup doesn't extend below the fold
|
405
405
|
|
406
406
|
popup.style[options.renderVerticalPosition] = "".concat(px, "px");
|
407
407
|
popup.style.maxHeight = "".concat(maxHeight, "px");
|
@@ -1213,6 +1213,9 @@ var _MiniProfiler = (function() {
|
|
1213
1213
|
shareUrl: function shareUrl(id) {
|
1214
1214
|
return options.path + "results?id=" + id;
|
1215
1215
|
},
|
1216
|
+
flamegraphUrl: function flamegrapgUrl(id) {
|
1217
|
+
return options.path + "flamegraph?id=" + id;
|
1218
|
+
},
|
1216
1219
|
moreUrl: function moreUrl(requestName) {
|
1217
1220
|
var requestParts = requestName.split(" ");
|
1218
1221
|
var linkSrc =
|
data/lib/html/includes.tmpl
CHANGED
@@ -142,6 +142,9 @@
|
|
142
142
|
<script id="linksTemplate" type="text/x-dot-tmpl">
|
143
143
|
<a href="{{= MiniProfiler.shareUrl(it.page.id) }}" class="profiler-share-profiler-results" target="_blank">share</a>
|
144
144
|
<a href="{{= MiniProfiler.moreUrl(it.timing.name) }}" class="profiler-more-actions">more</a>
|
145
|
+
{{? it.page.has_flamegraph}}
|
146
|
+
<a href="{{= MiniProfiler.flamegraphUrl(it.page.id) }}" class="profiler-show-flamegraph" target="_blank">flamegraph</a>
|
147
|
+
{{?}}
|
145
148
|
{{? it.custom_link}}
|
146
149
|
<a href="{{= it.custom_link }}" class="profiler-custom-link" target="_blank">{{= it.custom_link_name }}</a>
|
147
150
|
{{?}}
|
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.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;
|
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.page.has_flamegraph){out+=' <a href="'+( MiniProfiler.flamegraphUrl(it.page.id) )+'" class="profiler-show-flamegraph" target="_blank">flamegraph</a> ';}out+=' ';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
|
) {
|
@@ -42,7 +42,7 @@ module Rack
|
|
42
42
|
def handle_cookie(result)
|
43
43
|
status, headers, _body = result
|
44
44
|
|
45
|
-
if (MiniProfiler.config.authorization_mode == :
|
45
|
+
if (MiniProfiler.config.authorization_mode == :allow_authorized && !MiniProfiler.request_authorized?)
|
46
46
|
# this is non-obvious, don't kill the profiling cookie on errors or short requests
|
47
47
|
# this ensures that stuff that never reaches the rails stack does not kill profiling
|
48
48
|
if status.to_i >= 200 && status.to_i < 300 && ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - @start) > 0.1)
|
@@ -59,7 +59,7 @@ module Rack
|
|
59
59
|
|
60
60
|
tokens_changed = false
|
61
61
|
|
62
|
-
if MiniProfiler.request_authorized? && MiniProfiler.config.authorization_mode == :
|
62
|
+
if MiniProfiler.request_authorized? && MiniProfiler.config.authorization_mode == :allow_authorized
|
63
63
|
@allowed_tokens ||= @store.allowed_tokens
|
64
64
|
tokens_changed = !@orig_auth_tokens || ((@allowed_tokens - @orig_auth_tokens).length > 0)
|
65
65
|
end
|
@@ -90,7 +90,7 @@ module Rack
|
|
90
90
|
def has_valid_cookie?
|
91
91
|
valid_cookie = !@cookie.nil?
|
92
92
|
|
93
|
-
if (MiniProfiler.config.authorization_mode == :
|
93
|
+
if (MiniProfiler.config.authorization_mode == :allow_authorized) && valid_cookie
|
94
94
|
begin
|
95
95
|
@allowed_tokens ||= @store.allowed_tokens
|
96
96
|
rescue => e
|
data/lib/mini_profiler/config.rb
CHANGED
@@ -86,6 +86,22 @@ module Rack
|
|
86
86
|
|
87
87
|
attr_reader :assets_url
|
88
88
|
|
89
|
+
# redefined - since the accessor defines it first
|
90
|
+
undef :authorization_mode=
|
91
|
+
def authorization_mode=(mode)
|
92
|
+
if mode == :whitelist
|
93
|
+
warn "[DEPRECATION] `:whitelist` authorization mode is deprecated. Please use `:allow_authorized` instead."
|
94
|
+
|
95
|
+
mode = :allow_authorized
|
96
|
+
end
|
97
|
+
|
98
|
+
warn <<~DEP unless mode == :allow_authorized || mode == :allow_all
|
99
|
+
[DEPRECATION] unknown authorization mode #{mode}. Expected `:allow_all` or `:allow_authorized`.
|
100
|
+
DEP
|
101
|
+
|
102
|
+
@authorization_mode = mode
|
103
|
+
end
|
104
|
+
|
89
105
|
def assets_url=(lmbda)
|
90
106
|
if defined?(Rack::MiniProfilerRails)
|
91
107
|
Rack::MiniProfilerRails.create_engine
|
@@ -182,6 +182,7 @@ module Rack
|
|
182
182
|
|
183
183
|
return serve_results(env) if file_name.eql?('results')
|
184
184
|
return handle_snapshots_request(env) if file_name.eql?('snapshots')
|
185
|
+
return serve_flamegraph(env) if file_name.eql?('flamegraph')
|
185
186
|
|
186
187
|
resources_env = env.dup
|
187
188
|
resources_env['PATH_INFO'] = file_name
|
@@ -213,7 +214,7 @@ module Rack
|
|
213
214
|
def call(env)
|
214
215
|
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
215
216
|
client_settings = ClientSettings.new(env, @storage, start)
|
216
|
-
MiniProfiler.deauthorize_request if @config.authorization_mode == :
|
217
|
+
MiniProfiler.deauthorize_request if @config.authorization_mode == :allow_authorized
|
217
218
|
|
218
219
|
status = headers = body = nil
|
219
220
|
query_string = env['QUERY_STRING']
|
@@ -239,7 +240,7 @@ module Rack
|
|
239
240
|
skip_it = (@config.pre_authorize_cb && !@config.pre_authorize_cb.call(env))
|
240
241
|
|
241
242
|
if skip_it || (
|
242
|
-
@config.authorization_mode == :
|
243
|
+
@config.authorization_mode == :allow_authorized &&
|
243
244
|
!client_settings.has_valid_cookie?
|
244
245
|
)
|
245
246
|
if take_snapshot?(path)
|
@@ -281,6 +282,15 @@ module Rack
|
|
281
282
|
# profile memory
|
282
283
|
if query_string =~ /pp=profile-memory/
|
283
284
|
return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
|
285
|
+
|
286
|
+
unless defined?(MemoryProfiler) && MemoryProfiler.respond_to?(:report)
|
287
|
+
message = "Please install the memory_profiler gem and require it: add gem 'memory_profiler' to your Gemfile"
|
288
|
+
_, _, body = @app.call(env)
|
289
|
+
body.close if body.respond_to? :close
|
290
|
+
|
291
|
+
return client_settings.handle_cookie(text_result(message))
|
292
|
+
end
|
293
|
+
|
284
294
|
query_params = Rack::Utils.parse_nested_query(query_string)
|
285
295
|
options = {
|
286
296
|
ignore_files: query_params['memory_profiler_ignore_files'],
|
@@ -336,11 +346,12 @@ module Rack
|
|
336
346
|
# Prevent response body from being compressed
|
337
347
|
env['HTTP_ACCEPT_ENCODING'] = 'identity' if config.suppress_encoding
|
338
348
|
|
339
|
-
if query_string =~ /pp=flamegraph/
|
349
|
+
if query_string =~ /pp=(async-)?flamegraph/ || env['HTTP_REFERER'] =~ /pp=async-flamegraph/
|
340
350
|
unless defined?(StackProf) && StackProf.respond_to?(:run)
|
341
|
-
|
342
|
-
|
343
|
-
|
351
|
+
headers = { 'Content-Type' => 'text/html' }
|
352
|
+
message = "Please install the stackprof gem and require it: add gem 'stackprof' to your Gemfile"
|
353
|
+
body.close if body.respond_to? :close
|
354
|
+
return client_settings.handle_cookie([500, headers, message])
|
344
355
|
else
|
345
356
|
# do not sully our profile with mini profiler timings
|
346
357
|
current.measure = false
|
@@ -379,7 +390,7 @@ module Rack
|
|
379
390
|
|
380
391
|
skip_it = current.discard
|
381
392
|
|
382
|
-
if (config.authorization_mode == :
|
393
|
+
if (config.authorization_mode == :allow_authorized && !MiniProfiler.request_authorized?)
|
383
394
|
skip_it = true
|
384
395
|
end
|
385
396
|
|
@@ -420,9 +431,12 @@ module Rack
|
|
420
431
|
page_struct[:user] = user(env)
|
421
432
|
page_struct[:root].record_time((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000)
|
422
433
|
|
423
|
-
if flamegraph
|
434
|
+
if flamegraph && query_string =~ /pp=flamegraph/
|
424
435
|
body.close if body.respond_to? :close
|
425
436
|
return client_settings.handle_cookie(self.flamegraph(flamegraph, path))
|
437
|
+
elsif flamegraph # async-flamegraph
|
438
|
+
page_struct[:has_flamegraph] = true
|
439
|
+
page_struct[:flamegraph] = flamegraph
|
426
440
|
end
|
427
441
|
|
428
442
|
begin
|
@@ -639,13 +653,14 @@ Append the following to your query string:
|
|
639
653
|
#{make_link "full-backtrace", env} #{"(*) " if client_settings.backtrace_full?}: enable full backtraces for SQL executed (use pp=normal-backtrace to disable)
|
640
654
|
#{make_link "disable", env} : disable profiling for this session
|
641
655
|
#{make_link "enable", env} : enable profiling for this session (if previously disabled)
|
642
|
-
#{make_link "profile-gc", env} : perform gc profiling on this request, analyzes ObjectSpace generated by request
|
656
|
+
#{make_link "profile-gc", env} : perform gc profiling on this request, analyzes ObjectSpace generated by request
|
643
657
|
#{make_link "profile-memory", env} : requires the memory_profiler gem, new location based report
|
644
|
-
#{make_link "flamegraph", env} :
|
658
|
+
#{make_link "flamegraph", env} : a graph representing sampled activity (requires the stackprof gem).
|
659
|
+
#{make_link "async-flamegraph", env} : store flamegraph data for this page and all its AJAX requests. Flamegraph links will be available in the mini-profiler UI (requires the stackprof gem).
|
645
660
|
#{make_link "flamegraph&flamegraph_sample_rate=1", env}: creates a flamegraph with the specified sample rate (in ms). Overrides value set in config
|
646
|
-
#{make_link "flamegraph_embed", env} :
|
647
|
-
#{make_link "trace-exceptions", env} :
|
648
|
-
#{make_link "analyze-memory", env} :
|
661
|
+
#{make_link "flamegraph_embed", env} : a graph representing sampled activity (requires the stackprof gem), embedded resources for use on an intranet.
|
662
|
+
#{make_link "trace-exceptions", env} : will return all the spots where your application raises exceptions
|
663
|
+
#{make_link "analyze-memory", env} : will perform basic memory analysis of heap
|
649
664
|
</pre>
|
650
665
|
</body>
|
651
666
|
</html>
|
@@ -656,35 +671,31 @@ Append the following to your query string:
|
|
656
671
|
|
657
672
|
def flamegraph(graph, path)
|
658
673
|
headers = { 'Content-Type' => 'text/html' }
|
659
|
-
|
660
|
-
html
|
661
|
-
|
662
|
-
<
|
663
|
-
<
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
<
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
[200, headers, [html]]
|
685
|
-
else
|
686
|
-
[200, headers, [graph]]
|
687
|
-
end
|
674
|
+
html = <<~HTML
|
675
|
+
<!DOCTYPE html>
|
676
|
+
<html>
|
677
|
+
<head>
|
678
|
+
<style>
|
679
|
+
body { margin: 0; height: 100vh; }
|
680
|
+
#speedscope-iframe { width: 100%; height: 100%; border: none; }
|
681
|
+
</style>
|
682
|
+
</head>
|
683
|
+
<body>
|
684
|
+
<script type="text/javascript">
|
685
|
+
var graph = #{JSON.generate(graph)};
|
686
|
+
var json = JSON.stringify(graph);
|
687
|
+
var blob = new Blob([json], { type: 'text/plain' });
|
688
|
+
var objUrl = encodeURIComponent(URL.createObjectURL(blob));
|
689
|
+
var iframe = document.createElement('IFRAME');
|
690
|
+
iframe.setAttribute('id', 'speedscope-iframe');
|
691
|
+
document.body.appendChild(iframe);
|
692
|
+
var iframeUrl = '#{@config.base_url_path}speedscope/index.html#profileURL=' + objUrl + '&title=' + 'Flamegraph for #{CGI.escape(path)}';
|
693
|
+
iframe.setAttribute('src', iframeUrl);
|
694
|
+
</script>
|
695
|
+
</body>
|
696
|
+
</html>
|
697
|
+
HTML
|
698
|
+
[200, headers, [html]]
|
688
699
|
end
|
689
700
|
|
690
701
|
def ids(env)
|
@@ -815,6 +826,24 @@ Append the following to your query string:
|
|
815
826
|
response.finish
|
816
827
|
end
|
817
828
|
|
829
|
+
def serve_flamegraph(env)
|
830
|
+
request = Rack::Request.new(env)
|
831
|
+
id = request.params['id']
|
832
|
+
page_struct = @storage.load(id)
|
833
|
+
|
834
|
+
if !page_struct
|
835
|
+
id = ERB::Util.html_escape(id)
|
836
|
+
user_info = ERB::Util.html_escape(user(env))
|
837
|
+
return [404, {}, ["Request not found: #{id} - user #{user_info}"]]
|
838
|
+
end
|
839
|
+
|
840
|
+
if !page_struct[:flamegraph]
|
841
|
+
return [404, {}, ["No flamegraph available for #{ERB::Util.html_escape(id)}"]]
|
842
|
+
end
|
843
|
+
|
844
|
+
self.flamegraph(page_struct[:flamegraph], page_struct[:request_path])
|
845
|
+
end
|
846
|
+
|
818
847
|
def rails_route_from_path(path, method)
|
819
848
|
if defined?(Rails) && defined?(ActionController::RoutingError)
|
820
849
|
hash = Rails.application.routes.recognize_path(path, method: method)
|
@@ -36,7 +36,7 @@ module Rack
|
|
36
36
|
""
|
37
37
|
end
|
38
38
|
|
39
|
-
# a list of tokens that are permitted to access profiler in
|
39
|
+
# a list of tokens that are permitted to access profiler in explicit mode
|
40
40
|
def allowed_tokens
|
41
41
|
raise NotImplementedError.new("allowed_tokens is not implemented")
|
42
42
|
end
|
@@ -87,7 +87,9 @@ module Rack
|
|
87
87
|
executed_non_queries: 0,
|
88
88
|
custom_timing_names: [],
|
89
89
|
custom_timing_stats: {},
|
90
|
-
custom_fields: {}
|
90
|
+
custom_fields: {},
|
91
|
+
has_flamegraph: false,
|
92
|
+
flamegraph: nil
|
91
93
|
)
|
92
94
|
self[:request_method] = env['REQUEST_METHOD']
|
93
95
|
self[:request_path] = env['PATH_INFO']
|
@@ -111,12 +113,16 @@ module Rack
|
|
111
113
|
@attributes[:root]
|
112
114
|
end
|
113
115
|
|
116
|
+
def attributes_to_serialize
|
117
|
+
@attributes.keys - [:flamegraph]
|
118
|
+
end
|
119
|
+
|
114
120
|
def to_json(*a)
|
115
|
-
::JSON.generate(@attributes.merge(
|
121
|
+
::JSON.generate(@attributes.slice(*attributes_to_serialize).merge(extra_json))
|
116
122
|
end
|
117
123
|
|
118
124
|
def as_json(options = nil)
|
119
|
-
super(options).merge!(extra_json)
|
125
|
+
super(options).slice(*attributes_to_serialize.map(&:to_s)).merge!(extra_json)
|
120
126
|
end
|
121
127
|
|
122
128
|
def extra_json
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-mini-profiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-04-29 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|