rack-mini-profiler 0.9.2 → 0.9.3

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.

Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +17 -3
  3. data/lib/html/includes.css +15 -4
  4. data/lib/html/includes.js +93 -58
  5. data/lib/html/includes.less +21 -5
  6. data/lib/html/includes.tmpl +49 -49
  7. data/lib/html/list.tmpl +8 -8
  8. data/lib/mini_profiler/asset_version.rb +5 -0
  9. data/lib/mini_profiler/client_settings.rb +3 -3
  10. data/lib/mini_profiler/config.rb +11 -11
  11. data/lib/mini_profiler/gc_profiler.rb +10 -10
  12. data/lib/mini_profiler/profiler.rb +49 -71
  13. data/lib/mini_profiler/profiling_methods.rb +15 -17
  14. data/lib/mini_profiler/storage/file_store.rb +4 -4
  15. data/lib/mini_profiler/storage/memcache_store.rb +5 -7
  16. data/lib/mini_profiler/storage/memory_store.rb +56 -27
  17. data/lib/mini_profiler/storage/redis_store.rb +19 -11
  18. data/lib/mini_profiler/timer_struct/base.rb +33 -0
  19. data/lib/mini_profiler/timer_struct/client.rb +89 -0
  20. data/lib/mini_profiler/timer_struct/custom.rb +22 -0
  21. data/lib/mini_profiler/timer_struct/page.rb +62 -0
  22. data/lib/mini_profiler/timer_struct/request.rb +126 -0
  23. data/lib/mini_profiler/timer_struct/sql.rb +59 -0
  24. data/lib/mini_profiler/version.rb +2 -2
  25. data/lib/patches/db/activerecord.rb +42 -0
  26. data/lib/patches/db/moped.rb +12 -0
  27. data/lib/patches/db/mysql2.rb +30 -0
  28. data/lib/patches/db/pg.rb +104 -0
  29. data/lib/patches/db/plucky.rb +47 -0
  30. data/lib/patches/db/rsolr.rb +24 -0
  31. data/lib/patches/db/sequel.rb +10 -0
  32. data/lib/patches/sql_patches.rb +17 -255
  33. data/lib/rack-mini-profiler.rb +28 -0
  34. data/rack-mini-profiler.gemspec +6 -2
  35. metadata +16 -8
  36. data/lib/mini_profiler/client_timer_struct.rb +0 -78
  37. data/lib/mini_profiler/custom_timer_struct.rb +0 -22
  38. data/lib/mini_profiler/page_timer_struct.rb +0 -58
  39. data/lib/mini_profiler/request_timer_struct.rb +0 -115
  40. data/lib/mini_profiler/sql_timer_struct.rb +0 -58
  41. data/lib/mini_profiler/timer_struct.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8b3ee0b3863448cab4aa77a7d21a6660cd864fdd
4
- data.tar.gz: 84d03ff97e66376542b2ad7862abcb1e5fee280b
3
+ metadata.gz: 915cfa4f71cab960c3f73128fa213cce013f0b65
4
+ data.tar.gz: 3465e843ef28ed50178f1f76255de96b474903f6
5
5
  SHA512:
6
- metadata.gz: e31c6eacf0d6fa8b01f1c11ef4be1f16a86e1f08843ef79ff8051c5029b78460aa9c23802b1cdc1be8e1b4d19dc19e6644c621740bec0c8578aed6a04bb52ede
7
- data.tar.gz: cf86b40baacdd86a5e90f641a4ec9e2367ddfef55c3f1810aeed774fd55950b86c428ab9df7eabcd08f09a1dc093b142f270ac3bad4ff7acba4a4b87e1d52826
6
+ metadata.gz: 7c232ba029fb050b15d6b4cdb08b9dc3a6079ed723c06beb7b99dcbc7b6d009822aa2686895661a8e57497a0c5e529a691bf7507c0a895639be9b0e0346ddf29
7
+ data.tar.gz: 45b90274fd6828441a1a4ca14017a6d3b1f1292b65c157dbd03964748b7fd648b39f06484b36d56fd0340b52498bd9c8b0242fe6063e6e23dd115d4b99c10040
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # rack-mini-profiler
2
2
 
