rack-mini-profiler 0.1.18 → 0.1.23
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.
- data/{CHANGELOG → Ruby/CHANGELOG} +107 -83
- data/{README.md → Ruby/README.md} +22 -9
- data/{lib → Ruby/lib}/html/includes.css +0 -0
- data/{lib → Ruby/lib}/html/includes.js +80 -16
- data/{lib → Ruby/lib}/html/includes.less +0 -0
- data/{lib → Ruby/lib}/html/includes.tmpl +39 -15
- data/{lib → Ruby/lib}/html/jquery.1.7.1.js +1 -1
- data/{lib → Ruby/lib}/html/jquery.tmpl.js +1 -1
- data/{lib → Ruby/lib}/html/list.css +0 -0
- data/{lib → Ruby/lib}/html/list.js +7 -6
- data/{lib → Ruby/lib}/html/list.tmpl +0 -0
- data/Ruby/lib/html/profile_handler.js +1 -0
- data/{lib → Ruby/lib}/html/share.html +0 -0
- data/{lib → Ruby/lib}/mini_profiler/client_settings.rb +0 -0
- data/{lib → Ruby/lib}/mini_profiler/client_timer_struct.rb +1 -1
- data/{lib → Ruby/lib}/mini_profiler/config.rb +54 -52
- data/{lib → Ruby/lib}/mini_profiler/context.rb +0 -0
- data/Ruby/lib/mini_profiler/custom_timer_struct.rb +22 -0
- data/Ruby/lib/mini_profiler/gc_profiler.rb +103 -0
- data/{lib → Ruby/lib}/mini_profiler/page_timer_struct.rb +7 -2
- data/{lib → Ruby/lib}/mini_profiler/profiler.rb +81 -21
- data/{lib → Ruby/lib}/mini_profiler/profiling_methods.rb +10 -2
- data/{lib → Ruby/lib}/mini_profiler/request_timer_struct.rb +20 -1
- data/{lib → Ruby/lib}/mini_profiler/sql_timer_struct.rb +0 -0
- data/{lib → Ruby/lib}/mini_profiler/storage/abstract_store.rb +0 -0
- data/{lib → Ruby/lib}/mini_profiler/storage/file_store.rb +0 -0
- data/Ruby/lib/mini_profiler/storage/memcache_store.rb +51 -0
- data/{lib → Ruby/lib}/mini_profiler/storage/memory_store.rb +0 -0
- data/{lib → Ruby/lib}/mini_profiler/storage/redis_store.rb +44 -44
- data/{lib → Ruby/lib}/mini_profiler/timer_struct.rb +0 -0
- data/Ruby/lib/mini_profiler/version.rb +5 -0
- data/{lib → Ruby/lib}/mini_profiler_rails/railtie.rb +3 -2
- data/Ruby/lib/patches/net_patches.rb +14 -0
- data/{lib → Ruby/lib}/patches/sql_patches.rb +20 -1
- data/{lib → Ruby/lib}/rack-mini-profiler.rb +2 -1
- data/rack-mini-profiler.gemspec +8 -6
- metadata +45 -40
- data/lib/html/profile_handler.js +0 -62
@@ -1,83 +1,107 @@
|
|
1
|
-
28-June-2012 - Sam
|
2
|
-
|
3
|
-
* Started change log
|
4
|
-
* Corrected profiler so it properly captures POST requests (was supressing non 200s)
|
5
|
-
* Amended Rack.MiniProfiler.config[:user_provider] to use ip addres for identity
|
6
|
-
* Fixed bug where unviewed missing ids never got cleared
|
7
|
-
* Supress all '/assets/' in the rails tie (makes debugging easier)
|
8
|
-
* record_sql was mega buggy
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
*
|
17
|
-
*
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
*
|
24
|
-
*
|
25
|
-
*
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
*
|
31
|
-
*
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
*
|
37
|
-
* Fixed
|
38
|
-
*
|
39
|
-
*
|
40
|
-
*
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
*
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
*
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
*
|
60
|
-
*
|
61
|
-
* added setting config.
|
62
|
-
*
|
63
|
-
*
|
64
|
-
*
|
65
|
-
*
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
*
|
71
|
-
* fixed
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
*
|
77
|
-
* fixed
|
78
|
-
*
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
*
|
1
|
+
28-June-2012 - Sam
|
2
|
+
|
3
|
+
* Started change log
|
4
|
+
* Corrected profiler so it properly captures POST requests (was supressing non 200s)
|
5
|
+
* Amended Rack.MiniProfiler.config[:user_provider] to use ip addres for identity
|
6
|
+
* Fixed bug where unviewed missing ids never got cleared
|
7
|
+
* Supress all '/assets/' in the rails tie (makes debugging easier)
|
8
|
+
* record_sql was mega buggy
|
9
|
+
* added MemcacheStore
|
10
|
+
|
11
|
+
9-July-2012 - Sam
|
12
|
+
|
13
|
+
* Cleaned up mechanism for profiling in production, all you need to do now
|
14
|
+
is call Rack::MiniProfiler.authorize_request to get profiling working in
|
15
|
+
production
|
16
|
+
* Added option to display full backtraces pp=full-backtrace
|
17
|
+
* Cleaned up railties, got rid of the post authorize callback
|
18
|
+
* Version 0.1.3
|
19
|
+
|
20
|
+
12-July-2012 - Sam
|
21
|
+
|
22
|
+
* Fixed incorrect profiling steps (was not indenting or measuring start time right
|
23
|
+
* Implemented native PG and MySql2 interceptors, this gives way more accurate times
|
24
|
+
* Refactored context so its a proper class and not a hash
|
25
|
+
* Added some more client probing built in to rails
|
26
|
+
* More tests
|
27
|
+
|
28
|
+
18-July-2012 - Sam
|
29
|
+
|
30
|
+
* Added First Paint time for chrome
|
31
|
+
* Bug fix to ensure non Rails installs have mini profiler
|
32
|
+
* Version 0.1.7
|
33
|
+
|
34
|
+
30-July-2012 - Sam
|
35
|
+
|
36
|
+
* Made compliant with ancient versions of Rack (including Rack used by Rails2)
|
37
|
+
* Fixed broken share link
|
38
|
+
* Fixed crashes on startup (in MemoryStore and FileStore)
|
39
|
+
* Version 0.1.8
|
40
|
+
* Unicode fix
|
41
|
+
* Version 0.1.9
|
42
|
+
|
43
|
+
7-August-2012 - Sam
|
44
|
+
|
45
|
+
* Added option to disable profiler for the current session (pp=disable / pp=enable)
|
46
|
+
* yajl compatability contributed by Sven Riedel
|
47
|
+
|
48
|
+
10-August-2012 - Sam
|
49
|
+
|
50
|
+
* Added basic prepared statement profiling for postgres
|
51
|
+
|
52
|
+
20-August-2012 - Sam
|
53
|
+
|
54
|
+
* 1.12.pre
|
55
|
+
* Cap X-MiniProfiler-Ids at 10, otherwise the header can get killed
|
56
|
+
|
57
|
+
3-September-2012 - Sam
|
58
|
+
|
59
|
+
* 1.13.pre
|
60
|
+
* pg gem prepared statements were not being logged correctly
|
61
|
+
* added setting config.backtrace_ignores = [] - an array of regexes that match on caller lines that get ignored
|
62
|
+
* added setting config.backtrace_includes = [] - an array of regexes that get included in the trace by default
|
63
|
+
* cleaned up the way client settings are stored
|
64
|
+
* made pp=full-backtrace "sticky"
|
65
|
+
* added pp=normal-backtrace to clear the "sticky" state
|
66
|
+
* change "pp=sample" to work with "caller" no need for stack trace gem
|
67
|
+
|
68
|
+
4-September-2012 - Sam
|
69
|
+
|
70
|
+
* 1.15.pre
|
71
|
+
* fixed annoying bug where client settings were not sticking
|
72
|
+
* fixed long standing issue with Rack::ConditionalGet stopping MiniProfiler from working properly
|
73
|
+
|
74
|
+
5-September-2012 - Sam
|
75
|
+
|
76
|
+
* 1.16
|
77
|
+
* fixed long standing problem specs (issue with memory store)
|
78
|
+
* fixed issue where profiler would be dumped when you got a 404 in production (and any time rails is bypassed)
|
79
|
+
* implemented stacktrace properly
|
80
|
+
|
81
|
+
9-September-2012 - Sam
|
82
|
+
|
83
|
+
* 1.17
|
84
|
+
* pp=sample was bust unless stacktrace was installed
|
85
|
+
|
86
|
+
10-September-2012 - Sam
|
87
|
+
|
88
|
+
* 1.19
|
89
|
+
* fix compat issue with 1.8.7
|
90
|
+
|
91
|
+
12-September-2012 - Sam
|
92
|
+
|
93
|
+
* 1.20
|
94
|
+
* Added pp=profile-gc , it allows you to profile the GC in Ruby 1.9.3
|
95
|
+
|
96
|
+
17-September-2012
|
97
|
+
* 1.21
|
98
|
+
* New MemchacedStore
|
99
|
+
* Rails 4 support
|
100
|
+
|
101
|
+
17-September-2012
|
102
|
+
* Allow rack-mini-profiler to be sourced from github
|
103
|
+
* Extracted the pp=profile-gc-time out, the object space profiler needs to disable gc
|
104
|
+
|
105
|
+
20-September-2010
|
106
|
+
* 1.22
|
107
|
+
* Fix permission issue in the gem
|
@@ -15,7 +15,7 @@ All you have to do is include the Gem and you're good to go in development.
|
|
15
15
|
|
16
16
|
rack-mini-profiler is designed with production profiling in mind. To enable that just run `Rack::MiniProfiler.authorize_request` once you know a request is allowed to profile.
|
17
17
|
|
18
|
-
|
18
|
+
Using Rails:
|
19
19
|
|
20
20
|
```ruby
|
21
21
|
# A hook in your ApplicationController
|
@@ -47,24 +47,38 @@ class MyApp < Sinatra::Base
|
|
47
47
|
end
|
48
48
|
```
|
49
49
|
|
50
|
+
## Database profiling
|
51
|
+
|
52
|
+
Currently supports Mysql2, Postgres, and Mongoid3 (with fallback support to ActiveRecord)
|
53
|
+
|
50
54
|
## Storage
|
51
55
|
|
52
|
-
|
56
|
+
rack-mini-profiler stores it's results so they can be shared later and aren't lost at the end of the request.
|
57
|
+
|
58
|
+
There are 4 storage options: `MemoryStore`, `RedisStore`, `MemcacheStore`, and `FileStore`.
|
59
|
+
|
60
|
+
`FileStore` is the default in Rails environments and will write files to `tmp/miniprofiler/*`. `MemoryStore` is the default otherwise.
|
61
|
+
|
62
|
+
To change the default you can create a file in `config/initializers/mini_profiler.rb`
|
53
63
|
|
54
64
|
```ruby
|
55
|
-
#
|
65
|
+
# set MemoryStore
|
56
66
|
Rack::MiniProfiler.config.storage = Rack::MiniProfiler::MemoryStore
|
57
|
-
```
|
58
67
|
|
59
|
-
|
68
|
+
# set RedisStore
|
69
|
+
if Rails.env.production?
|
70
|
+
uri = URI.parse(ENV["REDIS_SERVER_URL"])
|
71
|
+
Rack::MiniProfiler.config.storage_options = { :host => uri.host, :port => uri.port, :password => uri.password }
|
72
|
+
Rack::MiniProfiler.config.storage = Rack::MiniProfiler::RedisStore
|
73
|
+
end
|
74
|
+
```
|
60
75
|
|
61
|
-
MemoryStore
|
76
|
+
MemoryStore stores results in a processes heap - something that does not work well in a multi process environment.
|
62
77
|
FileStore stores results in the file system - something that may not work well in a multi machine environment.
|
78
|
+
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).
|
63
79
|
|
64
80
|
Additionally you may implement an AbstractStore for your own provider.
|
65
81
|
|
66
|
-
Rails hooks up a FileStore for all environments.
|
67
|
-
|
68
82
|
## Running the Specs
|
69
83
|
|
70
84
|
```
|
@@ -120,7 +134,6 @@ end
|
|
120
134
|
* pre_authorize_cb - A lambda callback you can set to determine whether or not mini_profiler should be visible on a given request. Default in a Rails environment is only on in development mode. If in a Rack app, the default is always on.
|
121
135
|
* position - Can either be 'right' or 'left'. Default is 'left'.
|
122
136
|
* skip_schema_queries - Whether or not you want to log the queries about the schema of your tables. Default is 'false', 'true' in rails development.
|
123
|
-
* use_existing_jquery - Use the version of jQuery on the page as opposed to the self contained one
|
124
137
|
* auto_inject (default true) - when false the miniprofiler script is not injected in the page
|
125
138
|
* backtrace_filter - a regex you can use to filter out unwanted lines from the backtraces
|
126
139
|
|
File without changes
|
@@ -1,5 +1,6 @@
|
|
1
1
|
"use strict";
|
2
|
-
var MiniProfiler = (function (
|
2
|
+
var MiniProfiler = (function () {
|
3
|
+
var $;
|
3
4
|
|
4
5
|
var options,
|
5
6
|
container,
|
@@ -449,11 +450,12 @@ var MiniProfiler = (function ($) {
|
|
449
450
|
};
|
450
451
|
|
451
452
|
// fetch profile results for any ajax calls
|
453
|
+
// note, this does not use $ cause we want to hook into the main jQuery
|
452
454
|
if (jQuery && jQuery(document) && jQuery(document).ajaxComplete) {
|
453
455
|
jQuery(document).ajaxComplete(jQueryAjaxComplete);
|
454
456
|
}
|
455
457
|
|
456
|
-
if (jQuery(document).ajaxStart)
|
458
|
+
if (jQuery && jQuery(document).ajaxStart)
|
457
459
|
jQuery(document).ajaxStart(function () { ajaxStartTime = new Date(); });
|
458
460
|
|
459
461
|
// fetch results after ASP Ajax calls
|
@@ -512,9 +514,42 @@ var MiniProfiler = (function ($) {
|
|
512
514
|
|
513
515
|
return {
|
514
516
|
|
515
|
-
init: function (
|
517
|
+
init: function () {
|
518
|
+
var script = document.getElementById('mini-profiler');
|
519
|
+
if (!script || !script.getAttribute) return;
|
516
520
|
|
517
|
-
options =
|
521
|
+
options = (function () {
|
522
|
+
var version = script.getAttribute('data-version');
|
523
|
+
var path = script.getAttribute('data-path');
|
524
|
+
|
525
|
+
var currentId = script.getAttribute('data-current-id');
|
526
|
+
|
527
|
+
var ids = script.getAttribute('data-ids');
|
528
|
+
if (ids) ids = ids.split(',');
|
529
|
+
|
530
|
+
var position = script.getAttribute('data-position');
|
531
|
+
|
532
|
+
if (script.getAttribute('data-max-traces'))
|
533
|
+
var maxTraces = parseInt(script.getAttribute('data-max-traces'));
|
534
|
+
|
535
|
+
if (script.getAttribute('data-trivial') === 'true') var trivial = true;
|
536
|
+
if (script.getAttribute('data-children') == 'true') var children = true;
|
537
|
+
if (script.getAttribute('data-controls') == 'true') var controls = true;
|
538
|
+
if (script.getAttribute('data-authorized') == 'true') var authorized = true;
|
539
|
+
|
540
|
+
return {
|
541
|
+
ids: ids,
|
542
|
+
path: path,
|
543
|
+
version: version,
|
544
|
+
renderPosition: position,
|
545
|
+
showTrivial: trivial,
|
546
|
+
showChildrenTime: children,
|
547
|
+
maxTracesToShow: maxTraces,
|
548
|
+
showControls: controls,
|
549
|
+
currentId: currentId,
|
550
|
+
authorized: authorized
|
551
|
+
}
|
552
|
+
})();
|
518
553
|
|
519
554
|
var doInit = function () {
|
520
555
|
// when rendering a shared, full page, this div will exist
|
@@ -546,24 +581,50 @@ var MiniProfiler = (function ($) {
|
|
546
581
|
document.getElementsByTagName('head')[0].appendChild(sc);
|
547
582
|
};
|
548
583
|
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
584
|
+
var wait = 0;
|
585
|
+
var finish = false;
|
586
|
+
var deferInit = function() {
|
587
|
+
if (finish) return;
|
588
|
+
if (window.performance && window.performance.timing && window.performance.timing.loadEventEnd == 0 && wait < 10000) {
|
589
|
+
setTimeout(deferInit, 100);
|
590
|
+
wait += 100;
|
553
591
|
} else {
|
554
|
-
|
592
|
+
finish = true;
|
593
|
+
init();
|
555
594
|
}
|
595
|
+
};
|
556
596
|
|
557
|
-
|
558
|
-
|
559
|
-
|
597
|
+
var init = function() {
|
598
|
+
if (options.authorized) {
|
599
|
+
var url = options.path + "includes.css?v=" + options.version;
|
600
|
+
if (document.createStyleSheet) {
|
601
|
+
document.createStyleSheet(url);
|
602
|
+
} else {
|
603
|
+
$('head').append($('<link rel="stylesheet" type="text/css" href="' + url + '" />'));
|
604
|
+
}
|
605
|
+
if (!$.tmpl) {
|
606
|
+
load(options.path + 'jquery.tmpl.js?v=' + options.version, doInit);
|
607
|
+
} else {
|
608
|
+
doInit();
|
609
|
+
}
|
610
|
+
}
|
611
|
+
else {
|
560
612
|
doInit();
|
561
613
|
}
|
562
614
|
}
|
563
|
-
else {
|
564
|
-
doInit();
|
565
|
-
}
|
566
615
|
|
616
|
+
if (typeof(jQuery) == 'function') {
|
617
|
+
var jQueryVersion = jQuery.fn.jquery.split('.');
|
618
|
+
}
|
619
|
+
if (jQueryVersion && parseInt(jQueryVersion[0]) < 2 && parseInt(jQueryVersion[1]) >= 7) {
|
620
|
+
MiniProfiler.jQuery = $ = jQuery;
|
621
|
+
$(deferInit);
|
622
|
+
} else {
|
623
|
+
load(options.path + "jquery.1.7.1.js?v=" + options.version, function() {
|
624
|
+
MiniProfiler.jQuery = $ = jQuery.noConflict(true);
|
625
|
+
$(deferInit);
|
626
|
+
});
|
627
|
+
}
|
567
628
|
},
|
568
629
|
|
569
630
|
getClientTimingByName: function (clientTiming, name) {
|
@@ -783,7 +844,10 @@ var MiniProfiler = (function ($) {
|
|
783
844
|
return (duration || 0).toFixed(1);
|
784
845
|
}
|
785
846
|
};
|
786
|
-
})(
|
847
|
+
})();
|
848
|
+
|
849
|
+
MiniProfiler.init();
|
850
|
+
|
787
851
|
|
788
852
|
// prettify.js
|
789
853
|
// http://code.google.com/p/google-code-prettify/
|
File without changes
|
@@ -27,10 +27,13 @@
|
|
27
27
|
{{if HasSqlTimings}}
|
28
28
|
<th colspan="2">query time (ms)</th>
|
29
29
|
{{/if}}
|
30
|
+
{{each CustomTimingNames}}
|
31
|
+
<th colspan="2">${$value.toLowerCase()} (ms)</th>
|
32
|
+
{{/each}}
|
30
33
|
</tr>
|
31
34
|
</thead>
|
32
35
|
<tbody>
|
33
|
-
{{tmpl(Root) "#timingTemplate"}}
|
36
|
+
{{tmpl({timing:Root, page:this.data}) "#timingTemplate"}}
|
34
37
|
</tbody>
|
35
38
|
<tfoot>
|
36
39
|
<tr>
|
@@ -46,6 +49,12 @@
|
|
46
49
|
<span class="profiler-unit">% in sql</span>
|
47
50
|
</td>
|
48
51
|
{{/if}}
|
52
|
+
{{each CustomTimingNames}}
|
53
|
+
<td colspan="2" class="profiler-number profiler-percentage-in-sql" title="${CustomTimingStats[$value].Count} ${$value.toLowerCase()} invocations spent ${MiniProfiler.formatDuration(CustomTimingStats[$value].Duration)} ms of total request time">
|
54
|
+
${MiniProfiler.formatDuration(CustomTimingStats[$value].Duration / DurationMilliseconds * 100)}
|
55
|
+
<span class="profiler-unit">% in ${$value.toLowerCase()}</span>
|
56
|
+
</td>
|
57
|
+
{{/each}}
|
49
58
|
</tr>
|
50
59
|
</tfoot>
|
51
60
|
</table>
|
@@ -123,37 +132,52 @@
|
|
123
132
|
|
124
133
|
<script id="timingTemplate" type="text/x-jquery-tmpl">
|
125
134
|
|
126
|
-
<tr class="{{if IsTrivial }}profiler-trivial{{/if}}" data-timing-id="${Id}">
|
127
|
-
<td class="profiler-label" title="{{if Name && Name.length > 45 }}${Name}{{/if}}">
|
128
|
-
<span class="profiler-indent">${MiniProfiler.renderIndent(Depth)}</span> ${Name.slice(0,45)}{{if Name && Name.length > 45 }}...{{/if}}
|
135
|
+
<tr class="{{if timing.IsTrivial }}profiler-trivial{{/if}}" data-timing-id="${timing.Id}">
|
136
|
+
<td class="profiler-label" title="{{if timing.Name && timing.Name.length > 45 }}${timing.Name}{{/if}}">
|
137
|
+
<span class="profiler-indent">${MiniProfiler.renderIndent(timing.Depth)}</span> ${timing.Name.slice(0,45)}{{if timing.Name && timing.Name.length > 45 }}...{{/if}}
|
129
138
|
</td>
|
130
139
|
<td class="profiler-duration" title="duration of this step without any children's durations">
|
131
|
-
${MiniProfiler.formatDuration(DurationWithoutChildrenMilliseconds)}
|
140
|
+
${MiniProfiler.formatDuration(timing.DurationWithoutChildrenMilliseconds)}
|
132
141
|
</td>
|
133
142
|
<td class="profiler-duration profiler-duration-with-children" title="duration of this step and its children">
|
134
|
-
${MiniProfiler.formatDuration(DurationMilliseconds)}
|
143
|
+
${MiniProfiler.formatDuration(timing.DurationMilliseconds)}
|
135
144
|
</td>
|
136
145
|
<td class="profiler-duration time-from-start" title="time elapsed since profiling started">
|
137
|
-
<span class="profiler-unit">+</span>${MiniProfiler.formatDuration(StartMilliseconds)}
|
146
|
+
<span class="profiler-unit">+</span>${MiniProfiler.formatDuration(timing.StartMilliseconds)}
|
138
147
|
</td>
|
139
148
|
|
140
|
-
{{if HasSqlTimings}}
|
141
|
-
<td class="profiler-duration {{if HasDuplicateSqlTimings}}profiler-warning{{/if}}" title="{{if HasDuplicateSqlTimings}}duplicate queries detected - {{/if}}{{if ExecutedReaders > 0 || ExecutedScalars > 0 || ExecutedNonQueries > 0}}${ExecutedReaders} reader, ${ExecutedScalars} scalar, ${ExecutedNonQueries} non-query statements executed{{/if}}">
|
149
|
+
{{if timing.HasSqlTimings}}
|
150
|
+
<td class="profiler-duration {{if timing.HasDuplicateSqlTimings}}profiler-warning{{/if}}" title="{{if timing.HasDuplicateSqlTimings}}duplicate queries detected - {{/if}}{{if timing.ExecutedReaders > 0 || timing.ExecutedScalars > 0 || timing.ExecutedNonQueries > 0}}${timing.ExecutedReaders} reader, ${timing.ExecutedScalars} scalar, ${timing.ExecutedNonQueries} non-query statements executed{{/if}}">
|
142
151
|
<a class="profiler-queries-show">
|
143
|
-
{{if HasDuplicateSqlTimings}}<span class="profiler-nuclear">!</span>{{/if}}
|
144
|
-
${SqlTimings.length} <span class="profiler-unit">sql</span>
|
152
|
+
{{if timing.HasDuplicateSqlTimings}}<span class="profiler-nuclear">!</span>{{/if}}
|
153
|
+
${timing.SqlTimings.length} <span class="profiler-unit">sql</span>
|
145
154
|
</a>
|
146
155
|
</td>
|
147
156
|
<td class="profiler-duration" title="aggregate duration of all queries in this step (excludes children)">
|
148
|
-
${MiniProfiler.formatDuration(SqlTimingsDurationMilliseconds)}
|
157
|
+
${MiniProfiler.formatDuration(timing.SqlTimingsDurationMilliseconds)}
|
149
158
|
</td>
|
159
|
+
{{else}}
|
160
|
+
<td colspan='2'></td>
|
150
161
|
{{/if}}
|
151
162
|
|
163
|
+
{{each page.CustomTimingNames}}
|
164
|
+
{{if timing.CustomTimings[$value]}}
|
165
|
+
<td class="profiler-duration" title="aggregate number of all ${$value.toLowerCase()} invocations in this step (excludes children)">
|
166
|
+
${timing.CustomTimings[$value].length} ${$value.toLowerCase()}
|
167
|
+
</td>
|
168
|
+
<td class="profiler-duration" title="aggregate duration of all ${$value.toLowerCase()} invocations in this step (excludes children)">
|
169
|
+
${MiniProfiler.formatDuration(timing.CustomTimingStats[$value].Duration)}
|
170
|
+
</td>
|
171
|
+
{{else}}
|
172
|
+
<td colspan="2"></td>
|
173
|
+
{{/if}}
|
174
|
+
{{/each}}
|
175
|
+
|
152
176
|
</tr>
|
153
177
|
|
154
|
-
{{if HasChildren}}
|
155
|
-
{{each Children}}
|
156
|
-
{{tmpl($value) "#timingTemplate"}}
|
178
|
+
{{if timing.HasChildren}}
|
179
|
+
{{each timing.Children}}
|
180
|
+
{{tmpl({timing: $value, page: page}) "#timingTemplate"}}
|
157
181
|
{{/each}}
|
158
182
|
{{/if}}
|
159
183
|
|