rack-mini-profiler 0.9.8 → 0.9.9
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.
Potentially problematic release.
This version of rack-mini-profiler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +40 -19
- data/lib/html/includes.css +12 -0
- data/lib/html/includes.js +53 -18
- data/lib/html/includes.less +17 -3
- data/lib/html/profile_handler.js +1 -1
- data/lib/mini_profiler/asset_version.rb +1 -1
- data/lib/mini_profiler/config.rb +2 -1
- data/lib/mini_profiler/gc_profiler.rb +18 -22
- data/lib/mini_profiler/profiler.rb +47 -63
- data/lib/mini_profiler/profiling_methods.rb +17 -11
- data/lib/mini_profiler/storage/file_store.rb +2 -0
- data/lib/mini_profiler/timer_struct/page.rb +8 -0
- data/lib/mini_profiler/timer_struct/request.rb +8 -0
- data/lib/mini_profiler/timer_struct/sql.rb +2 -2
- data/lib/mini_profiler/version.rb +1 -1
- data/lib/mini_profiler_rails/railtie.rb +17 -10
- data/lib/patches/db/activerecord.rb +2 -0
- data/lib/patches/db/mongo.rb +5 -1
- data/lib/patches/db/neo4j.rb +14 -0
- data/lib/patches/db/riak.rb +103 -0
- data/lib/patches/sql_patches.rb +3 -1
- data/rack-mini-profiler.gemspec +1 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 09e877779936ca60a9be72fc14ae574a450cd338
|
4
|
+
data.tar.gz: b53fc49ccabb1d8560c0ee8014199388fbf6749a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a5b9ced034cd204f59eb4be61c718a97960fed72a7e4484af99748b9ed62eb7a736a7ebc78668b46b71f743432c53758ced36f918a1c31859c7f965917f0c826
|
7
|
+
data.tar.gz: 3c97726e0f276ff8b1bd3cf220f64f4b9908ca950b4485f6c9978c05d3479582aa166314e0dbc2afb2c1cb478ebb6801f1459a9cb4bcc51df7cec7826ee96356
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
##
|
4
|
+
|
5
|
+
## 0.9.9 2016-03-06
|
6
|
+
|
7
|
+
- [FIX] removes alias_method_chain in favor of alias_method until Ruby 1.9.3 (@ayfredlund)
|
8
|
+
- [FIX] Dont block mongo when already patched for another db (@rrooding @kbrock)
|
9
|
+
- [FIX] get_profile_script when running under passenger configured with RailsBaseURI (@nspring)
|
10
|
+
- [FEATURE] Add support for neo4j (@ProGM)
|
11
|
+
- [FIX] ArgumentError: comparison of String with 200 failed (@paweljw)
|
12
|
+
- [FEATURE] Add support for Riak (@janx)
|
13
|
+
- [PERF] GC profiler much faster (@dgynn)
|
14
|
+
- [FIX] If local storage is disabled don't bomb out (@elia)
|
15
|
+
- [FIX] Create tmp directory when actually using it (@kbrock)
|
16
|
+
- [ADDED] Default collapse_results setting that collapses multiple timings on same page to a single one (@sam)
|
17
|
+
- [ADDED] Rack::MiniProfiler.profile_singleton_method (@kbrock)
|
18
|
+
- [CHANGE] Added Rack 2.0 support (and dropped support for Rack 1.1) (@dgynn)
|
19
|
+
|
3
20
|
## 0.9.8 - 2015-11-27 (Sam Saffron)
|
4
21
|
|
5
22
|
- [FEATURE] disable_env_dump config setting (@mathias)
|
data/README.md
CHANGED
@@ -66,11 +66,17 @@ end
|
|
66
66
|
|
67
67
|
```ruby
|
68
68
|
require 'rack-mini-profiler'
|
69
|
+
|
70
|
+
home = lambda { |env|
|
71
|
+
[200, {'Content-Type' => 'text/html'}, ["<html><body>hello!</body></html>"]]
|
72
|
+
}
|
73
|
+
|
69
74
|
builder = Rack::Builder.new do
|
70
75
|
use Rack::MiniProfiler
|
71
|
-
|
72
|
-
map('/') { run get }
|
76
|
+
map('/') { run home }
|
73
77
|
end
|
78
|
+
|
79
|
+
run builder
|
74
80
|
```
|
75
81
|
|
76
82
|
#### Sinatra
|
@@ -145,11 +151,11 @@ if Rails.env.production?
|
|
145
151
|
end
|
146
152
|
```
|
147
153
|
|
148
|
-
MemoryStore stores results in a processes heap - something that does not work well in a multi process environment.
|
149
|
-
FileStore stores results in the file system - something that may not work well in a multi machine environment.
|
150
|
-
RedisStore
|
154
|
+
`MemoryStore` stores results in a processes heap - something that does not work well in a multi process environment.
|
155
|
+
`FileStore` stores results in the file system - something that may not work well in a multi machine environment.
|
156
|
+
`RedisStore`/`MemcacheStore` work in multi process and multi machine environments (`RedisStore` only saves results for up to 24 hours so it won't continue to fill up Redis).
|
151
157
|
|
152
|
-
Additionally you may implement an AbstractStore for your own provider.
|
158
|
+
Additionally you may implement an `AbstractStore` for your own provider.
|
153
159
|
|
154
160
|
### User result segregation
|
155
161
|
|
@@ -167,6 +173,17 @@ Rack::MiniProfiler.config.user_provider = Proc.new{ |env| CurrentUser.get(env) }
|
|
167
173
|
|
168
174
|
The string this function returns should be unique for each user on the system (for anonymous you may need to fall back to ip address)
|
169
175
|
|
176
|
+
### Profiling specific methods
|
177
|
+
|
178
|
+
You can increase the granularity of profiling by measuring the performance of specific methods. Add methods of interest to an initializer.
|
179
|
+
|
180
|
+
```ruby
|
181
|
+
Rails.application.config.to_prepare do
|
182
|
+
::Rack::MiniProfiler.profile_singleton_method(User, :non_admins) { |a| "executing all_non_admins" }
|
183
|
+
::Rack::MiniProfiler.profile_method(User, :favorite_post) { |a| "executing favorite_post" }
|
184
|
+
end
|
185
|
+
```
|
186
|
+
|
170
187
|
### Configuration Options
|
171
188
|
|
172
189
|
You can set configuration options using the configuration accessor on `Rack::MiniProfiler`.
|
@@ -178,19 +195,23 @@ Rack::MiniProfiler.config.start_hidden = true
|
|
178
195
|
```
|
179
196
|
The available configuration options are:
|
180
197
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
198
|
+
Option|Default|Description
|
199
|
+
-------|---|--------
|
200
|
+
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.
|
201
|
+
position|`'left'`|Display mini_profiler on `'right'` or `'left'`.
|
202
|
+
skip_paths|`[]`|Paths that skip profiling.
|
203
|
+
skip_schema_queries|Rails dev: `'true'`<br>Othwerwise: `'false'`|`'true'` to log schema queries.
|
204
|
+
auto_inject|`true`|`true` to inject the miniprofiler script in the page.
|
205
|
+
backtrace_ignores|`[]`|Regexes of lines to be removed from backtraces.
|
206
|
+
backtrace_includes|Rails: `[/^\/?(app|config|lib|test)/]`<br>Rack: `[]`|Regexes of lines to keep in backtraces.
|
207
|
+
backtrace_remove|rails: `Rails.root`<br>Rack: `nil`|A string or regex to remove part of each line in the backtrace.
|
208
|
+
toggle_shortcut|Alt+P|Keyboard shortcut to toggle the mini_profiler's visibility. See [jquery.hotkeys](https://github.com/jeresig/jquery.hotkeys).
|
209
|
+
start_hidden|`false`|`false` to make mini_profiler visible on page load.
|
210
|
+
backtrace_threshold_ms|`0`|Minimum SQL query elapsed time before a backtrace is recorded. Backtrace recording can take a couple of milliseconds on rubies earlier than 2.0, impacting performance for very small queries.
|
211
|
+
flamegraph_sample_rate|`0.5ms`|How often to capture stack traces for flamegraphs.
|
212
|
+
disable_env_dump|`false`|`true` disables `?pp=env`, which prevents sending ENV vars over HTTP.
|
213
|
+
base_url_path|`'/mini-profiler-resources/'`|Path for assets; added as a prefix when naming assets and sought when responding to requests.
|
214
|
+
collapse_results|`true`|If multiple timing results exist in a single page, collapse them till clicked.
|
194
215
|
|
195
216
|
### Custom middleware ordering (required if using `Rack::Deflate` with Rails)
|
196
217
|
|
data/lib/html/includes.css
CHANGED
@@ -267,6 +267,7 @@
|
|
267
267
|
.profiler-results.profiler-left {
|
268
268
|
left: 0px;
|
269
269
|
}
|
270
|
+
.profiler-results.profiler-left.profiler-no-controls .profiler-totals,
|
270
271
|
.profiler-results.profiler-left.profiler-no-controls .profiler-result:last-child .profiler-button,
|
271
272
|
.profiler-results.profiler-left .profiler-controls {
|
272
273
|
-webkit-border-bottom-right-radius: 10px;
|
@@ -280,6 +281,7 @@
|
|
280
281
|
.profiler-results.profiler-right {
|
281
282
|
right: 0px;
|
282
283
|
}
|
284
|
+
.profiler-results.profiler-right.profiler-no-controls .profiler-totals,
|
283
285
|
.profiler-results.profiler-right.profiler-no-controls .profiler-result:last-child .profiler-button,
|
284
286
|
.profiler-results.profiler-right .profiler-controls {
|
285
287
|
-webkit-border-bottom-left-radius: 10px;
|
@@ -316,6 +318,16 @@
|
|
316
318
|
color: #fff;
|
317
319
|
font-weight: normal;
|
318
320
|
}
|
321
|
+
.profiler-results .profiler-totals .profiler-reqs {
|
322
|
+
font-family: Consolas, monospace, serif;
|
323
|
+
font-size: 10px;
|
324
|
+
margin-left: 6px;
|
325
|
+
}
|
326
|
+
.profiler-results .profiler-totals .profiler-reqs:before {
|
327
|
+
font-family: Consolas, monospace, serif;
|
328
|
+
content: "×";
|
329
|
+
margin-right: 1px;
|
330
|
+
}
|
319
331
|
.profiler-results .profiler-controls {
|
320
332
|
display: block;
|
321
333
|
font-size: 12px;
|
data/lib/html/includes.js
CHANGED
@@ -10,9 +10,12 @@ var MiniProfiler = (function () {
|
|
10
10
|
ajaxStartTime
|
11
11
|
;
|
12
12
|
|
13
|
-
var hasLocalStorage = function () {
|
13
|
+
var hasLocalStorage = function (keyPrefix) {
|
14
14
|
try {
|
15
|
-
|
15
|
+
// attempt to save to localStorage as Safari private windows will throw an error
|
16
|
+
localStorage[keyPrefix+'-test'] = '1';
|
17
|
+
localStorage.removeItem(keyPrefix+'-test');
|
18
|
+
return 'localStorage' in window && window['localStorage'] !== null ;
|
16
19
|
} catch (e) {
|
17
20
|
return false;
|
18
21
|
}
|
@@ -23,7 +26,7 @@ var MiniProfiler = (function () {
|
|
23
26
|
};
|
24
27
|
|
25
28
|
var save = function (keyPrefix, value) {
|
26
|
-
if (!hasLocalStorage()) { return; }
|
29
|
+
if (!hasLocalStorage(keyPrefix)) { return; }
|
27
30
|
|
28
31
|
// clear old keys with this prefix, if any
|
29
32
|
for (var i = 0; i < localStorage.length; i++) {
|
@@ -37,7 +40,7 @@ var MiniProfiler = (function () {
|
|
37
40
|
};
|
38
41
|
|
39
42
|
var load = function (keyPrefix) {
|
40
|
-
if (!hasLocalStorage()) { return null; }
|
43
|
+
if (!hasLocalStorage(keyPrefix)) { return null; }
|
41
44
|
|
42
45
|
return localStorage[getVersionedKey(keyPrefix)];
|
43
46
|
};
|
@@ -62,7 +65,7 @@ var MiniProfiler = (function () {
|
|
62
65
|
};
|
63
66
|
|
64
67
|
var getClientPerformance = function() {
|
65
|
-
return window.performance
|
68
|
+
return window.performance === null ? null : window.performance;
|
66
69
|
};
|
67
70
|
|
68
71
|
var fetchResults = function (ids) {
|
@@ -86,7 +89,7 @@ var MiniProfiler = (function () {
|
|
86
89
|
|
87
90
|
clientPerformance = getClientPerformance();
|
88
91
|
|
89
|
-
if (clientPerformance
|
92
|
+
if (clientPerformance !== null) {
|
90
93
|
// ie is buggy strip out functions
|
91
94
|
var copy = { navigation: {}, timing: {} };
|
92
95
|
|
@@ -114,7 +117,7 @@ var MiniProfiler = (function () {
|
|
114
117
|
|
115
118
|
}
|
116
119
|
}
|
117
|
-
} else if (ajaxStartTime
|
120
|
+
} else if (ajaxStartTime !== null && clientProbes && clientProbes.length > 0) {
|
118
121
|
clientPerformance = { timing: { navigationStart: ajaxStartTime.getTime() } };
|
119
122
|
ajaxStartTime = null;
|
120
123
|
}
|
@@ -146,9 +149,39 @@ var MiniProfiler = (function () {
|
|
146
149
|
return $('#profilerTemplate').tmpl(json);
|
147
150
|
};
|
148
151
|
|
152
|
+
var totalsControl;
|
153
|
+
var reqs = 0;
|
154
|
+
var totalTime = 0;
|
155
|
+
|
149
156
|
var buttonShow = function (json) {
|
150
157
|
var result = renderTemplate(json);
|
151
158
|
|
159
|
+
totalTime += parseFloat(json.duration_milliseconds, 10);
|
160
|
+
reqs++;
|
161
|
+
|
162
|
+
if (!controls && reqs > 1 && options.collapseResults) {
|
163
|
+
if (!totalsControl) {
|
164
|
+
container.find('.profiler-result').hide();
|
165
|
+
|
166
|
+
totalsControl = $("<div class='profiler-result'><div class='profiler-button profiler-totals'></div></div>");
|
167
|
+
totalsControl.appendTo(container);
|
168
|
+
totalsControl.click(function(){
|
169
|
+
totalsControl.parent().find('.profiler-result').show();
|
170
|
+
totalsControl.hide();
|
171
|
+
options.collapseResults = false;
|
172
|
+
});
|
173
|
+
|
174
|
+
totalsControl.find('.profiler-button').show();
|
175
|
+
}
|
176
|
+
|
177
|
+
var reqsHtml = reqs > 1 ? ("<span class='profiler-reqs'>" + reqs + "</span>") : "";
|
178
|
+
totalsControl.find('.profiler-button').html("<span class='profiler-number'>" +
|
179
|
+
totalTime.toFixed(1) + "</span> <span class='profiler-unit'>ms</span>" +
|
180
|
+
reqsHtml);
|
181
|
+
|
182
|
+
result.hide();
|
183
|
+
}
|
184
|
+
|
152
185
|
if (controls)
|
153
186
|
result.insertBefore(controls);
|
154
187
|
else
|
@@ -480,7 +513,7 @@ var MiniProfiler = (function () {
|
|
480
513
|
PageRequestManager.add_endRequest(function (sender, args) {
|
481
514
|
if (args) {
|
482
515
|
var response = args.get_response();
|
483
|
-
if (response.get_responseAvailable() && response._xmlHttpRequest
|
516
|
+
if (response.get_responseAvailable() && response._xmlHttpRequest !== null) {
|
484
517
|
var stringIds = args.get_response().getResponseHeader('X-MiniProfiler-Ids');
|
485
518
|
if (stringIds) {
|
486
519
|
var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
|
@@ -557,14 +590,14 @@ var MiniProfiler = (function () {
|
|
557
590
|
}
|
558
591
|
}
|
559
592
|
|
560
|
-
if (this.miniprofiler.prev_onreadystatechange
|
593
|
+
if (this.miniprofiler.prev_onreadystatechange !== null)
|
561
594
|
return this.miniprofiler.prev_onreadystatechange.apply(this, arguments);
|
562
595
|
};
|
563
596
|
}
|
564
597
|
}
|
565
598
|
|
566
599
|
return _send.apply(this, arguments);
|
567
|
-
}
|
600
|
+
};
|
568
601
|
}
|
569
602
|
|
570
603
|
// some elements want to be hidden on certain doc events
|
@@ -594,11 +627,12 @@ var MiniProfiler = (function () {
|
|
594
627
|
var maxTraces = parseInt(script.getAttribute('data-max-traces'), 10);
|
595
628
|
}
|
596
629
|
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
630
|
+
var collapseResults = script.getAttribute('data-collapse-results') === 'true';
|
631
|
+
var trivial = script.getAttribute('data-trivial') === 'true';
|
632
|
+
var children = script.getAttribute('data-children') === 'true';
|
633
|
+
var controls = script.getAttribute('data-controls') === 'true';
|
634
|
+
var authorized = script.getAttribute('data-authorized') === 'true';
|
635
|
+
var startHidden = script.getAttribute('data-start-hidden') === 'true';
|
602
636
|
|
603
637
|
return {
|
604
638
|
ids: ids,
|
@@ -612,7 +646,8 @@ var MiniProfiler = (function () {
|
|
612
646
|
currentId: currentId,
|
613
647
|
authorized: authorized,
|
614
648
|
toggleShortcut: toggleShortcut,
|
615
|
-
startHidden: startHidden
|
649
|
+
startHidden: startHidden,
|
650
|
+
collapseResults: collapseResults
|
616
651
|
};
|
617
652
|
})();
|
618
653
|
|
@@ -842,7 +877,7 @@ var MiniProfiler = (function () {
|
|
842
877
|
var processTimes = function (elem, parent) {
|
843
878
|
var duration = { start: elem.start_milliseconds, finish: (elem.start_milliseconds + elem.duration_milliseconds) };
|
844
879
|
elem.richTiming = [duration];
|
845
|
-
if (parent
|
880
|
+
if (parent !== null) {
|
846
881
|
elem.parent = parent;
|
847
882
|
elem.parent.richTiming = removeDuration(elem.parent.richTiming, duration);
|
848
883
|
}
|
@@ -877,7 +912,7 @@ var MiniProfiler = (function () {
|
|
877
912
|
|
878
913
|
var determineGap = function (gap, node, match) {
|
879
914
|
var overlap = determineOverlap(gap, node);
|
880
|
-
if (match
|
915
|
+
if (match === null || overlap > match.duration) {
|
881
916
|
match = { name: node.name, duration: overlap };
|
882
917
|
}
|
883
918
|
else if (match.name == node.name) {
|
data/lib/html/includes.less
CHANGED
@@ -247,7 +247,7 @@
|
|
247
247
|
}
|
248
248
|
|
249
249
|
// ajaxed-in results will be appended to this
|
250
|
-
.profiler-results
|
250
|
+
.profiler-results
|
251
251
|
{
|
252
252
|
z-index:@zindex + 3;
|
253
253
|
position:fixed;
|
@@ -258,7 +258,7 @@
|
|
258
258
|
&.profiler-left {
|
259
259
|
left:0px;
|
260
260
|
|
261
|
-
&.profiler-no-controls .profiler-result:last-child .profiler-button, .profiler-controls {
|
261
|
+
&.profiler-no-controls .profiler-totals, &.profiler-no-controls .profiler-result:last-child .profiler-button, .profiler-controls {
|
262
262
|
-webkit-border-bottom-right-radius: @radius;
|
263
263
|
-moz-border-radius-bottomright: @radius;
|
264
264
|
border-bottom-right-radius: @radius;
|
@@ -272,7 +272,7 @@
|
|
272
272
|
&.profiler-right {
|
273
273
|
right:0px;
|
274
274
|
|
275
|
-
&.profiler-no-controls .profiler-result:last-child .profiler-button, .profiler-controls {
|
275
|
+
&.profiler-no-controls .profiler-totals, &.profiler-no-controls .profiler-result:last-child .profiler-button, .profiler-controls {
|
276
276
|
-webkit-border-bottom-left-radius: @radius;
|
277
277
|
-moz-border-radius-bottomleft: @radius;
|
278
278
|
border-bottom-left-radius: @radius;
|
@@ -306,6 +306,20 @@
|
|
306
306
|
}
|
307
307
|
}
|
308
308
|
|
309
|
+
|
310
|
+
.profiler-totals {
|
311
|
+
.profiler-reqs {
|
312
|
+
font-family: @codeFonts;
|
313
|
+
font-size: 10px;
|
314
|
+
margin-left: 6px;
|
315
|
+
&:before {
|
316
|
+
font-family: @codeFonts;
|
317
|
+
content: "×";
|
318
|
+
margin-right: 1px;
|
319
|
+
}
|
320
|
+
}
|
321
|
+
}
|
322
|
+
|
309
323
|
.profiler-controls {
|
310
324
|
display: block;
|
311
325
|
font-size:12px;
|
data/lib/html/profile_handler.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
<script async type="text/javascript" id="mini-profiler" src="{path}includes.js?v={version}" data-version="{version}" data-path="{path}" data-current-id="{currentId}" data-ids="{ids}" data-position="{position}" data-trivial="{showTrivial}" data-children="{showChildren}" data-max-traces="{maxTracesToShow}" data-controls="{showControls}" data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}" data-start-hidden="{startHidden}"></script>
|
1
|
+
<script async type="text/javascript" id="mini-profiler" src="{path}includes.js?v={version}" data-version="{version}" data-path="{path}" data-current-id="{currentId}" data-ids="{ids}" data-position="{position}" data-trivial="{showTrivial}" data-children="{showChildren}" data-max-traces="{maxTracesToShow}" data-controls="{showControls}" data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}" data-start-hidden="{startHidden}" data-collapse-results="{collapseResults}"></script>
|
data/lib/mini_profiler/config.rb
CHANGED
@@ -18,7 +18,7 @@ module Rack
|
|
18
18
|
:flamegraph_sample_rate, :logger, :position, :pre_authorize_cb,
|
19
19
|
:skip_paths, :skip_schema_queries, :start_hidden, :storage,
|
20
20
|
:storage_failure, :storage_instance, :storage_options, :toggle_shortcut,
|
21
|
-
:user_provider
|
21
|
+
:user_provider, :collapse_results
|
22
22
|
|
23
23
|
# Deprecated options
|
24
24
|
attr_accessor :use_existing_jquery
|
@@ -48,6 +48,7 @@ module Rack
|
|
48
48
|
end
|
49
49
|
@enabled = true
|
50
50
|
@disable_env_dump = false
|
51
|
+
@collapse_results = true
|
51
52
|
self
|
52
53
|
}
|
53
54
|
end
|
@@ -6,18 +6,15 @@ class Rack::MiniProfiler::GCProfiler
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def object_space_stats
|
9
|
-
stats =
|
10
|
-
ids =
|
9
|
+
stats = Hash.new(0).compare_by_identity
|
10
|
+
ids = Hash.new.compare_by_identity
|
11
11
|
|
12
12
|
@ignore << stats.__id__
|
13
13
|
@ignore << ids.__id__
|
14
14
|
|
15
|
-
i=0
|
16
15
|
ObjectSpace.each_object { |o|
|
17
16
|
begin
|
18
|
-
|
19
|
-
i += 1
|
20
|
-
stats[o.class] = i
|
17
|
+
stats[o.class] += 1
|
21
18
|
ids[o.__id__] = o if Integer === o.__id__
|
22
19
|
rescue NoMethodError
|
23
20
|
# protect against BasicObject
|
@@ -38,12 +35,12 @@ class Rack::MiniProfiler::GCProfiler
|
|
38
35
|
end
|
39
36
|
|
40
37
|
def diff_object_stats(before, after)
|
41
|
-
diff = {}
|
38
|
+
diff = {}.compare_by_identity
|
42
39
|
after.each do |k,v|
|
43
|
-
diff[k] = v -
|
40
|
+
diff[k] = v - before[k]
|
44
41
|
end
|
45
42
|
before.each do |k,v|
|
46
|
-
diff[k] = 0 - v unless after
|
43
|
+
diff[k] = 0 - v unless after.has_key?(k)
|
47
44
|
end
|
48
45
|
|
49
46
|
diff
|
@@ -97,11 +94,6 @@ class Rack::MiniProfiler::GCProfiler
|
|
97
94
|
# for memsize_of
|
98
95
|
require 'objspace'
|
99
96
|
|
100
|
-
body = [];
|
101
|
-
|
102
|
-
stat_before,stat_after,diff,string_analysis,
|
103
|
-
new_objects, memory_allocated, stat, memory_before, objects_before = nil
|
104
|
-
|
105
97
|
# clean up before
|
106
98
|
GC.start
|
107
99
|
stat = GC.stat
|
@@ -118,13 +110,17 @@ class Rack::MiniProfiler::GCProfiler
|
|
118
110
|
new_objects, memory_allocated = analyze_growth(stat_before[:ids], stat_after[:ids])
|
119
111
|
objects_before, memory_before = analyze_initial_state(stat_before[:ids])
|
120
112
|
|
113
|
+
body = []
|
121
114
|
|
122
115
|
body << "
|
123
116
|
Overview
|
124
|
-
|
125
|
-
Initial state: object count
|
117
|
+
--------
|
118
|
+
Initial state: object count: #{objects_before}
|
119
|
+
Memory allocated outside heap (bytes): #{memory_before}
|
126
120
|
|
127
|
-
GC Stats:
|
121
|
+
GC Stats:
|
122
|
+
--------
|
123
|
+
#{stat.map{|k,v| "#{k} : #{v}" }.sort!.join("\n")}
|
128
124
|
|
129
125
|
New bytes allocated outside of Ruby heaps: #{memory_allocated}
|
130
126
|
New objects: #{new_objects}
|
@@ -132,16 +128,16 @@ New objects: #{new_objects}
|
|
132
128
|
|
133
129
|
body << "
|
134
130
|
ObjectSpace delta caused by request:
|
135
|
-
|
136
|
-
diff.to_a.
|
137
|
-
body << "#{k} : #{v}\n"
|
131
|
+
-----------------------------------\n"
|
132
|
+
diff.to_a.delete_if{|_k, v| v == 0}.sort_by! { |_k, v| v }.reverse_each do |k,v|
|
133
|
+
body << "#{k} : #{v}\n"
|
138
134
|
end
|
139
135
|
|
140
136
|
body << "\n
|
141
137
|
ObjectSpace stats:
|
142
138
|
-----------------\n"
|
143
139
|
|
144
|
-
stat_after[:stats].to_a.
|
140
|
+
stat_after[:stats].to_a.sort_by!{ |_k, v| v }.reverse_each do |k,v|
|
145
141
|
body << "#{k} : #{v}\n"
|
146
142
|
end
|
147
143
|
|
@@ -150,7 +146,7 @@ ObjectSpace stats:
|
|
150
146
|
String stats:
|
151
147
|
------------\n"
|
152
148
|
|
153
|
-
string_analysis.to_a.
|
149
|
+
string_analysis.to_a.sort_by!{ |_k, v| -v }.take(1000).each do |string,count|
|
154
150
|
body << "#{count} : #{string}\n"
|
155
151
|
end
|
156
152
|
|
@@ -17,6 +17,10 @@ module Rack
|
|
17
17
|
@config ||= Config.default
|
18
18
|
end
|
19
19
|
|
20
|
+
def resources_root
|
21
|
+
@resources_root ||= ::File.expand_path("../../html", __FILE__)
|
22
|
+
end
|
23
|
+
|
20
24
|
def share_template
|
21
25
|
@share_template ||= ::File.read(::File.expand_path("../html/share.html", ::File.dirname(__FILE__)))
|
22
26
|
end
|
@@ -37,10 +41,11 @@ module Rack
|
|
37
41
|
|
38
42
|
def create_current(env={}, options={})
|
39
43
|
# profiling the request
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
+
context = Context.new
|
45
|
+
context.inject_js = config.auto_inject && (!env['HTTP_X_REQUESTED_WITH'].eql? 'XMLHttpRequest')
|
46
|
+
context.page_struct = TimerStruct::Page.new(env)
|
47
|
+
context.current_timer = context.page_struct[:root]
|
48
|
+
self.current = context
|
44
49
|
end
|
45
50
|
|
46
51
|
def authorize_request
|
@@ -92,24 +97,26 @@ module Rack
|
|
92
97
|
@storage.set_viewed(user(env), id)
|
93
98
|
end
|
94
99
|
|
95
|
-
result_json = page_struct.to_json
|
96
100
|
# If we're an XMLHttpRequest, serve up the contents as JSON
|
97
101
|
if request.xhr?
|
102
|
+
result_json = page_struct.to_json
|
98
103
|
[200, { 'Content-Type' => 'application/json'}, [result_json]]
|
99
104
|
else
|
100
|
-
|
101
105
|
# Otherwise give the HTML back
|
102
|
-
html =
|
103
|
-
html.gsub!(/\{path\}/, "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}")
|
104
|
-
html.gsub!(/\{version\}/, MiniProfiler::ASSET_VERSION)
|
105
|
-
html.gsub!(/\{json\}/, result_json)
|
106
|
-
html.gsub!(/\{includes\}/, get_profile_script(env))
|
107
|
-
html.gsub!(/\{name\}/, page_struct[:name])
|
108
|
-
html.gsub!(/\{duration\}/, "%.1f" % page_struct.duration_ms)
|
109
|
-
|
106
|
+
html = generate_html(page_struct, env)
|
110
107
|
[200, {'Content-Type' => 'text/html'}, [html]]
|
111
108
|
end
|
109
|
+
end
|
112
110
|
|
111
|
+
def generate_html(page_struct, env, result_json = page_struct.to_json)
|
112
|
+
html = MiniProfiler.share_template.dup
|
113
|
+
html.sub!('{path}', "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}")
|
114
|
+
html.sub!('{version}', MiniProfiler::ASSET_VERSION)
|
115
|
+
html.sub!('{json}', result_json)
|
116
|
+
html.sub!('{includes}', get_profile_script(env))
|
117
|
+
html.sub!('{name}', page_struct[:name])
|
118
|
+
html.sub!('{duration}', page_struct.duration_ms.round(1).to_s)
|
119
|
+
html
|
113
120
|
end
|
114
121
|
|
115
122
|
def serve_html(env)
|
@@ -117,21 +124,11 @@ module Rack
|
|
117
124
|
|
118
125
|
return serve_results(env) if file_name.eql?('results')
|
119
126
|
|
120
|
-
|
121
|
-
|
122
|
-
f = Rack::File.new nil
|
123
|
-
f.path = full_path
|
124
|
-
|
125
|
-
begin
|
126
|
-
f.cache_control = "max-age:86400"
|
127
|
-
f.serving env
|
128
|
-
rescue
|
129
|
-
# old versions of rack have a different api
|
130
|
-
status, headers, body = f.serving
|
131
|
-
headers.merge! 'Cache-Control' => "max-age:86400"
|
132
|
-
[status, headers, body]
|
133
|
-
end
|
127
|
+
resources_env = env.dup
|
128
|
+
resources_env['PATH_INFO'] = file_name
|
134
129
|
|
130
|
+
rack_file = Rack::File.new(MiniProfiler.resources_root, {'Cache-Control' => 'max-age:86400'})
|
131
|
+
rack_file.call(resources_env)
|
135
132
|
end
|
136
133
|
|
137
134
|
|
@@ -197,11 +194,13 @@ module Rack
|
|
197
194
|
client_settings.disable_profiling = false
|
198
195
|
end
|
199
196
|
|
197
|
+
# profile gc
|
200
198
|
if query_string =~ /pp=profile-gc/
|
201
199
|
current.measure = false if current
|
202
200
|
return Rack::MiniProfiler::GCProfiler.new.profile_gc(@app, env)
|
203
201
|
end
|
204
202
|
|
203
|
+
# profile memory
|
205
204
|
if query_string =~ /pp=profile-memory/
|
206
205
|
query_params = Rack::Utils.parse_nested_query(query_string)
|
207
206
|
options = {
|
@@ -291,7 +290,7 @@ module Rack
|
|
291
290
|
if (config.authorization_mode == :whitelist && !MiniProfiler.request_authorized?)
|
292
291
|
# this is non-obvious, don't kill the profiling cookie on errors or short requests
|
293
292
|
# this ensures that stuff that never reaches the rails stack does not kill profiling
|
294
|
-
if status >= 200 && status < 300 && ((Time.now - start) > 0.1)
|
293
|
+
if status.to_i >= 200 && status.to_i < 300 && ((Time.now - start) > 0.1)
|
295
294
|
client_settings.discard_cookie!(headers)
|
296
295
|
end
|
297
296
|
skip_it = true
|
@@ -389,39 +388,17 @@ module Rack
|
|
389
388
|
end
|
390
389
|
|
391
390
|
def inject(fragment, script)
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
regex = /<\/html>/i
|
401
|
-
close_tag = '</html>'
|
402
|
-
else
|
403
|
-
# implicit </body> and </html>. Don't do anything.
|
404
|
-
|
405
|
-
return fragment
|
406
|
-
end
|
407
|
-
|
408
|
-
matches = fragment.scan(regex).length
|
409
|
-
index = 1
|
410
|
-
fragment.gsub(regex) do
|
411
|
-
# though malformed there is an edge case where /body exists earlier in the html, work around
|
412
|
-
if index < matches
|
413
|
-
index += 1
|
414
|
-
close_tag
|
415
|
-
else
|
416
|
-
|
417
|
-
# if for whatever crazy reason we dont get a utf string,
|
418
|
-
# just force the encoding, no utf in the mp scripts anyway
|
419
|
-
if script.respond_to?(:encoding) && script.respond_to?(:force_encoding)
|
420
|
-
(script + close_tag).force_encoding(fragment.encoding)
|
421
|
-
else
|
422
|
-
script + close_tag
|
423
|
-
end
|
391
|
+
# find explicit or implicit body
|
392
|
+
index = fragment.rindex(/<\/body>/i) || fragment.rindex(/<\/html>/i)
|
393
|
+
if index
|
394
|
+
# if for whatever crazy reason we dont get a utf string,
|
395
|
+
# just force the encoding, no utf in the mp scripts anyway
|
396
|
+
if script.respond_to?(:encoding) && script.respond_to?(:force_encoding)
|
397
|
+
script = script.force_encoding(fragment.encoding)
|
424
398
|
end
|
399
|
+
fragment.insert(index, script)
|
400
|
+
else
|
401
|
+
fragment
|
425
402
|
end
|
426
403
|
end
|
427
404
|
|
@@ -594,7 +571,13 @@ Append the following to your query string:
|
|
594
571
|
# * you have disabled auto append behaviour throught :auto_inject => false flag
|
595
572
|
# * you do not want script to be automatically appended for the current page. You can also call cancel_auto_inject
|
596
573
|
def get_profile_script(env)
|
597
|
-
path = if
|
574
|
+
path = if ENV["PASSENGER_BASE_URI"] then
|
575
|
+
# added because the SCRIPT_NAME workaround below then
|
576
|
+
# breaks running under a prefix as permitted by Passenger.
|
577
|
+
"#{ENV['PASSENGER_BASE_URI']}#{@config.base_url_path}"
|
578
|
+
elsif env["action_controller.instance"]
|
579
|
+
# Rails engines break SCRIPT_NAME; the following appears to discard SCRIPT_NAME
|
580
|
+
# since url_for appears documented to return any String argument unmodified
|
598
581
|
env["action_controller.instance"].url_for("#{@config.base_url_path}")
|
599
582
|
else
|
600
583
|
"#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}"
|
@@ -610,7 +593,8 @@ Append the following to your query string:
|
|
610
593
|
:showControls => false,
|
611
594
|
:authorized => true,
|
612
595
|
:toggleShortcut => @config.toggle_shortcut,
|
613
|
-
:startHidden => @config.start_hidden
|
596
|
+
:startHidden => @config.start_hidden,
|
597
|
+
:collapseResults => @config.collapse_results
|
614
598
|
}
|
615
599
|
|
616
600
|
if current && current.page_struct
|
@@ -3,9 +3,9 @@ module Rack
|
|
3
3
|
module ProfilingMethods
|
4
4
|
|
5
5
|
def record_sql(query, elapsed_ms)
|
6
|
-
return unless current
|
6
|
+
return unless current && current.current_timer
|
7
7
|
c = current
|
8
|
-
c.current_timer.add_sql(query, elapsed_ms, c.page_struct, c.skip_backtrace, c.full_backtrace)
|
8
|
+
c.current_timer.add_sql(query, elapsed_ms, c.page_struct, c.skip_backtrace, c.full_backtrace)
|
9
9
|
end
|
10
10
|
|
11
11
|
def start_step(name)
|
@@ -26,10 +26,9 @@ module Rack
|
|
26
26
|
def step(name, opts = nil)
|
27
27
|
if current
|
28
28
|
parent_timer = current.current_timer
|
29
|
-
result = nil
|
30
29
|
current.current_timer = current_timer = current.current_timer.add_child(name)
|
31
30
|
begin
|
32
|
-
|
31
|
+
yield if block_given?
|
33
32
|
ensure
|
34
33
|
current_timer.record_time
|
35
34
|
current.current_timer = parent_timer
|
@@ -87,34 +86,37 @@ module Rack
|
|
87
86
|
end
|
88
87
|
end
|
89
88
|
|
90
|
-
result = nil
|
91
89
|
parent_timer = Rack::MiniProfiler.current.current_timer
|
92
90
|
|
93
91
|
if type == :counter
|
94
92
|
start = Time.now
|
95
93
|
begin
|
96
|
-
|
94
|
+
self.send without_profiling, *args, &orig
|
97
95
|
ensure
|
98
96
|
duration_ms = (Time.now - start).to_f * 1000
|
99
97
|
parent_timer.add_custom(name, duration_ms, Rack::MiniProfiler.current.page_struct )
|
100
98
|
end
|
101
99
|
else
|
102
|
-
page_struct = Rack::MiniProfiler.current.page_struct
|
103
|
-
|
104
100
|
Rack::MiniProfiler.current.current_timer = current_timer = parent_timer.add_child(name)
|
105
101
|
begin
|
106
|
-
|
102
|
+
self.send without_profiling, *args, &orig
|
107
103
|
ensure
|
108
104
|
current_timer.record_time
|
109
105
|
Rack::MiniProfiler.current.current_timer = parent_timer
|
110
106
|
end
|
111
107
|
end
|
112
|
-
|
113
|
-
result
|
114
108
|
end
|
115
109
|
klass.send :alias_method, method, with_profiling
|
116
110
|
end
|
117
111
|
|
112
|
+
def profile_singleton_method(klass, method, type = :profile, &blk)
|
113
|
+
profile_method(singleton_class(klass), method, type, &blk)
|
114
|
+
end
|
115
|
+
|
116
|
+
def unprofile_singleton_method(klass, method)
|
117
|
+
unprofile_method(singleton_class(klass), method)
|
118
|
+
end
|
119
|
+
|
118
120
|
# Add a custom timing. These are displayed similar to SQL/query time in
|
119
121
|
# columns expanding to the right.
|
120
122
|
#
|
@@ -140,6 +142,10 @@ module Rack
|
|
140
142
|
|
141
143
|
private
|
142
144
|
|
145
|
+
def singleton_class(klass)
|
146
|
+
class << klass; self; end
|
147
|
+
end
|
148
|
+
|
143
149
|
def clean_method_name(method)
|
144
150
|
method.to_s.gsub(/[\?\!]/, "")
|
145
151
|
end
|
@@ -44,6 +44,8 @@ module Rack
|
|
44
44
|
@path = args[:path]
|
45
45
|
@expires_in_seconds = args[:expires_in] || EXPIRES_IN_SECONDS
|
46
46
|
raise ArgumentError.new :path unless @path
|
47
|
+
FileUtils.mkdir_p(@path) unless ::File.exists?(@path)
|
48
|
+
|
47
49
|
@timer_struct_cache = FileCache.new(@path, "mp_timers")
|
48
50
|
@timer_struct_lock = Mutex.new
|
49
51
|
@user_view_cache = FileCache.new(@path, "mp_views")
|
@@ -40,10 +40,18 @@ module Rack
|
|
40
40
|
self[:root] = TimerStruct::Request.createRoot(name, self)
|
41
41
|
end
|
42
42
|
|
43
|
+
def name
|
44
|
+
@attributes[:name]
|
45
|
+
end
|
46
|
+
|
43
47
|
def duration_ms
|
44
48
|
@attributes[:root][:duration_milliseconds]
|
45
49
|
end
|
46
50
|
|
51
|
+
def duration_ms_in_sql
|
52
|
+
@attributes[:duration_milliseconds_in_sql]
|
53
|
+
end
|
54
|
+
|
47
55
|
def root
|
48
56
|
@attributes[:root]
|
49
57
|
end
|
@@ -44,10 +44,18 @@ module Rack
|
|
44
44
|
@page = page
|
45
45
|
end
|
46
46
|
|
47
|
+
def name
|
48
|
+
@attributes[:name]
|
49
|
+
end
|
50
|
+
|
47
51
|
def duration_ms
|
48
52
|
self[:duration_milliseconds]
|
49
53
|
end
|
50
54
|
|
55
|
+
def duration_ms_in_sql
|
56
|
+
@attributes[:duration_milliseconds_in_sql]
|
57
|
+
end
|
58
|
+
|
51
59
|
def start_ms
|
52
60
|
self[:start_milliseconds]
|
53
61
|
end
|
@@ -17,11 +17,11 @@ module Rack
|
|
17
17
|
(
|
18
18
|
(
|
19
19
|
Rack::MiniProfiler.config.backtrace_includes.nil? or
|
20
|
-
Rack::MiniProfiler.config.backtrace_includes.
|
20
|
+
Rack::MiniProfiler.config.backtrace_includes.any?{|regex| ln =~ regex}
|
21
21
|
) and
|
22
22
|
(
|
23
23
|
Rack::MiniProfiler.config.backtrace_ignores.nil? or
|
24
|
-
Rack::MiniProfiler.config.backtrace_ignores.
|
24
|
+
Rack::MiniProfiler.config.backtrace_ignores.none?{|regex| ln =~ regex}
|
25
25
|
)
|
26
26
|
)
|
27
27
|
stack_trace << ln << "\n"
|
@@ -4,9 +4,9 @@ module Rack::MiniProfilerRails
|
|
4
4
|
|
5
5
|
# call direct if needed to do a defer init
|
6
6
|
def self.initialize!(app)
|
7
|
-
|
7
|
+
|
8
8
|
raise "MiniProfilerRails initialized twice. Set `require: false' for rack-mini-profiler in your Gemfile" if @already_initialized
|
9
|
-
|
9
|
+
|
10
10
|
c = Rack::MiniProfiler.config
|
11
11
|
|
12
12
|
# By default, only show the MiniProfiler in development mode.
|
@@ -24,7 +24,9 @@ module Rack::MiniProfilerRails
|
|
24
24
|
|
25
25
|
c.skip_paths ||= []
|
26
26
|
|
27
|
-
|
27
|
+
if serves_static_assets?(app)
|
28
|
+
c.skip_paths << app.config.assets.prefix
|
29
|
+
end
|
28
30
|
|
29
31
|
if Rails.env.development?
|
30
32
|
c.skip_schema_queries = true
|
@@ -41,7 +43,6 @@ module Rack::MiniProfilerRails
|
|
41
43
|
# The file store is just so much less flaky
|
42
44
|
base_path = Rails.application.config.paths['tmp'].first rescue "#{Rails.root}/tmp"
|
43
45
|
tmp = base_path + '/miniprofiler'
|
44
|
-
FileUtils.mkdir_p(tmp) unless File.exists?(tmp)
|
45
46
|
|
46
47
|
c.storage_options = {:path => tmp}
|
47
48
|
c.storage = Rack::MiniProfiler::FileStore
|
@@ -61,17 +62,23 @@ module Rack::MiniProfilerRails
|
|
61
62
|
ActiveSupport.on_load(:action_view) do
|
62
63
|
::Rack::MiniProfiler.profile_method(ActionView::Template, :render) {|x,y| "Rendering: #{@virtual_path}"}
|
63
64
|
end
|
64
|
-
|
65
|
+
|
65
66
|
@already_initialized = true
|
66
67
|
end
|
67
68
|
|
68
69
|
def self.serves_static_assets?(app)
|
69
|
-
|
70
|
-
|
71
|
-
if
|
72
|
-
|
70
|
+
config = app.config
|
71
|
+
|
72
|
+
if !config.respond_to?(:assets) || !config.assets.respond_to?(:prefix)
|
73
|
+
return false
|
74
|
+
end
|
75
|
+
|
76
|
+
if ::Rails.version >= "5.0.0"
|
77
|
+
::Rails.configuration.public_file_server.enabled
|
78
|
+
elsif ::Rails.version >= "4.2.0"
|
79
|
+
::Rails.configuration.serve_static_files
|
73
80
|
else
|
74
|
-
|
81
|
+
::Rails.configuration.serve_static_assets
|
75
82
|
end
|
76
83
|
end
|
77
84
|
|
@@ -21,6 +21,8 @@ module Rack
|
|
21
21
|
rval = log_without_miniprofiler(*args, &block)
|
22
22
|
|
23
23
|
# Don't log schema queries if the option is set
|
24
|
+
# return rval unless sql =~ /\"vms\"/
|
25
|
+
# return rval unless sql =~ /\"(vms|ext_management_systems)\"/
|
24
26
|
return rval if Rack::MiniProfiler.config.skip_schema_queries and name =~ /SCHEMA/
|
25
27
|
|
26
28
|
elapsed_time = SqlPatches.elapsed_time(start)
|
data/lib/patches/db/mongo.rb
CHANGED
@@ -8,5 +8,9 @@ class Mongo::Server::Connection
|
|
8
8
|
end
|
9
9
|
return result
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
|
+
# TODO: change to Module#prepend as soon as Ruby 1.9.3 support is dropped
|
13
|
+
alias_method :dispatch_without_timing, :dispatch
|
14
|
+
alias_method :dispatch, :dispatch_with_timing
|
15
|
+
|
12
16
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Neo4j::Core::Query
|
2
|
+
alias_method :response_without_miniprofiler, :response
|
3
|
+
|
4
|
+
def response
|
5
|
+
return @response if @response
|
6
|
+
start = Time.now
|
7
|
+
rval = response_without_miniprofiler
|
8
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
9
|
+
Rack::MiniProfiler.record_sql(to_cypher, elapsed_time)
|
10
|
+
rval
|
11
|
+
end
|
12
|
+
|
13
|
+
alias_method :response_with_miniprofiler, :response
|
14
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# riak-client 2.2.2 patches
|
2
|
+
class Riak::Multiget
|
3
|
+
class <<self
|
4
|
+
alias_method :get_all_without_profiling, :get_all
|
5
|
+
def get_all(client, fetch_list)
|
6
|
+
return get_all_without_profiling(client, fetch_list) unless SqlPatches.should_measure?
|
7
|
+
|
8
|
+
start = Time.now
|
9
|
+
result = get_all_without_profiling(client, fetch_list)
|
10
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
11
|
+
record = ::Rack::MiniProfiler.record_sql("get_all size=#{fetch_list.size}", elapsed_time)
|
12
|
+
|
13
|
+
result
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class Riak::Client
|
19
|
+
|
20
|
+
alias_method :buckets_without_profiling, :buckets
|
21
|
+
def buckets(options={}, &blk)
|
22
|
+
profile("buckets #{options}") { buckets_without_profiling(options, &blk) }
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method :client_id_without_profiling, :client_id
|
26
|
+
def client_id
|
27
|
+
profile("client_id") { client_id_without_profiling }
|
28
|
+
end
|
29
|
+
|
30
|
+
alias_method :delete_object_without_profiling, :delete_object
|
31
|
+
def delete_object(bucket, key, options={})
|
32
|
+
profile("delete_object bucket=#{bucket.name} key=#{key} options=#{options}") { delete_object_without_profiling(bucket, key, options) }
|
33
|
+
end
|
34
|
+
|
35
|
+
alias_method :get_bucket_props_without_profiling, :get_bucket_props
|
36
|
+
def get_bucket_props(bucket, options={})
|
37
|
+
profile("get_bucket_props bucket=#{bucket.name} options=#{options}") { get_bucket_props_without_profiling(bucket, options) }
|
38
|
+
end
|
39
|
+
|
40
|
+
alias_method :get_index_without_profiling, :get_index
|
41
|
+
def get_index(bucket, index, query, options={})
|
42
|
+
profile("get_index bucket=#{bucket.name} index=#{index} query=#{query} options=#{options}") { get_index_without_profiling(bucket, index, query, options) }
|
43
|
+
end
|
44
|
+
|
45
|
+
alias_method :get_preflist_without_profiling, :get_preflist
|
46
|
+
def get_preflist(bucket, key, type=nil, options={})
|
47
|
+
profile("get_preflist bucket=#{bucket.name} key=#{key} type=#{type} options=#{options}") { get_preflist_without_profiling(bucket, key, type, options) }
|
48
|
+
end
|
49
|
+
|
50
|
+
alias_method :get_object_without_profiling, :get_object
|
51
|
+
def get_object(bucket, key, options={})
|
52
|
+
profile("get_object bucket=#{bucket.name} key=#{key} options=#{options}") { get_object_without_profiling(bucket, key, options) }
|
53
|
+
end
|
54
|
+
|
55
|
+
alias_method :list_keys_without_profiling, :list_keys
|
56
|
+
def list_keys(bucket, options={}, &block)
|
57
|
+
profile("list_keys bucket=#{bucket.name} options=#{options}") { list_keys_without_profiling(bucket, options, &block) }
|
58
|
+
end
|
59
|
+
|
60
|
+
alias_method :mapred_without_profiling, :mapred
|
61
|
+
def mapred(mr, &block)
|
62
|
+
profile("mapred") { mapred_without_profiling(mr, &block) }
|
63
|
+
end
|
64
|
+
|
65
|
+
alias_method :ping_without_profiling, :ping
|
66
|
+
def ping
|
67
|
+
profile("ping") { ping_without_profiling }
|
68
|
+
end
|
69
|
+
|
70
|
+
alias_method :reload_object_without_profiling, :reload_object
|
71
|
+
def reload_object(object, options={})
|
72
|
+
profile("reload_object bucket=#{object.bucket.name} key=#{object.key} vclock=#{object.vclock} options=#{options}") { reload_object_without_profiling(object, options) }
|
73
|
+
end
|
74
|
+
|
75
|
+
alias_method :set_bucket_props_without_profiling, :set_bucket_props
|
76
|
+
def set_bucket_props(bucket, properties, type=nil)
|
77
|
+
profile("set_bucket_props bucket=#{bucket.name} type=#{type}") { set_bucket_props_without_profiling(bucket, properties, type) }
|
78
|
+
end
|
79
|
+
|
80
|
+
alias_method :clear_bucket_props_without_profiling, :clear_bucket_props
|
81
|
+
def clear_bucket_props(bucket, options={})
|
82
|
+
profile("clear_bucket_props bucket=#{bucket.name} options=#{options}") { clear_bucket_props_without_profiling(bucket, options) }
|
83
|
+
end
|
84
|
+
|
85
|
+
alias_method :store_object_without_profiling, :store_object
|
86
|
+
def store_object(object, options={})
|
87
|
+
profile("store_object bucket=#{object.bucket.name} key=#{object.key} vclock=#{object.vclock} options=#{options}") { store_object_without_profiling(object, options) }
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def profile(request, &blk)
|
93
|
+
return yield unless SqlPatches.should_measure?
|
94
|
+
|
95
|
+
start = Time.now
|
96
|
+
result = yield
|
97
|
+
elapsed_time = SqlPatches.elapsed_time(start)
|
98
|
+
record = ::Rack::MiniProfiler.record_sql(request, elapsed_time)
|
99
|
+
|
100
|
+
result
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
data/lib/patches/sql_patches.rb
CHANGED
@@ -46,10 +46,12 @@ end
|
|
46
46
|
require 'patches/db/mysql2' if defined?(Mysql2::Client) && SqlPatches.class_exists?("Mysql2::Client")
|
47
47
|
require 'patches/db/pg' if defined?(PG::Result) && SqlPatches.class_exists?("PG::Result")
|
48
48
|
require 'patches/db/oracle_enhanced' if defined?(ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter) && SqlPatches.class_exists?("ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter") && SqlPatches.correct_version?('~> 1.5.0', ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter)
|
49
|
-
require 'patches/db/mongo' if defined?(Mongo)
|
49
|
+
require 'patches/db/mongo' if defined?(Mongo) && SqlPatches.module_exists?("Mongo")
|
50
50
|
require 'patches/db/moped' if defined?(Moped::Node) && SqlPatches.class_exists?("Moped::Node")
|
51
51
|
require 'patches/db/plucky' if defined?(Plucky::Query) && SqlPatches.class_exists?("Plucky::Query")
|
52
52
|
require 'patches/db/rsolr' if defined?(RSolr::Connection) && SqlPatches.class_exists?("RSolr::Connection") && RSolr::VERSION[0] != "0"
|
53
53
|
require 'patches/db/sequel' if defined?(Sequel::Database) && !SqlPatches.patched? && SqlPatches.class_exists?("Sequel::Database")
|
54
54
|
require 'patches/db/activerecord' if defined?(ActiveRecord) &&!SqlPatches.patched? && SqlPatches.module_exists?("ActiveRecord")
|
55
55
|
require 'patches/db/nobrainer' if defined?(NoBrainer) && SqlPatches.module_exists?("NoBrainer")
|
56
|
+
require 'patches/db/riak' if defined?(Riak) && SqlPatches.module_exists?("Riak")
|
57
|
+
require 'patches/db/neo4j' if defined?(Neo4j::Core) && SqlPatches.class_exists?("Neo4j::Core::Query")
|
data/rack-mini-profiler.gemspec
CHANGED
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: 0.9.
|
4
|
+
version: 0.9.9
|
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:
|
13
|
+
date: 2016-03-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|
@@ -18,14 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 1.
|
21
|
+
version: 1.2.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 1.
|
28
|
+
version: 1.2.0
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: rake
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,10 +226,12 @@ files:
|
|
226
226
|
- lib/patches/db/mongo.rb
|
227
227
|
- lib/patches/db/moped.rb
|
228
228
|
- lib/patches/db/mysql2.rb
|
229
|
+
- lib/patches/db/neo4j.rb
|
229
230
|
- lib/patches/db/nobrainer.rb
|
230
231
|
- lib/patches/db/oracle_enhanced.rb
|
231
232
|
- lib/patches/db/pg.rb
|
232
233
|
- lib/patches/db/plucky.rb
|
234
|
+
- lib/patches/db/riak.rb
|
233
235
|
- lib/patches/db/rsolr.rb
|
234
236
|
- lib/patches/db/sequel.rb
|
235
237
|
- lib/patches/net_patches.rb
|
@@ -256,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
256
258
|
version: '0'
|
257
259
|
requirements: []
|
258
260
|
rubyforge_project:
|
259
|
-
rubygems_version: 2.4.5
|
261
|
+
rubygems_version: 2.4.5
|
260
262
|
signing_key:
|
261
263
|
specification_version: 4
|
262
264
|
summary: Profiles loading speed for rack applications.
|