3
- [![Code Climate](https://codeclimate.com/github/MiniProfiler/rack-mini-profiler.png)](https://codeclimate.com/github/MiniProfiler/rack-mini-profiler) [![Build Status](https://travis-ci.org/MiniProfiler/rack-mini-profiler.png)](https://travis-ci.org/MiniProfiler/rack-mini-profiler)
3
+ [![Code Climate](https://codeclimate.com/github/MiniProfiler/rack-mini-profiler/badges/gpa.svg)](https://codeclimate.com/github/MiniProfiler/rack-mini-profiler) [![Build Status](https://travis-ci.org/MiniProfiler/rack-mini-profiler.svg)](https://travis-ci.org/MiniProfiler/rack-mini-profiler)
4
4
 
5
5
  Middleware that displays speed badge for every html page. Designed to work both in production and in development.
6
6
 
@@ -23,7 +23,7 @@ We have decided to restructure our repository so there is a central UI repo and
23
23
 
24
24
  - Setting up a build that reuses https://github.com/MiniProfiler/ui
25
25
  - Migrating the internal data structures [per the spec](https://github.com/MiniProfiler/ui)
26
- - Cleaning up the [horrendous class structure that is using strings as keys and crazy non-objects](https://github.com/MiniProfiler/rack-mini-profiler/blob/master/lib/mini_profiler/sql_timer_struct.rb#L36-L44)
26
+ - Cleaning up the [horrendous class structure that is using strings as keys and crazy non-objects](https://github.com/MiniProfiler/rack-mini-profiler/blob/master/lib/mini_profiler/timer_struct/sql.rb#L36-L44)
27
27
 
28
28
  If you feel like taking on any of this start an issue and update us on your progress.
29
29
 
@@ -87,7 +87,7 @@ end
87
87
 
88
88
  To generate [flamegraphs](http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-miniprofiler):
89
89
 
90
- * add the **flamegraph** gem to your Gemfile
90
+ * add the [**flamegraph**](https://github.com/SamSaffron/flamegraph) gem to your Gemfile
91
91
  * visit a page in your app with `?pp=flamegraph`
92
92
 
93
93
  Flamegraph generation is supported in MRI 2.0 and 2.1 only.
@@ -112,6 +112,19 @@ Various aspects of rack-mini-profiler's behavior can be configured when your app
112
112
  For example in a Rails app, this should be done in an initializer:
113
113
  **config/initializers/mini_profiler.rb**
114
114
 
115
+ ### Caching behavior
116
+ To fix some nasty bugs with rack-mini-profiler showing the wrong data, the middleware
117
+ will remove headers relating to caching (Date & Etag on responses, If-Modified-Since & If-None-Match on requests).
118
+ This probably won't ever break your application, but it can cause some unexpected behavior. For
119
+ example, in a Rails app, calls to `stale?` will always return true.
120
+
121
+ To disable this behavior, use the following config setting:
122
+
123
+ ```ruby
124
+ # Do not let rack-mini-profiler disable caching
125
+ Rack::MiniProfiler.config.disable_caching = false # defaults to true
126
+ ```
127
+
115
128
  ### Storage
116
129
 
117
130
  rack-mini-profiler stores its results so they can be shared later and aren't lost at the end of the request.
@@ -167,6 +180,7 @@ The available configuration options are:
167
180
 
168
181
  * 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.
169
182
  * position - Can either be 'right' or 'left'. Default is 'left'.
183
+ * skip_paths - Specifies path list that can be skipped.
170
184
  * 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.
171
185
  * auto_inject (default true) - when false the miniprofiler script is not injected in the page
172
186
  * backtrace_filter - a regex you can use to filter out unwanted lines from the backtraces
@@ -149,6 +149,21 @@
149
149
  .profiler-result .profiler-queries .profiler-stack-trace {
150
150
  margin-bottom: 15px;
151
151
  }
152
+ .profiler-result .profiler-queries tbody tr {
153
+ border-bottom: 1px solid #f1f1f1;
154
+ }
155
+ .profiler-result .profiler-queries tr {
156
+ background-color: #FFF;
157
+ }
158
+ .profiler-result .profiler-queries tr.slow {
159
+ background-color: #FEE;
160
+ }
161
+ .profiler-result .profiler-queries tr.very-slow {
162
+ background-color: #FDD;
163
+ }
164
+ .profiler-result .profiler-queries tr.very-very-slow {
165
+ background-color: #FCC;
166
+ }
152
167
  .profiler-result .profiler-queries pre {
153
168
  font-family: Consolas, monospace, serif;
154
169
  white-space: pre-wrap;
@@ -163,14 +178,10 @@
163
178
  .profiler-result .profiler-queries td {
164
179
  padding: 15px;
165
180
  text-align: left;
166
- background-color: #fff;
167
181
  }
168
182
  .profiler-result .profiler-queries td:last-child {
169
183
  padding-right: 25px;
170
184
  }
171
- .profiler-result .profiler-queries .profiler-odd td {
172
- background-color: #e5e5e5;
173
- }
174
185
  .profiler-result .profiler-queries .profiler-since-start,
175
186
  .profiler-result .profiler-queries .profiler-duration {
176
187
  text-align: right;
@@ -278,7 +278,7 @@ var MiniProfiler = (function () {
278
278
 
279
279
  var queriesScrollIntoView = function (link, queries, whatToScroll) {
280
280
  var id = link.closest('tr').attr('data-timing-id'),
281
- cells = queries.find('tr[data-timing-id="' + id + '"] td');
281
+ cells = queries.find('tr[data-timing-id="' + id + '"]');
282
282
 
283
283
  // ensure they're in view
284
284
  whatToScroll.scrollTop(whatToScroll.scrollTop() + cells.first().position().top - 100);
@@ -326,13 +326,13 @@ var MiniProfiler = (function () {
326
326
  if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) return [parseInt(result[1] + result[1], 16), parseInt(result[2] + result[2], 16), parseInt(result[3] + result[3], 16)];
327
327
 
328
328
  // Look for rgba(0, 0, 0, 0) == transparent in Safari 3
329
- if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) return colors['transparent'];
329
+ if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) return [0,0,0,0];
330
330
 
331
331
  return null;
332
332
  };
333
333
 
334
334
  var bindDocumentEvents = function () {
335
- $(document).bind('click keyup', function (e) {
335
+ $(document).bind('click.mini-profiler keyup.mini-profiler', function (e) {
336
336
 
337
337
  // this happens on every keystroke, and :visible is crazy expensive in IE <9
338
338
  // and in this case, the display:none check is sufficient.
@@ -365,9 +365,19 @@ var MiniProfiler = (function () {
365
365
  popupHide(button, popup);
366
366
  }
367
367
  });
368
- $(document).bind('keydown', options.toggleShortcut, function(e) {
368
+ $(document).bind('keydown.mini-profiler', options.toggleShortcut, function(e) {
369
369
  $('.profiler-results').toggle();
370
370
  });
371
+
372
+ if (typeof Turbolinks !== 'undefined' && Turbolinks.supported) {
373
+ $(document).bind('page:change.mini-profiler', function() {
374
+ unbindDocumentEvents();
375
+ });
376
+ }
377
+ };
378
+
379
+ var unbindDocumentEvents = function() {
380
+ $(document).unbind('.mini-profiler');
371
381
  };
372
382
 
373
383
  var initFullView = function () {
@@ -456,11 +466,11 @@ var MiniProfiler = (function () {
456
466
  // fetch profile results for any ajax calls
457
467
  // note, this does not use $ cause we want to hook into the main jQuery
458
468
  if (jQuery && jQuery(document) && jQuery(document).ajaxComplete) {
459
- jQuery(document).ajaxComplete(jQueryAjaxComplete);
469
+ jQuery(document).bind('ajaxComplete.mini-profiler', jQueryAjaxComplete);
460
470
  }
461
471
 
462
472
  if (jQuery && jQuery(document).ajaxStart)
463
- jQuery(document).ajaxStart(function () { ajaxStartTime = new Date(); });
473
+ jQuery(document).bind('ajaxStart.mini-profiler', function () { ajaxStartTime = new Date(); });
464
474
 
465
475
  // fetch results after ASP Ajax calls
466
476
  if (typeof (Sys) != 'undefined' && typeof (Sys.WebForms) != 'undefined' && typeof (Sys.WebForms.PageRequestManager) != 'undefined') {
@@ -534,22 +544,27 @@ var MiniProfiler = (function () {
534
544
  var _send = XMLHttpRequest.prototype.send;
535
545
 
536
546
  XMLHttpRequest.prototype.send = function sendReplacement(data) {
537
- this._onreadystatechange = this.onreadystatechange;
547
+ if (this.onreadystatechange) {
548
+ if (typeof (this.miniprofiler) == 'undefined' || typeof (this.miniprofiler.prev_onreadystatechange) == 'undefined') {
549
+ this.miniprofiler = { prev_onreadystatechange: this.onreadystatechange };
538
550
 
539
- this.onreadystatechange = function onReadyStateChangeReplacement() {
540
- if (this.readyState == 4) {
541
- var stringIds = this.getResponseHeader('X-MiniProfiler-Ids');
542
- if (stringIds) {
543
- var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
544
- fetchResults(ids);
545
- }
546
- }
551
+ this.onreadystatechange = function onReadyStateChangeReplacement() {
552
+ if (this.readyState == 4) {
553
+ var stringIds = this.getResponseHeader('X-MiniProfiler-Ids');
554
+ if (stringIds) {
555
+ var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
556
+ fetchResults(ids);
557
+ }
558
+ }
547
559
 
548
- return this._onreadystatechange.apply(this, arguments);
549
- };
560
+ if (this.miniprofiler.prev_onreadystatechange != null)
561
+ return this.miniprofiler.prev_onreadystatechange.apply(this, arguments);
562
+ };
563
+ }
564
+ }
550
565
 
551
566
  return _send.apply(this, arguments);
552
- };
567
+ }
553
568
  }
554
569
 
555
570
  // some elements want to be hidden on certain doc events
@@ -644,6 +659,16 @@ var MiniProfiler = (function () {
644
659
  };
645
660
 
646
661
  var init = function() {
662
+
663
+ // jquery.hotkeys.js
664
+ // https://github.com/jeresig/jquery.hotkeys/blob/master/jquery.hotkeys.js
665
+
666
+ if (jQuery.hotkeys === undefined) {
667
+ (function(d){function h(g){if("string"===typeof g.data){var h=g.handler,j=g.data.toLowerCase().split(" ");g.handler=function(b){if(!(this!==b.target&&(/textarea|select/i.test(b.target.nodeName)||"text"===b.target.type))){var c="keypress"!==b.type&&d.hotkeys.specialKeys[b.which],e=String.fromCharCode(b.which).toLowerCase(),a="",f={};b.altKey&&"alt"!==c&&(a+="alt+");b.ctrlKey&&"ctrl"!==c&&(a+="ctrl+");b.metaKey&&(!b.ctrlKey&&"meta"!==c)&&(a+="meta+");b.shiftKey&&"shift"!==c&&(a+="shift+");c?f[a+c]=
668
+ !0:(f[a+e]=!0,f[a+d.hotkeys.shiftNums[e]]=!0,"shift+"===a&&(f[d.hotkeys.shiftNums[e]]=!0));c=0;for(e=j.length;c<e;c++)if(f[j[c]])return h.apply(this,arguments)}}}}d.hotkeys={version:"0.8",specialKeys:{8:"backspace",9:"tab",13:"return",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",
669
+ 109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",191:"/",224:"meta"},shiftNums:{"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(","0":")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|"}};d.each(["keydown","keyup","keypress"],function(){d.event.special[this]={add:h}})})(MiniProfiler.jQuery);
670
+ }
671
+
647
672
  if (options.authorized) {
648
673
  var url = options.path + "includes.css?v=" + options.version;
649
674
  if (document.createStyleSheet) {
@@ -660,13 +685,6 @@ var MiniProfiler = (function () {
660
685
  doInit();
661
686
  }
662
687
 
663
- // jquery.hotkeys.js
664
- // https://github.com/jeresig/jquery.hotkeys/blob/master/jquery.hotkeys.js
665
-
666
- (function(d){function h(g){if("string"===typeof g.data){var h=g.handler,j=g.data.toLowerCase().split(" ");g.handler=function(b){if(!(this!==b.target&&(/textarea|select/i.test(b.target.nodeName)||"text"===b.target.type))){var c="keypress"!==b.type&&d.hotkeys.specialKeys[b.which],e=String.fromCharCode(b.which).toLowerCase(),a="",f={};b.altKey&&"alt"!==c&&(a+="alt+");b.ctrlKey&&"ctrl"!==c&&(a+="ctrl+");b.metaKey&&(!b.ctrlKey&&"meta"!==c)&&(a+="meta+");b.shiftKey&&"shift"!==c&&(a+="shift+");c?f[a+c]=
667
- !0:(f[a+e]=!0,f[a+d.hotkeys.shiftNums[e]]=!0,"shift+"===a&&(f[d.hotkeys.shiftNums[e]]=!0));c=0;for(e=j.length;c<e;c++)if(f[j[c]])return h.apply(this,arguments)}}}}d.hotkeys={version:"0.8",specialKeys:{8:"backspace",9:"tab",13:"return",16:"shift",17:"ctrl",18:"alt",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",
668
- 109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scroll",191:"/",224:"meta"},shiftNums:{"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(","0":")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|"}};d.each(["keydown","keyup","keypress"],function(){d.event.special[this]={add:h}})})(MiniProfiler.jQuery);
669
-
670
688
  };
671
689
 
672
690
  var major, minor;
@@ -688,11 +706,15 @@ var MiniProfiler = (function () {
688
706
  }
689
707
  },
690
708
 
709
+ cleanUp: function() {
710
+ unbindDocumentEvents();
711
+ },
712
+
691
713
  getClientTimingByName: function (clientTiming, name) {
692
714
 
693
- for (var i = 0; i < clientTiming.Timings.length; i++) {
694
- if (clientTiming.Timings[i].Name == name) {
695
- return clientTiming.Timings[i];
715
+ for (var i = 0; i < clientTiming.timings.length; i++) {
716
+ if (clientTiming.timings[i].name == name) {
717
+ return clientTiming.timings[i];
696
718
  }
697
719
  }
698
720
  return { Name: name, Duration: "", Start: "" };
@@ -730,10 +752,10 @@ var MiniProfiler = (function () {
730
752
  var list = [];
731
753
  var t;
732
754
 
733
- if (!clientTimings.Timings) return [];
755
+ if (!clientTimings.timings) return [];
734
756
 
735
- for (var i = 0; i < clientTimings.Timings.length; i++) {
736
- t = clientTimings.Timings[i];
757
+ for (var i = 0; i < clientTimings.timings.length; i++) {
758
+ t = clientTimings.timings[i];
737
759
  var trivial = t.Name != "Dom Complete" && t.Name != "Response" && t.Name != "First Paint Time";
738
760
  trivial = t.Duration < 2 ? trivial : false;
739
761
  list.push(
@@ -752,19 +774,32 @@ var MiniProfiler = (function () {
752
774
  getSqlTimings: function (root) {
753
775
  var result = [],
754
776
  addToResults = function (timing) {
755
- if (timing.SqlTimings) {
756
- for (var i = 0, sqlTiming; i < timing.SqlTimings.length; i++) {
757
- sqlTiming = timing.SqlTimings[i];
777
+ if (timing.sql_timings) {
778
+ for (var i = 0, sqlTiming; i < timing.sql_timings.length; i++) {
779
+ sqlTiming = timing.sql_timings[i];
758
780
 
759
781
  // HACK: add info about the parent Timing to each SqlTiming so UI can render
760
- sqlTiming.ParentTimingName = timing.Name;
782
+ sqlTiming.parent_timing_name = timing.name;
783
+
784
+ if(sqlTiming.duration_milliseconds > 50) {
785
+ sqlTiming.row_class = "slow";
786
+ }
787
+
788
+ if(sqlTiming.duration_milliseconds > 200) {
789
+ sqlTiming.row_class = "very-slow";
790
+ }
791
+
792
+ if(sqlTiming.duration_milliseconds > 400) {
793
+ sqlTiming.row_class = "very-very-slow";
794
+ }
795
+
761
796
  result.push(sqlTiming);
762
797
  }
763
798
  }
764
799
 
765
- if (timing.Children) {
766
- for (var i = 0; i < timing.Children.length; i++) {
767
- addToResults(timing.Children[i]);
800
+ if (timing.children) {
801
+ for (var i = 0; i < timing.children.length; i++) {
802
+ addToResults(timing.children[i]);
768
803
  }
769
804
  }
770
805
  };
@@ -799,16 +834,16 @@ var MiniProfiler = (function () {
799
834
  };
800
835
 
801
836
  var processTimes = function (elem, parent) {
802
- var duration = { start: elem.StartMilliseconds, finish: (elem.StartMilliseconds + elem.DurationMilliseconds) };
837
+ var duration = { start: elem.start_milliseconds, finish: (elem.start_milliseconds + elem.duration_milliseconds) };
803
838
  elem.richTiming = [duration];
804
839
  if (parent != null) {
805
840
  elem.parent = parent;
806
841
  elem.parent.richTiming = removeDuration(elem.parent.richTiming, duration);
807
842
  }
808
843
 
809
- if (elem.Children) {
810
- for (var i = 0; i < elem.Children.length; i++) {
811
- processTimes(elem.Children[i], elem);
844
+ if (elem.children) {
845
+ for (var i = 0; i < elem.children.length; i++) {
846
+ processTimes(elem.children[i], elem);
812
847
  }
813
848
  }
814
849
  };
@@ -816,7 +851,7 @@ var MiniProfiler = (function () {
816
851
  processTimes(root, null);
817
852
 
818
853
  // sort results by time
819
- result.sort(function (a, b) { return a.StartMilliseconds - b.StartMilliseconds; });
854
+ result.sort(function (a, b) { return a.start_milliseconds - b.start_milliseconds; });
820
855
 
821
856
  var determineOverlap = function(gap, node) {
822
857
  var overlap = 0;
@@ -837,15 +872,15 @@ var MiniProfiler = (function () {
837
872
  var determineGap = function (gap, node, match) {
838
873
  var overlap = determineOverlap(gap, node);
839
874
  if (match == null || overlap > match.duration) {
840
- match = { name: node.Name, duration: overlap };
875
+ match = { name: node.name, duration: overlap };
841
876
  }
842
- else if (match.name == node.Name) {
877
+ else if (match.name == node.name) {
843
878
  match.duration += overlap;
844
879
  }
845
880
 
846
- if (node.Children) {
847
- for (var i = 0; i < node.Children.length; i++) {
848
- match = determineGap(gap, node.Children[i], match);
881
+ if (node.children) {
882
+ for (var i = 0; i < node.children.length; i++) {
883
+ match = determineGap(gap, node.children[i], match);
849
884
  }
850
885
  }
851
886
  return match;
@@ -855,14 +890,14 @@ var MiniProfiler = (function () {
855
890
  var prev = null;
856
891
  $.each(result, function () {
857
892
  this.prevGap = {
858
- duration: (this.StartMilliseconds - time).toFixed(2),
893
+ duration: (this.start_milliseconds - time).toFixed(2),
859
894
  start: time,
860
- finish: this.StartMilliseconds
895
+ finish: this.start_milliseconds
861
896
  };
862
897
 
863
898
  this.prevGap.topReason = determineGap(this.prevGap, root, null);
864
899
 
865
- time = this.StartMilliseconds + this.DurationMilliseconds;
900
+ time = this.start_milliseconds + this.duration_milliseconds;
866
901
  prev = this;
867
902
  });
868
903
 
@@ -870,9 +905,9 @@ var MiniProfiler = (function () {
870
905
  if (result.length > 0) {
871
906
  var me = result[result.length - 1];
872
907
  me.nextGap = {
873
- duration: (root.DurationMilliseconds - time).toFixed(2),
908
+ duration: (root.duration_milliseconds - time).toFixed(2),
874
909
  start: time,
875
- finish: root.DurationMilliseconds
910
+ finish: root.duration_milliseconds
876
911
  };
877
912
  me.nextGap.topReason = determineGap(me.nextGap, root, null);
878
913
  }
@@ -883,13 +918,13 @@ var MiniProfiler = (function () {
883
918
  getSqlTimingsCount: function (root) {
884
919
  var result = 0,
885
920
  countSql = function (timing) {
886
- if (timing.SqlTimings) {
887
- result += timing.SqlTimings.length;
921
+ if (timing.sql_timings) {
922
+ result += timing.sql_timings.length;
888
923
  }
889
924
 
890
- if (timing.Children) {
891
- for (var i = 0; i < timing.Children.length; i++) {
892
- countSql(timing.Children[i]);
925
+ if (timing.children) {
926
+ for (var i = 0; i < timing.children.length; i++) {
927
+ countSql(timing.children[i]);
893
928
  }
894
929
  }
895
930
  };
@@ -157,6 +157,27 @@
157
157
  .profiler-stack-trace {
158
158
  margin-bottom:15px;
159
159
  }
160
+
161
+ tbody tr {
162
+ border-bottom: 1px solid #f1f1f1;
163
+ }
164
+
165
+ tr {
166
+ background-color: #FFF;
167
+ }
168
+
169
+ tr.slow {
170
+ background-color: #FEE;
171
+ }
172
+
173
+ tr.very-slow {
174
+ background-color: #FDD;
175
+ }
176
+
177
+ tr.very-very-slow {
178
+ background-color: #FCC;
179
+ }
180
+
160
181
  pre {
161
182
  font-family:@codeFonts;
162
183
  white-space:pre-wrap;
@@ -173,17 +194,12 @@
173
194
  td {
174
195
  padding:15px;
175
196
  text-align:left;
176
- background-color:#fff;
177
197
 
178
198
  &:last-child {
179
199
  padding-right:25px; // compensate for scrollbars
180
200
  }
181
201
  }
182
202
 
183
- .profiler-odd td {
184
- background-color:#e5e5e5;
185
- }
186
-
187
203
  .profiler-since-start, .profiler-duration {
188
204
  text-align:right;
189
205
  }
@@ -2,19 +2,19 @@
2
2
 
3
3
  <div class="profiler-result">
4
4
 
5
- <div class="profiler-button {{if HasDuplicateSqlTimings}}profiler-warning{{/if}}">
6
- {{if HasDuplicateSqlTimings}}<span class="profiler-nuclear">!</span>{{/if}}
5
+ <div class="profiler-button {{if has_duplicate_sql_timings}}profiler-warning{{/if}}">
6
+ {{if has_duplicate_sql_timings}}<span class="profiler-nuclear">!</span>{{/if}}
7
7
  <span class="profiler-number">
8
- ${MiniProfiler.formatDuration(DurationMilliseconds)} <span class="profiler-unit">ms</span>
8
+ ${MiniProfiler.formatDuration(duration_milliseconds)} <span class="profiler-unit">ms</span>
9
9
  </span>
10
10
  </div>
11
11
 
12
12
  <div class="profiler-popup">
13
13
  <div class="profiler-info">
14
14
  <span class="profiler-name">
15
- ${Name} <span class="profiler-overall-duration">(${MiniProfiler.formatDuration(DurationMilliseconds)} ms)</span>
15
+ ${name} <span class="profiler-overall-duration">(${MiniProfiler.formatDuration(duration_milliseconds)} ms)</span>
16
16
  </span>
17
- <span class="profiler-server-time">${MachineName} on ${MiniProfiler.renderDate(Started)}</span>
17
+ <span class="profiler-server-time">${machine_name} on ${MiniProfiler.renderDate(started)}</span>
18
18
  </div>
19
19
  <div class="profiler-output">
20
20
  <table class="profiler-timings">
@@ -24,41 +24,41 @@
24
24
  <th>duration (ms)</th>
25
25
  <th class="profiler-duration-with-children">with children (ms)</th>
26
26
  <th class="time-from-start">from start (ms)</th>
27
- {{if HasSqlTimings}}
27
+ {{if has_sql_timings}}
28
28
  <th colspan="2">query time (ms)</th>
29
29
  {{/if}}
30
- {{each CustomTimingNames}}
30
+ {{each custom_timing_names}}
31
31
  <th colspan="2">${$value.toLowerCase()} (ms)</th>
32
32
  {{/each}}
33
33
  </tr>
34
34
  </thead>
35
35
  <tbody>
36
- {{tmpl({timing:Root, page:this.data}) "#timingTemplate"}}
36
+ {{tmpl({timing:root, page:this.data}) "#timingTemplate"}}
37
37
  </tbody>
38
38
  <tfoot>
39
39
  <tr>
40
40
  <td colspan="3">
41
- {{if !ClientTimings}}
41
+ {{if !client_timings}}
42
42
  {{tmpl "#linksTemplate"}}
43
43
  {{/if}}
44
44
  <a class="profiler-toggle-duration-with-children" title="toggles column with aggregate child durations">show time with children</a>
45
45
  </td>
46
- {{if HasSqlTimings}}
47
- <td colspan="2" class="profiler-number profiler-percent-in-sql" title="${MiniProfiler.getSqlTimingsCount(Root)} queries spent ${MiniProfiler.formatDuration(DurationMillisecondsInSql)} ms of total request time">
48
- ${MiniProfiler.formatDuration(DurationMillisecondsInSql / DurationMilliseconds * 100)}
46
+ {{if has_sql_timings}}
47
+ <td colspan="2" class="profiler-number profiler-percent-in-sql" title="${MiniProfiler.getSqlTimingsCount(root)} queries spent ${MiniProfiler.formatDuration(duration_milliseconds_in_sql)} ms of total request time">
48
+ ${MiniProfiler.formatDuration(duration_milliseconds_in_sql / duration_milliseconds * 100)}
49
49
  <span class="profiler-unit">% in sql</span>
50
50
  </td>
51
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)}
52
+ {{each custom_timing_names}}
53
+ <td colspan="2" class="profiler-number profiler-percentage-in-sql" title="${custom_timing_stats[$value].count} ${$value.toLowerCase()} invocations spent ${MiniProfiler.formatDuration(custom_timing_stats[$value].duration)} ms of total request time">
54
+ ${MiniProfiler.formatDuration(custom_timing_stats[$value].duration / duration_milliseconds * 100)}
55
55
  <span class="profiler-unit">% in ${$value.toLowerCase()}</span>
56
56
  </td>
57
57
  {{/each}}
58
58
  </tr>
59
59
  </tfoot>
60
60
  </table>
61
- {{if ClientTimings}}
61
+ {{if client_timings}}
62
62
  <table class="profiler-timings profiler-client-timings">
63
63
  <thead>
64
64
  <tr>
@@ -68,7 +68,7 @@
68
68
  </tr>
69
69
  </thead>
70
70
  <tbody>
71
- {{each MiniProfiler.getClientTimings(ClientTimings)}}
71
+ {{each MiniProfiler.getClientTimings(client_timings)}}
72
72
  <tr class="{{if $value.isTrivial }}profiler-trivial{{/if}}">
73
73
  <td class="profiler-label">${$value.name}</td>
74
74
  <td class="profiler-duration">
@@ -92,7 +92,7 @@
92
92
  </div>
93
93
  </div>
94
94
 
95
- {{if HasSqlTimings}}
95
+ {{if has_sql_timings}}
96
96
  <div class="profiler-queries">
97
97
  <table>
98
98
  <thead>
@@ -102,7 +102,7 @@
102
102
  </tr>
103
103
  </thead>
104
104
  <tbody>
105
- {{each(i, s) MiniProfiler.getSqlTimings(Root)}}
105
+ {{each(i, s) MiniProfiler.getSqlTimings(root)}}
106
106
  {{tmpl({ g:s.prevGap }) "#sqlGapTemplate"}}
107
107
  {{tmpl({ i:i, s:s }) "#sqlTimingTemplate"}}
108
108
  {{if s.nextGap}}
@@ -122,12 +122,12 @@
122
122
  </script>
123
123
 
124
124
  <script id="linksTemplate" type="text/x-jquery-tmpl">
125
- <a href="${MiniProfiler.shareUrl(Id)}" class="profiler-share-profiler-results" target="_blank">share</a>
126
- {{if CustomLink}}
127
- <a href="${CustomLink}" class="profiler-custom-link" target="_blank">${CustomLinkName}</a>
125
+ <a href="${MiniProfiler.shareUrl(id)}" class="profiler-share-profiler-results" target="_blank">share</a>
126
+ {{if custom_link}}
127
+ <a href="${custom_link}" class="profiler-custom-link" target="_blank">${custom_link_name}</a>
128
128
  {{/if}}
129
- {{if HasTrivialTimings}}
130
- <a class="profiler-toggle-trivial" data-show-on-load="${HasAllTrivialTimings}" title="toggles any rows with &lt; ${TrivialDurationThresholdMilliseconds} ms">
129
+ {{if has_trivial_timings}}
130
+ <a class="profiler-toggle-trivial" data-show-on-load="${has_all_trivial_timings}" title="toggles any rows with &lt; ${trivial_duration_threshold_milliseconds} ms">
131
131
  show trivial
132
132
  </a>
133
133
  {{/if}}
@@ -135,41 +135,41 @@
135
135
 
136
136
  <script id="timingTemplate" type="text/x-jquery-tmpl">
137
137
 
138
- <tr class="{{if timing.IsTrivial }}profiler-trivial{{/if}}" data-timing-id="${timing.Id}">
139
- <td class="profiler-label" title="{{if timing.Name && timing.Name.length > 45 }}${timing.Name}{{/if}}">
140
- <span class="profiler-indent">${MiniProfiler.renderIndent(timing.Depth)}</span> ${timing.Name.slice(0,45)}{{if timing.Name && timing.Name.length > 45 }}...{{/if}}
138
+ <tr class="{{if timing.is_trivial }}profiler-trivial{{/if}}" data-timing-id="${timing.id}">
139
+ <td class="profiler-label" title="{{if timing.name && timing.name.length > 45 }}${timing.name}{{/if}}">
140
+ <span class="profiler-indent">${MiniProfiler.renderIndent(timing.depth)}</span> ${timing.name.slice(0,45)}{{if timing.name && timing.name.length > 45 }}...{{/if}}
141
141
  </td>
142
142
  <td class="profiler-duration" title="duration of this step without any children's durations">
143
- ${MiniProfiler.formatDuration(timing.DurationWithoutChildrenMilliseconds)}
143
+ ${MiniProfiler.formatDuration(timing.duration_without_children_milliseconds)}
144
144
  </td>
145
145
  <td class="profiler-duration profiler-duration-with-children" title="duration of this step and its children">
146
- ${MiniProfiler.formatDuration(timing.DurationMilliseconds)}
146
+ ${MiniProfiler.formatDuration(timing.duration_milliseconds)}
147
147
  </td>
148
148
  <td class="profiler-duration time-from-start" title="time elapsed since profiling started">
149
- <span class="profiler-unit">+</span>${MiniProfiler.formatDuration(timing.StartMilliseconds)}
149
+ <span class="profiler-unit">+</span>${MiniProfiler.formatDuration(timing.start_milliseconds)}
150
150
  </td>
151
151
 
152
- {{if timing.HasSqlTimings}}
153
- <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}}">
152
+ {{if timing.has_sql_timings}}
153
+ <td class="profiler-duration {{if timing.has_duplicate_sql_timings}}profiler-warning{{/if}}" title="{{if timing.has_duplicate_sql_timings}}duplicate queries detected - {{/if}}{{if timing.executed_readers > 0 || timing.executed_scalars > 0 || timing.executed_non_queries > 0}}${timing.executed_readers} reader, ${timing.executed_scalars} scalar, ${timing.executed_non_queries} non-query statements executed{{/if}}">
154
154
  <a class="profiler-queries-show">
155
- {{if timing.HasDuplicateSqlTimings}}<span class="profiler-nuclear">!</span>{{/if}}
156
- ${timing.SqlTimings.length} <span class="profiler-unit">sql</span>
155
+ {{if timing.has_duplicate_sql_timings}}<span class="profiler-nuclear">!</span>{{/if}}
156
+ ${timing.sql_timings.length} <span class="profiler-unit">sql</span>
157
157
  </a>
158
158
  </td>
159
159
  <td class="profiler-duration" title="aggregate duration of all queries in this step (excludes children)">
160
- ${MiniProfiler.formatDuration(timing.SqlTimingsDurationMilliseconds)}
160
+ ${MiniProfiler.formatDuration(timing.sql_timings_duration_milliseconds)}
161
161
  </td>
162
162
  {{else}}
163
163
  <td colspan="2"></td>
164
164
  {{/if}}
165
165
 
166
- {{each page.CustomTimingNames}}
167
- {{if timing.CustomTimings && timing.CustomTimings[$value]}}
166
+ {{each page.custom_timing_names}}
167
+ {{if timing.custom_timings && timing.custom_timings[$value]}}
168
168
  <td class="profiler-duration" title="aggregate number of all ${$value.toLowerCase()} invocations in this step (excludes children)">
169
- ${timing.CustomTimings[$value].length} ${$value.toLowerCase()}
169
+ ${timing.custom_timings[$value].length} ${$value.toLowerCase()}
170
170
  </td>
171
171
  <td class="profiler-duration" title="aggregate duration of all ${$value.toLowerCase()} invocations in this step (excludes children)">
172
- ${MiniProfiler.formatDuration(timing.CustomTimingStats[$value].Duration)}
172
+ ${MiniProfiler.formatDuration(timing.custom_timing_stats[$value].duration)}
173
173
  </td>
174
174
  {{else}}
175
175
  <td colspan="2"></td>
@@ -178,8 +178,8 @@
178
178
 
179
179
  </tr>
180
180
 
181
- {{if timing.HasChildren}}
182
- {{each timing.Children}}
181
+ {{if timing.has_children}}
182
+ {{each timing.children}}
183
183
  {{tmpl({timing: $value, page: page}) "#timingTemplate"}}
184
184
  {{/each}}
185
185
  {{/if}}
@@ -188,20 +188,20 @@
188
188
 
189
189
  <script id="sqlTimingTemplate" type="text/x-jquery-tmpl">
190
190
 
191
- <tr class="{{if i % 2 == 1}}profiler-odd{{/if}}" data-timing-id="${s.ParentTimingId}">
191
+ <tr class="${s.row_class}" data-timing-id="${s.parent_timing_id}">
192
192
  <td class="profiler-info">
193
- <div>${s.ParentTimingName}</div>
194
- <div class="profiler-number"><span class="profiler-unit">T+</span>${MiniProfiler.formatDuration(s.StartMilliseconds)} <span class="profiler-unit">ms</span></div>
193
+ <div>${s.parent_timing_name}</div>
194
+ <div class="profiler-number"><span class="profiler-unit">T+</span>${MiniProfiler.formatDuration(s.start_milliseconds)} <span class="profiler-unit">ms</span></div>
195
195
  <div>
196
- {{if s.IsDuplicate}}<span class="profiler-warning">DUPLICATE</span>{{/if}}
197
- ${MiniProfiler.renderExecuteType(s.ExecuteType)}
196
+ {{if s.is_duplicate}}<span class="profiler-warning">DUPLICATE</span>{{/if}}
197
+ ${MiniProfiler.renderExecuteType(s.execute_type)}
198
198
  </div>
199
- <div title="{{if s.ExecuteType == 3}}first result fetched: ${s.FirstFetchDurationMilliseconds}ms{{/if}}">${MiniProfiler.formatDuration(s.DurationMilliseconds)} <span class="profiler-unit">ms</span></div>
199
+ <div title="{{if s.execute_type == 3}}first result fetched: ${s.first_fetch_duration_milliseconds}ms{{/if}}">${MiniProfiler.formatDuration(s.duration_milliseconds)} <span class="profiler-unit">ms</span></div>
200
200
  </td>
201
201
  <td>
202
202
  <div class="query">
203
- <pre class="profiler-stack-trace">${s.StackTraceSnippet}</pre>
204
- <pre class="prettyprint lang-sql"><code>${s.FormattedCommandString} </code></pre>
203
+ <pre class="profiler-stack-trace">${s.stack_trace_snippet}</pre>
204
+ <pre class="prettyprint lang-sql"><code>${s.formatted_command_string} </code></pre>
205
205
  </div>
206
206
  </td>
207
207
  </tr>