rack-mini-profiler 0.1 → 0.1.21
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.
- data/CHANGELOG +99 -0
- data/README.md +72 -24
- data/lib/html/includes.css +75 -1
- data/lib/html/includes.js +42 -11
- data/lib/html/includes.less +2 -2
- data/lib/html/includes.tmpl +2 -2
- data/lib/html/profile_handler.js +9 -9
- data/lib/mini_profiler/client_settings.rb +65 -0
- data/lib/mini_profiler/client_timer_struct.rb +38 -3
- data/lib/mini_profiler/config.rb +52 -0
- data/lib/mini_profiler/context.rb +10 -0
- data/lib/mini_profiler/gc_profiler.rb +84 -0
- data/lib/mini_profiler/page_timer_struct.rb +7 -3
- data/lib/mini_profiler/profiler.rb +312 -142
- data/lib/mini_profiler/profiling_methods.rb +108 -0
- data/lib/mini_profiler/request_timer_struct.rb +40 -9
- data/lib/mini_profiler/sql_timer_struct.rb +26 -5
- data/lib/mini_profiler/storage/abstract_store.rb +0 -0
- data/lib/mini_profiler/storage/file_store.rb +8 -7
- data/lib/mini_profiler/storage/memcache_store.rb +51 -0
- data/lib/mini_profiler/storage/memory_store.rb +1 -6
- data/lib/mini_profiler/storage/redis_store.rb +2 -1
- data/lib/mini_profiler/timer_struct.rb +3 -1
- data/lib/mini_profiler_rails/railtie.rb +66 -11
- data/lib/patches/sql_patches.rb +198 -39
- data/lib/rack-mini-profiler.rb +4 -4
- data/rack-mini-profiler.gemspec +8 -8
- metadata +16 -10
- data/lib/html/MiniProfilerHandler.cs +0 -419
- data/lib/mini_profiler/body_add_proxy.rb +0 -45
data/CHANGELOG
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
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
|
data/README.md
CHANGED
|
@@ -1,27 +1,31 @@
|
|
|
1
1
|
# rack-mini-profiler
|
|
2
2
|
|
|
3
|
-
Middleware that displays speed badge for every html page.
|
|
3
|
+
Middleware that displays speed badge for every html page. Designed to work both in production and in development.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
7
|
-
MiniProfiler keeps you aware of your site's performance as you are developing it.
|
|
8
|
-
It does this by....
|
|
9
|
-
|
|
10
|
-
`env['profiler.mini']` is the profiler
|
|
11
|
-
|
|
12
|
-
## Using mini-profiler in your app
|
|
5
|
+
## Using rack-mini-profiler in your app
|
|
13
6
|
|
|
14
7
|
Install/add to Gemfile
|
|
15
8
|
|
|
16
9
|
```ruby
|
|
17
10
|
gem 'rack-mini-profiler'
|
|
18
11
|
```
|
|
12
|
+
Using Rails:
|
|
19
13
|
|
|
20
|
-
|
|
14
|
+
All you have to do is include the Gem and you're good to go in development.
|
|
21
15
|
|
|
22
|
-
|
|
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
|
+
|
|
18
|
+
For example:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
# A hook in your ApplicationController
|
|
22
|
+
def authorize
|
|
23
|
+
if current_user.is_admin?
|
|
24
|
+
Rack::MiniProfiler.authorize_request
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
````
|
|
23
28
|
|
|
24
|
-
All you have to do is include the Gem and you're good to go.
|
|
25
29
|
|
|
26
30
|
Using Builder:
|
|
27
31
|
|
|
@@ -43,6 +47,24 @@ class MyApp < Sinatra::Base
|
|
|
43
47
|
end
|
|
44
48
|
```
|
|
45
49
|
|
|
50
|
+
## Storage
|
|
51
|
+
|
|
52
|
+
By default, rack-mini-profiler stores its results in a memory store:
|
|
53
|
+
|
|
54
|
+
```ruby
|
|
55
|
+
# our default
|
|
56
|
+
Rack::MiniProfiler.config.storage = Rack::MiniProfiler::MemoryStore
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
There are 2 other available storage engines, `RedisStore`, `MemcacheStore`, and `FileStore`.
|
|
60
|
+
|
|
61
|
+
MemoryStore is stores results in a processes heap - something that does not work well in a multi process environment.
|
|
62
|
+
FileStore stores results in the file system - something that may not work well in a multi machine environment.
|
|
63
|
+
|
|
64
|
+
Additionally you may implement an AbstractStore for your own provider.
|
|
65
|
+
|
|
66
|
+
Rails hooks up a FileStore for all environments.
|
|
67
|
+
|
|
46
68
|
## Running the Specs
|
|
47
69
|
|
|
48
70
|
```
|
|
@@ -58,25 +80,51 @@ You can set configuration options using the configuration accessor on Rack::Mini
|
|
|
58
80
|
|
|
59
81
|
```
|
|
60
82
|
# Have Mini Profiler show up on the right
|
|
61
|
-
Rack::MiniProfiler.
|
|
83
|
+
Rack::MiniProfiler.config.position = 'right'
|
|
62
84
|
```
|
|
63
85
|
|
|
64
86
|
In a Rails app, this can be done conveniently in an initializer such as config/initializers/mini_profiler.rb.
|
|
65
87
|
|
|
88
|
+
## Rails 2.X support
|
|
89
|
+
|
|
90
|
+
To get MiniProfiler working with Rails 2.3.X you need to do the initialization manually as well as monkey patch away an incompatibility between activesupport and json_pure.
|
|
91
|
+
|
|
92
|
+
Add the following code to your environment.rb (or just in a specific environment such as development.rb) for initialization and configuration of MiniProfiler.
|
|
93
|
+
|
|
94
|
+
```ruby
|
|
95
|
+
# configure and initialize MiniProfiler
|
|
96
|
+
require 'rack-mini-profiler'
|
|
97
|
+
c = ::Rack::MiniProfiler.config
|
|
98
|
+
c.pre_authorize_cb = lambda { |env|
|
|
99
|
+
Rails.env.development? || Rails.env.production?
|
|
100
|
+
}
|
|
101
|
+
tmp = Rails.root.to_s + "/tmp/miniprofiler"
|
|
102
|
+
FileUtils.mkdir_p(tmp) unless File.exists?(tmp)
|
|
103
|
+
c.storage_options = {:path => tmp}
|
|
104
|
+
c.storage = ::Rack::MiniProfiler::FileStore
|
|
105
|
+
config.middleware.use(::Rack::MiniProfiler)
|
|
106
|
+
::Rack::MiniProfiler.profile_method(ActionController::Base, :process) {|action| "Executing action: #{action}"}
|
|
107
|
+
::Rack::MiniProfiler.profile_method(ActionView::Template, :render) {|x,y| "Rendering: #{@virtual_path}"}
|
|
108
|
+
|
|
109
|
+
# monkey patch away an activesupport and json_pure incompatability
|
|
110
|
+
# http://pivotallabs.com/users/alex/blog/articles/1332-monkey-patch-of-the-day-activesupport-vs-json-pure-vs-ruby-1-8
|
|
111
|
+
if JSON.const_defined?(:Pure)
|
|
112
|
+
class JSON::Pure::Generator::State
|
|
113
|
+
include ActiveSupport::CoreExtensions::Hash::Except
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
```
|
|
117
|
+
|
|
66
118
|
## Available Options
|
|
67
119
|
|
|
68
|
-
*
|
|
120
|
+
* 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.
|
|
69
121
|
* position - Can either be 'right' or 'left'. Default is 'left'.
|
|
70
|
-
* skip_schema_queries - Whether or not you want to log the queries about the schema of your tables. Default is 'true'
|
|
71
|
-
|
|
122
|
+
* 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
|
+
* auto_inject (default true) - when false the miniprofiler script is not injected in the page
|
|
125
|
+
* backtrace_filter - a regex you can use to filter out unwanted lines from the backtraces
|
|
72
126
|
|
|
73
|
-
##
|
|
127
|
+
## Special query strings
|
|
74
128
|
|
|
75
|
-
|
|
76
|
-
- Decide if we hook up SQL at the driver level (eg mysql gem) or library level (eg active record) - my personal perference is to do driver level hooks (Sam)
|
|
77
|
-
- Add automatic instrumentation for Rails (Controller times, Action times, Partial times, Layout times)
|
|
78
|
-
- Grab / display the parameters of SQL executed for parameterized SQL
|
|
79
|
-
- Beef up the documentation
|
|
80
|
-
- Auto-wire-up rails middleware
|
|
81
|
-
- Review our API and ensure it is trivial
|
|
129
|
+
If you include the query string `pp=help` at the end of your request you will see the various option you have. You can use these options to extend or contract the amount of diagnostics rack-mini-profiler gathers.
|
|
82
130
|
|
data/lib/html/includes.css
CHANGED
|
@@ -1 +1,75 @@
|
|
|
1
|
-
.profiler-result,.profiler-queries{color:#555;line-height:1;font-size:12px;}.profiler-result pre,.profiler-queries pre,.profiler-result code,.profiler-queries code,.profiler-result label,.profiler-queries label,.profiler-result table,.profiler-queries table,.profiler-result tbody,.profiler-queries tbody,.profiler-result thead,.profiler-queries thead,.profiler-result tfoot,.profiler-queries tfoot,.profiler-result tr,.profiler-queries tr,.profiler-result th,.profiler-queries th,.profiler-result td,.profiler-queries td{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline;background-color:transparent;overflow:visible;max-height:none;}.profiler-result table,.profiler-queries table{border-collapse:collapse;border-spacing:0;}.profiler-result a,.profiler-queries a,.profiler-result a:hover,.profiler-queries a:hover{cursor:pointer;color:#07c;}.profiler-result a,.profiler-queries a{text-decoration:none;}.profiler-result a:hover,.profiler-queries a:hover{text-decoration:underline;}.profiler-result{font-family:Helvetica,Arial,sans-serif;}.profiler-result .profiler-toggle-duration-with-children{float:right;}.profiler-result table.profiler-client-timings{margin-top:10px;}.profiler-result .profiler-label{color:#555;overflow:hidden;text-overflow:ellipsis;}.profiler-result .profiler-unit{color:#aaa;}.profiler-result .profiler-trivial{display:none;}.profiler-result .profiler-trivial td,.profiler-result .profiler-trivial td *{color:#aaa !important;}.profiler-result pre,.profiler-result code,.profiler-result .profiler-number,.profiler-result .profiler-unit{font-family:Consolas,monospace,serif;}.profiler-result .profiler-number{color:#111;}.profiler-result .profiler-info{text-align:right;}.profiler-result .profiler-info .profiler-name{float:left;}.profiler-result .profiler-info .profiler-server-time{white-space:nowrap;}.profiler-result .profiler-timings th{background-color:#fff;color:#aaa;text-align:right;}.profiler-result .profiler-timings th,.profiler-result .profiler-timings td{white-space:nowrap;}.profiler-result .profiler-timings .profiler-duration-with-children{display:none;}.profiler-result .profiler-timings .profiler-duration{font-family:Consolas,monospace,serif;color:#111;text-align:right;}.profiler-result .profiler-timings .profiler-indent{letter-spacing:4px;}.profiler-result .profiler-timings .profiler-queries-show .profiler-number,.profiler-result .profiler-timings .profiler-queries-show .profiler-unit{color:#07c;}.profiler-result .profiler-timings .profiler-queries-duration{padding-left:6px;}.profiler-result .profiler-timings .profiler-percent-in-sql{white-space:nowrap;text-align:right;}.profiler-result .profiler-timings tfoot td{padding-top:10px;text-align:right;}.profiler-result .profiler-timings tfoot td a{font-size:95%;display:inline-block;margin-left:12px;}.profiler-result .profiler-timings tfoot td a:first-child{float:left;margin-left:0px;}.profiler-result .profiler-queries{font-family:Helvetica,Arial,sans-serif;}.profiler-result .profiler-queries .profiler-stack-trace{margin-bottom:15px;}.profiler-result .profiler-queries pre{font-family:Consolas,monospace,serif;white-space:pre-wrap;}.profiler-result .profiler-queries th{background-color:#fff;border-bottom:1px solid #555;font-weight:bold;padding:15px;white-space:nowrap;}.profiler-result .profiler-queries td{padding:15px;text-align:left;background-color:#fff;}.profiler-result .profiler-queries td:last-child{padding-right:25px;}.profiler-result .profiler-queries .profiler-odd td{background-color:#e5e5e5;}.profiler-result .profiler-queries .profiler-since-start,.profiler-result .profiler-queries .profiler-duration{text-align:right;}.profiler-result .profiler-queries .profiler-info div{text-align:right;margin-bottom:5px;}.profiler-result .profiler-queries .profiler-gap-info,.profiler-result .profiler-queries .profiler-gap-info td{background-color:#ccc;}.profiler-result .profiler-queries .profiler-gap-info .profiler-unit{color:#777;}.profiler-result .profiler-queries .profiler-gap-info .profiler-info{text-align:right;}.profiler-result .profiler-queries .profiler-gap-info.profiler-trivial-gaps{display:none;}.profiler-result .profiler-queries .profiler-trivial-gap-container{text-align:center;}.profiler-result .profiler-queries .str{color:maroon;}.profiler-result .profiler-queries .kwd{color:#00008b;}.profiler-result .profiler-queries .com{color:gray;}.profiler-result .profiler-queries .typ{color:#2b91af;}.profiler-result .profiler-queries .lit{color:maroon;}.profiler-result .profiler-queries .pun{color:#000;}.profiler-result .profiler-queries .pln{color:#000;}.profiler-result .profiler-queries .tag{color:maroon;}.profiler-result .profiler-queries .atn{color:red;}.profiler-result .profiler-queries .atv{color:blue;}.profiler-result .profiler-queries .dec{color:purple;}.profiler-result .profiler-warning,.profiler-result .profiler-warning *,.profiler-result .profiler-warning .profiler-queries-show,.profiler-result .profiler-warning .profiler-queries-show .profiler-unit{color:#f00;}.profiler-result .profiler-warning:hover,.profiler-result .profiler-warning *:hover,.profiler-result .profiler-warning .profiler-queries-show:hover,.profiler-result .profiler-warning .profiler-queries-show .profiler-unit:hover{color:#f00;}.profiler-result .profiler-nuclear{color:#f00;font-weight:bold;padding-right:2px;}.profiler-result .profiler-nuclear:hover{color:#f00;}.profiler-results{z-index:2147483643;position:fixed;top:0px;}.profiler-results.profiler-left{left:0px;}.profiler-results.profiler-left.profiler-no-controls .profiler-result:last-child .profiler-button,.profiler-results.profiler-left .profiler-controls{-webkit-border-bottom-right-radius:10px;-moz-border-radius-bottomright:10px;border-bottom-right-radius:10px;}.profiler-results.profiler-left .profiler-button,.profiler-results.profiler-left .profiler-controls{border-right:1px solid #888;}.profiler-results.profiler-right{right:0px;}.profiler-results.profiler-right.profiler-no-controls .profiler-result:last-child .profiler-button,.profiler-results.profiler-right .profiler-controls{-webkit-border-bottom-left-radius:10px;-moz-border-radius-bottomleft:10px;border-bottom-left-radius:10px;}.profiler-results.profiler-right .profiler-button,.profiler-results.profiler-right .profiler-controls{border-left:1px solid #888;}.profiler-results .profiler-button,.profiler-results .profiler-controls{display:none;z-index:2147483640;border-bottom:1px solid #888;background-color:#fff;padding:4px 7px;text-align:right;cursor:pointer;}.profiler-results .profiler-button.profiler-button-active,.profiler-results .profiler-controls.profiler-button-active{background-color:maroon;}.profiler-results .profiler-button.profiler-button-active .profiler-number,.profiler-results .profiler-controls.profiler-button-active .profiler-number,.profiler-results .profiler-button.profiler-button-active .profiler-nuclear,.profiler-results .profiler-controls.profiler-button-active .profiler-nuclear{color:#fff;font-weight:bold;}.profiler-results .profiler-button.profiler-button-active .profiler-unit,.profiler-results .profiler-controls.profiler-button-active .profiler-unit{color:#fff;font-weight:normal;}.profiler-results .profiler-controls{display:block;font-size:12px;font-family:Consolas,monospace,serif;cursor:default;text-align:center;}.profiler-results .profiler-controls span{border-right:1px solid #aaa;padding-right:5px;margin-right:5px;cursor:pointer;}.profiler-results .profiler-controls span:last-child{border-right:none;}.profiler-results .profiler-popup{display:none;z-index:2147483641;position:absolute;background-color:#fff;border:1px solid #aaa;padding:5px 10px;text-align:left;line-height:18px;overflow:auto;-moz-box-shadow:0px 1px 15px #555;-webkit-box-shadow:0px 1px 15px #555;box-shadow:0px 1px 15px #555;}.profiler-results .profiler-popup .profiler-info{margin-bottom:3px;padding-bottom:2px;border-bottom:1px solid #ddd;}.profiler-results .profiler-popup .profiler-info .profiler-name{font-size:110%;font-weight:bold;}.profiler-results .profiler-popup .profiler-info .profiler-name .profiler-overall-duration{display:none;}.profiler-results .profiler-popup .profiler-info .profiler-server-time{font-size:95%;}.profiler-results .profiler-popup .profiler-timings th,.profiler-results .profiler-popup .profiler-timings td{padding-left:6px;padding-right:6px;}.profiler-results .profiler-popup .profiler-timings th{font-size:95%;padding-bottom:3px;}.profiler-results .profiler-popup .profiler-timings .profiler-label{max-width:275px;}.profiler-results .profiler-queries{display:none;z-index:2147483643;position:absolute;overflow-y:auto;overflow-x:hidden;background-color:#fff;}.profiler-results .profiler-queries th{font-size:17px;}.profiler-results.profiler-min .profiler-result{display:none;}.profiler-results.profiler-min .profiler-controls span{display:none;}.profiler-results.profiler-min .profiler-controls .profiler-min-max{border-right:none;padding:0px;margin:0px;}.profiler-queries-bg{z-index:2147483642;display:none;background:#000;opacity:0.7;position:absolute;top:0px;left:0px;min-width:100%;}.profiler-result-full .profiler-result{width:950px;margin:30px auto;}.profiler-result-full .profiler-result .profiler-button{display:none;}.profiler-result-full .profiler-result .profiler-popup .profiler-info{font-size:25px;border-bottom:1px solid #aaa;padding-bottom:3px;margin-bottom:25px;}.profiler-result-full .profiler-result .profiler-popup .profiler-info .profiler-overall-duration{padding-right:20px;font-size:80%;color:#888;}.profiler-result-full .profiler-result .profiler-popup .profiler-timings td,.profiler-result-full .profiler-result .profiler-popup .profiler-timings th{padding-left:8px;padding-right:8px;}.profiler-result-full .profiler-result .profiler-popup .profiler-timings th{padding-bottom:7px;}.profiler-result-full .profiler-result .profiler-popup .profiler-timings td{font-size:14px;padding-bottom:4px;}.profiler-result-full .profiler-result .profiler-popup .profiler-timings td:first-child{padding-left:10px;}.profiler-result-full .profiler-result .profiler-popup .profiler-timings .profiler-label{max-width:550px;}.profiler-result-full .profiler-result .profiler-queries{margin:25px 0;}.profiler-result-full .profiler-result .profiler-queries table{width:100%;}.profiler-result-full .profiler-result .profiler-queries th{font-size:16px;color:#555;line-height:20px;}.profiler-result-full .profiler-result .profiler-queries td{padding:15px 10px;text-align:left;}.profiler-result-full .profiler-result .profiler-queries .profiler-info div{text-align:right;margin-bottom:5px;}
|
|
1
|
+
.profiler-result,.profiler-queries{color:#555;line-height:1;font-size:12px;}.profiler-result pre,.profiler-queries pre,.profiler-result code,.profiler-queries code,.profiler-result label,.profiler-queries label,.profiler-result table,.profiler-queries table,.profiler-result tbody,.profiler-queries tbody,.profiler-result thead,.profiler-queries thead,.profiler-result tfoot,.profiler-queries tfoot,.profiler-result tr,.profiler-queries tr,.profiler-result th,.profiler-queries th,.profiler-result td,.profiler-queries td{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline;background-color:transparent;overflow:visible;max-height:none;}
|
|
2
|
+
.profiler-result table,.profiler-queries table{border-collapse:collapse;border-spacing:0;}
|
|
3
|
+
.profiler-result a,.profiler-queries a,.profiler-result a:hover,.profiler-queries a:hover{cursor:pointer;color:#0077cc;}
|
|
4
|
+
.profiler-result a,.profiler-queries a{text-decoration:none;}.profiler-result a:hover,.profiler-queries a:hover{text-decoration:underline;}
|
|
5
|
+
.profiler-result{font-family:Helvetica,Arial,sans-serif;}.profiler-result .profiler-toggle-duration-with-children{float:right;}
|
|
6
|
+
.profiler-result table.profiler-client-timings{margin-top:10px;}
|
|
7
|
+
.profiler-result .profiler-label{color:#555555;overflow:hidden;text-overflow:ellipsis;}
|
|
8
|
+
.profiler-result .profiler-unit{color:#aaaaaa;}
|
|
9
|
+
.profiler-result .profiler-trivial{display:none;}.profiler-result .profiler-trivial td,.profiler-result .profiler-trivial td *{color:#aaaaaa !important;}
|
|
10
|
+
.profiler-result pre,.profiler-result code,.profiler-result .profiler-number,.profiler-result .profiler-unit{font-family:Consolas,monospace,serif;}
|
|
11
|
+
.profiler-result .profiler-number{color:#111111;}
|
|
12
|
+
.profiler-result .profiler-info{text-align:right;}.profiler-result .profiler-info .profiler-name{float:left;}
|
|
13
|
+
.profiler-result .profiler-info .profiler-server-time{white-space:nowrap;}
|
|
14
|
+
.profiler-result .profiler-timings th{background-color:#fff;color:#aaaaaa;text-align:right;}
|
|
15
|
+
.profiler-result .profiler-timings th,.profiler-result .profiler-timings td{white-space:nowrap;}
|
|
16
|
+
.profiler-result .profiler-timings .profiler-duration-with-children{display:none;}
|
|
17
|
+
.profiler-result .profiler-timings .profiler-duration{font-family:Consolas,monospace,serif;color:#111111;text-align:right;}
|
|
18
|
+
.profiler-result .profiler-timings .profiler-indent{letter-spacing:4px;}
|
|
19
|
+
.profiler-result .profiler-timings .profiler-queries-show .profiler-number,.profiler-result .profiler-timings .profiler-queries-show .profiler-unit{color:#0077cc;}
|
|
20
|
+
.profiler-result .profiler-timings .profiler-queries-duration{padding-left:6px;}
|
|
21
|
+
.profiler-result .profiler-timings .profiler-percent-in-sql{white-space:nowrap;text-align:right;}
|
|
22
|
+
.profiler-result .profiler-timings tfoot td{padding-top:10px;text-align:right;}.profiler-result .profiler-timings tfoot td a{font-size:95%;display:inline-block;margin-left:12px;}.profiler-result .profiler-timings tfoot td a:first-child{float:left;margin-left:0px;}
|
|
23
|
+
.profiler-result .profiler-queries{font-family:Helvetica,Arial,sans-serif;}.profiler-result .profiler-queries .profiler-stack-trace{margin-bottom:15px;}
|
|
24
|
+
.profiler-result .profiler-queries pre{font-family:Consolas,monospace,serif;white-space:pre-wrap;}
|
|
25
|
+
.profiler-result .profiler-queries th{background-color:#fff;border-bottom:1px solid #555;font-weight:bold;padding:15px;white-space:nowrap;}
|
|
26
|
+
.profiler-result .profiler-queries td{padding:15px;text-align:left;background-color:#fff;}.profiler-result .profiler-queries td:last-child{padding-right:25px;}
|
|
27
|
+
.profiler-result .profiler-queries .profiler-odd td{background-color:#e5e5e5;}
|
|
28
|
+
.profiler-result .profiler-queries .profiler-since-start,.profiler-result .profiler-queries .profiler-duration{text-align:right;}
|
|
29
|
+
.profiler-result .profiler-queries .profiler-info div{text-align:right;margin-bottom:5px;}
|
|
30
|
+
.profiler-result .profiler-queries .profiler-gap-info,.profiler-result .profiler-queries .profiler-gap-info td{background-color:#ccc;}
|
|
31
|
+
.profiler-result .profiler-queries .profiler-gap-info .profiler-unit{color:#777;}
|
|
32
|
+
.profiler-result .profiler-queries .profiler-gap-info .profiler-info{text-align:right;}
|
|
33
|
+
.profiler-result .profiler-queries .profiler-gap-info.profiler-trivial-gaps{display:none;}
|
|
34
|
+
.profiler-result .profiler-queries .profiler-trivial-gap-container{text-align:center;}
|
|
35
|
+
.profiler-result .profiler-queries .str{color:#800000;}
|
|
36
|
+
.profiler-result .profiler-queries .kwd{color:#00008b;}
|
|
37
|
+
.profiler-result .profiler-queries .com{color:#808080;}
|
|
38
|
+
.profiler-result .profiler-queries .typ{color:#2b91af;}
|
|
39
|
+
.profiler-result .profiler-queries .lit{color:#800000;}
|
|
40
|
+
.profiler-result .profiler-queries .pun{color:#000000;}
|
|
41
|
+
.profiler-result .profiler-queries .pln{color:#000000;}
|
|
42
|
+
.profiler-result .profiler-queries .tag{color:#800000;}
|
|
43
|
+
.profiler-result .profiler-queries .atn{color:#ff0000;}
|
|
44
|
+
.profiler-result .profiler-queries .atv{color:#0000ff;}
|
|
45
|
+
.profiler-result .profiler-queries .dec{color:#800080;}
|
|
46
|
+
.profiler-result .profiler-warning,.profiler-result .profiler-warning *,.profiler-result .profiler-warning .profiler-queries-show,.profiler-result .profiler-warning .profiler-queries-show .profiler-unit{color:#f00;}.profiler-result .profiler-warning:hover,.profiler-result .profiler-warning *:hover,.profiler-result .profiler-warning .profiler-queries-show:hover,.profiler-result .profiler-warning .profiler-queries-show .profiler-unit:hover{color:#f00;}
|
|
47
|
+
.profiler-result .profiler-nuclear{color:#f00;font-weight:bold;padding-right:2px;}.profiler-result .profiler-nuclear:hover{color:#f00;}
|
|
48
|
+
.profiler-results{z-index:2147483643;position:fixed;top:0px;}.profiler-results.profiler-left{left:0px;}.profiler-results.profiler-left.profiler-no-controls .profiler-result:last-child .profiler-button,.profiler-results.profiler-left .profiler-controls{-webkit-border-bottom-right-radius:10px;-moz-border-radius-bottomright:10px;border-bottom-right-radius:10px;}
|
|
49
|
+
.profiler-results.profiler-left .profiler-button,.profiler-results.profiler-left .profiler-controls{border-right:1px solid #888888;}
|
|
50
|
+
.profiler-results.profiler-right{right:0px;}.profiler-results.profiler-right.profiler-no-controls .profiler-result:last-child .profiler-button,.profiler-results.profiler-right .profiler-controls{-webkit-border-bottom-left-radius:10px;-moz-border-radius-bottomleft:10px;border-bottom-left-radius:10px;}
|
|
51
|
+
.profiler-results.profiler-right .profiler-button,.profiler-results.profiler-right .profiler-controls{border-left:1px solid #888888;}
|
|
52
|
+
.profiler-results .profiler-button,.profiler-results .profiler-controls{display:none;z-index:2147483640;border-bottom:1px solid #888888;background-color:#fff;padding:4px 7px;text-align:right;cursor:pointer;}.profiler-results .profiler-button.profiler-button-active,.profiler-results .profiler-controls.profiler-button-active{background-color:maroon;}.profiler-results .profiler-button.profiler-button-active .profiler-number,.profiler-results .profiler-controls.profiler-button-active .profiler-number,.profiler-results .profiler-button.profiler-button-active .profiler-nuclear,.profiler-results .profiler-controls.profiler-button-active .profiler-nuclear{color:#fff;font-weight:bold;}
|
|
53
|
+
.profiler-results .profiler-button.profiler-button-active .profiler-unit,.profiler-results .profiler-controls.profiler-button-active .profiler-unit{color:#fff;font-weight:normal;}
|
|
54
|
+
.profiler-results .profiler-controls{display:block;font-size:12px;font-family:Consolas,monospace,serif;cursor:default;text-align:center;}.profiler-results .profiler-controls span{border-right:1px solid #aaaaaa;padding-right:5px;margin-right:5px;cursor:pointer;}
|
|
55
|
+
.profiler-results .profiler-controls span:last-child{border-right:none;}
|
|
56
|
+
.profiler-results .profiler-popup{display:none;z-index:2147483641;position:absolute;background-color:#fff;border:1px solid #aaa;padding:5px 10px;text-align:left;line-height:18px;overflow:auto;-moz-box-shadow:0px 1px 15px #555555;-webkit-box-shadow:0px 1px 15px #555555;box-shadow:0px 1px 15px #555555;}.profiler-results .profiler-popup .profiler-info{margin-bottom:3px;padding-bottom:2px;border-bottom:1px solid #ddd;}.profiler-results .profiler-popup .profiler-info .profiler-name{font-size:110%;font-weight:bold;}.profiler-results .profiler-popup .profiler-info .profiler-name .profiler-overall-duration{display:none;}
|
|
57
|
+
.profiler-results .profiler-popup .profiler-info .profiler-server-time{font-size:95%;}
|
|
58
|
+
.profiler-results .profiler-popup .profiler-timings th,.profiler-results .profiler-popup .profiler-timings td{padding-left:6px;padding-right:6px;}
|
|
59
|
+
.profiler-results .profiler-popup .profiler-timings th{font-size:95%;padding-bottom:3px;}
|
|
60
|
+
.profiler-results .profiler-popup .profiler-timings .profiler-label{max-width:275px;}
|
|
61
|
+
.profiler-results .profiler-queries{display:none;z-index:2147483643;position:absolute;overflow-y:auto;overflow-x:auto;background-color:#fff;}.profiler-results .profiler-queries th{font-size:17px;}
|
|
62
|
+
.profiler-results.profiler-min .profiler-result{display:none;}
|
|
63
|
+
.profiler-results.profiler-min .profiler-controls span{display:none;}
|
|
64
|
+
.profiler-results.profiler-min .profiler-controls .profiler-min-max{border-right:none;padding:0px;margin:0px;}
|
|
65
|
+
.profiler-queries-bg{z-index:2147483642;display:none;background:#000;opacity:0.7;position:absolute;top:0px;left:0px;min-width:100%;}
|
|
66
|
+
.profiler-result-full .profiler-result{width:950px;margin:30px auto;}.profiler-result-full .profiler-result .profiler-button{display:none;}
|
|
67
|
+
.profiler-result-full .profiler-result .profiler-popup .profiler-info{font-size:25px;border-bottom:1px solid #aaaaaa;padding-bottom:3px;margin-bottom:25px;}.profiler-result-full .profiler-result .profiler-popup .profiler-info .profiler-overall-duration{padding-right:20px;font-size:80%;color:#888;}
|
|
68
|
+
.profiler-result-full .profiler-result .profiler-popup .profiler-timings td,.profiler-result-full .profiler-result .profiler-popup .profiler-timings th{padding-left:8px;padding-right:8px;}
|
|
69
|
+
.profiler-result-full .profiler-result .profiler-popup .profiler-timings th{padding-bottom:7px;}
|
|
70
|
+
.profiler-result-full .profiler-result .profiler-popup .profiler-timings td{font-size:14px;padding-bottom:4px;}.profiler-result-full .profiler-result .profiler-popup .profiler-timings td:first-child{padding-left:10px;}
|
|
71
|
+
.profiler-result-full .profiler-result .profiler-popup .profiler-timings .profiler-label{max-width:550px;}
|
|
72
|
+
.profiler-result-full .profiler-result .profiler-queries{margin:25px 0;}.profiler-result-full .profiler-result .profiler-queries table{width:100%;}
|
|
73
|
+
.profiler-result-full .profiler-result .profiler-queries th{font-size:16px;color:#555;line-height:20px;}
|
|
74
|
+
.profiler-result-full .profiler-result .profiler-queries td{padding:15px 10px;text-align:left;}
|
|
75
|
+
.profiler-result-full .profiler-result .profiler-queries .profiler-info div{text-align:right;margin-bottom:5px;}
|
data/lib/html/includes.js
CHANGED
|
@@ -5,7 +5,8 @@ var MiniProfiler = (function ($) {
|
|
|
5
5
|
container,
|
|
6
6
|
controls,
|
|
7
7
|
fetchedIds = [],
|
|
8
|
-
fetchingIds = []
|
|
8
|
+
fetchingIds = [], // so we never pull down a profiler twice
|
|
9
|
+
ajaxStartTime
|
|
9
10
|
;
|
|
10
11
|
|
|
11
12
|
var hasLocalStorage = function () {
|
|
@@ -73,15 +74,15 @@ var MiniProfiler = (function ($) {
|
|
|
73
74
|
clientPerformance = null;
|
|
74
75
|
clientProbes = null;
|
|
75
76
|
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
clientProbes =
|
|
80
|
-
for (j = 0; j < clientProbes.length; j++) {
|
|
81
|
-
clientProbes[j].d = clientProbes[j].d.getTime();
|
|
82
|
-
}
|
|
83
|
-
mPt.t = [];
|
|
77
|
+
if (window.mPt) {
|
|
78
|
+
clientProbes = mPt.results();
|
|
79
|
+
for (j = 0; j < clientProbes.length; j++) {
|
|
80
|
+
clientProbes[j].d = clientProbes[j].d.getTime();
|
|
84
81
|
}
|
|
82
|
+
mPt.flush();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (id == options.currentId) {
|
|
85
86
|
|
|
86
87
|
clientPerformance = getClientPerformance();
|
|
87
88
|
|
|
@@ -100,7 +101,22 @@ var MiniProfiler = (function ($) {
|
|
|
100
101
|
copy.navigation.redirectCount = clientPerformance.navigation.redirectCount;
|
|
101
102
|
}
|
|
102
103
|
clientPerformance = copy;
|
|
104
|
+
|
|
105
|
+
// hack to add chrome timings
|
|
106
|
+
if (window.chrome && window.chrome.loadTimes) {
|
|
107
|
+
var chromeTimes = window.chrome.loadTimes();
|
|
108
|
+
if (chromeTimes.firstPaintTime) {
|
|
109
|
+
clientPerformance.timing["First Paint Time"] = Math.round(chromeTimes.firstPaintTime * 1000);
|
|
110
|
+
}
|
|
111
|
+
if (chromeTimes.firstPaintTime) {
|
|
112
|
+
clientPerformance.timing["First Paint After Load Time"] = Math.round(chromeTimes.firstPaintAfterLoadTime * 1000);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
}
|
|
103
116
|
}
|
|
117
|
+
} else if (ajaxStartTime != null && clientProbes && clientProbes.length > 0) {
|
|
118
|
+
clientPerformance = { timing: { navigationStart: ajaxStartTime.getTime() } };
|
|
119
|
+
ajaxStartTime = null;
|
|
104
120
|
}
|
|
105
121
|
|
|
106
122
|
if ($.inArray(id, fetchedIds) < 0 && $.inArray(id, fetchingIds) < 0) {
|
|
@@ -437,6 +453,9 @@ var MiniProfiler = (function ($) {
|
|
|
437
453
|
jQuery(document).ajaxComplete(jQueryAjaxComplete);
|
|
438
454
|
}
|
|
439
455
|
|
|
456
|
+
if (jQuery(document).ajaxStart)
|
|
457
|
+
jQuery(document).ajaxStart(function () { ajaxStartTime = new Date(); });
|
|
458
|
+
|
|
440
459
|
// fetch results after ASP Ajax calls
|
|
441
460
|
if (typeof (Sys) != 'undefined' && typeof (Sys.WebForms) != 'undefined' && typeof (Sys.WebForms.PageRequestManager) != 'undefined') {
|
|
442
461
|
// Get the instance of PageRequestManager.
|
|
@@ -475,6 +494,18 @@ var MiniProfiler = (function ($) {
|
|
|
475
494
|
})();
|
|
476
495
|
}
|
|
477
496
|
|
|
497
|
+
// also fetch results after ExtJS requests, in case it is being used
|
|
498
|
+
if (typeof (Ext) != 'undefined' && typeof (Ext.Ajax) != 'undefined' && typeof (Ext.Ajax.on) != 'undefined') {
|
|
499
|
+
// Ext.Ajax is a singleton, so we just have to attach to its 'requestcomplete' event
|
|
500
|
+
Ext.Ajax.on('requestcomplete', function(e, xhr, settings) {
|
|
501
|
+
var stringIds = xhr.getResponseHeader('X-MiniProfiler-Ids');
|
|
502
|
+
if (stringIds) {
|
|
503
|
+
var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
|
|
504
|
+
fetchResults(ids);
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
|
|
478
509
|
// some elements want to be hidden on certain doc events
|
|
479
510
|
bindDocumentEvents();
|
|
480
511
|
};
|
|
@@ -581,7 +612,7 @@ var MiniProfiler = (function ($) {
|
|
|
581
612
|
|
|
582
613
|
for (var i = 0; i < clientTimings.Timings.length; i++) {
|
|
583
614
|
t = clientTimings.Timings[i];
|
|
584
|
-
var trivial = t.Name != "Dom Complete" && t.Name != "Response";
|
|
615
|
+
var trivial = t.Name != "Dom Complete" && t.Name != "Response" && t.Name != "First Paint Time";
|
|
585
616
|
trivial = t.Duration < 2 ? trivial : false;
|
|
586
617
|
list.push(
|
|
587
618
|
{
|
|
@@ -799,4 +830,4 @@ PR_TAG:"tag",PR_TYPE:S}})()
|
|
|
799
830
|
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\r \xA0]+/,null,"\t\n\r \u00a0"],["str",/^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/,null,"\"'"]],[["com",/^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],["kwd",/^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i,
|
|
800
831
|
null],["lit",/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],["pln",/^[a-z_][\w-]*/i],["pun",/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/]]),["sql"])
|
|
801
832
|
|
|
802
|
-
;
|
|
833
|
+
;
|
data/lib/html/includes.less
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
.box-shadow(@dx, @dy, @radius, @color) {
|
|
2
2
|
-moz-box-shadow: @dx @dy @radius @color;
|
|
3
3
|
-webkit-box-shadow: @dx @dy @radius @color;
|
|
4
4
|
box-shadow: @dx @dy @radius @color;
|
|
@@ -359,7 +359,7 @@
|
|
|
359
359
|
z-index:@zindex + 3;
|
|
360
360
|
position:absolute;
|
|
361
361
|
overflow-y:auto;
|
|
362
|
-
overflow-x:
|
|
362
|
+
overflow-x:auto;
|
|
363
363
|
background-color:#fff;
|
|
364
364
|
|
|
365
365
|
th {
|
data/lib/html/includes.tmpl
CHANGED
|
@@ -138,7 +138,7 @@
|
|
|
138
138
|
</td>
|
|
139
139
|
|
|
140
140
|
{{if HasSqlTimings}}
|
|
141
|
-
<td class="profiler-duration {{if HasDuplicateSqlTimings}}profiler-warning{{/if}}" title="{{if HasDuplicateSqlTimings}}duplicate queries detected - {{/if}}${ExecutedReaders} reader, ${ExecutedScalars} scalar, ${ExecutedNonQueries} non-query statements executed">
|
|
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}}">
|
|
142
142
|
<a class="profiler-queries-show">
|
|
143
143
|
{{if HasDuplicateSqlTimings}}<span class="profiler-nuclear">!</span>{{/if}}
|
|
144
144
|
${SqlTimings.length} <span class="profiler-unit">sql</span>
|
|
@@ -192,4 +192,4 @@
|
|
|
192
192
|
</td>
|
|
193
193
|
</tr>
|
|
194
194
|
|
|
195
|
-
</script>
|
|
195
|
+
</script>
|
data/lib/html/profile_handler.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
<script type="text/javascript">
|
|
1
|
+
<script type="text/javascript">
|
|
2
2
|
(function(){{
|
|
3
|
-
var init = function() {{
|
|
3
|
+
var init = function() {{
|
|
4
4
|
var load = function(s,f){{
|
|
5
5
|
var sc = document.createElement('script');
|
|
6
6
|
sc.async = 'async';
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
}};
|
|
15
15
|
|
|
16
16
|
document.getElementsByTagName('head')[0].appendChild(sc);
|
|
17
|
-
}};
|
|
18
|
-
|
|
17
|
+
}};
|
|
18
|
+
|
|
19
19
|
var initMp = function(){{
|
|
20
20
|
load('{path}includes.js?v={version}',function(){{
|
|
21
21
|
MiniProfiler.init({{
|
|
@@ -32,18 +32,18 @@
|
|
|
32
32
|
}});
|
|
33
33
|
}});
|
|
34
34
|
}};
|
|
35
|
-
if ({useExistingjQuery}) {{
|
|
35
|
+
if ({useExistingjQuery} && typeof(jQuery) === 'function') {{
|
|
36
36
|
jQueryMP = jQuery;
|
|
37
37
|
initMp();
|
|
38
38
|
}} else {{
|
|
39
39
|
load('{path}jquery.1.7.1.js?v={version}', initMp);
|
|
40
40
|
}}
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
}};
|
|
43
43
|
|
|
44
|
-
var w = 0;
|
|
44
|
+
var w = 0;
|
|
45
45
|
var f = false;
|
|
46
|
-
var deferInit = function(){{
|
|
46
|
+
var deferInit = function(){{
|
|
47
47
|
if (f) return;
|
|
48
48
|
if (window.performance && window.performance.timing && window.performance.timing.loadEventEnd == 0 && w < 10000){{
|
|
49
49
|
setTimeout(deferInit, 100);
|
|
@@ -59,4 +59,4 @@
|
|
|
59
59
|
var o = window.onload;
|
|
60
60
|
window.onload = function(){{if(o)o; deferInit()}};
|
|
61
61
|
}})();
|
|
62
|
-
</script>
|
|
62
|
+
</script>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Rack
|
|
2
|
+
class MiniProfiler
|
|
3
|
+
class ClientSettings
|
|
4
|
+
|
|
5
|
+
COOKIE_NAME = "__profilin"
|
|
6
|
+
|
|
7
|
+
BACKTRACE_DEFAULT = nil
|
|
8
|
+
BACKTRACE_FULL = 1
|
|
9
|
+
BACKTRACE_NONE = 2
|
|
10
|
+
|
|
11
|
+
attr_accessor :disable_profiling
|
|
12
|
+
attr_accessor :backtrace_level
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def initialize(env)
|
|
16
|
+
request = ::Rack::Request.new(env)
|
|
17
|
+
@cookie = request.cookies[COOKIE_NAME]
|
|
18
|
+
if @cookie
|
|
19
|
+
@cookie.split(",").map{|pair| pair.split("=")}.each do |k,v|
|
|
20
|
+
@orig_disable_profiling = @disable_profiling = (v=='t') if k == "dp"
|
|
21
|
+
@backtrace_level = v.to_i if k == "bt"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
@backtrace_level = nil if !@backtrace_level.nil? && (@backtrace_level == 0 || @backtrace_level > BACKTRACE_NONE)
|
|
26
|
+
@orig_backtrace_level = @backtrace_level
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def write!(headers)
|
|
31
|
+
if @orig_disable_profiling != @disable_profiling || @orig_backtrace_level != @backtrace_level || @cookie.nil?
|
|
32
|
+
settings = {"p" => "t" }
|
|
33
|
+
settings["dp"] = "t" if @disable_profiling
|
|
34
|
+
settings["bt"] = @backtrace_level if @backtrace_level
|
|
35
|
+
settings_string = settings.map{|k,v| "#{k}=#{v}"}.join(",")
|
|
36
|
+
Rack::Utils.set_cookie_header!(headers, COOKIE_NAME, :value => settings_string, :path => '/')
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def discard_cookie!(headers)
|
|
41
|
+
Rack::Utils.delete_cookie_header!(headers, COOKIE_NAME, :path => '/')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def has_cookie?
|
|
45
|
+
!@cookie.nil?
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def disable_profiling?
|
|
49
|
+
@disable_profiling
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def backtrace_full?
|
|
53
|
+
@backtrace_level == BACKTRACE_FULL
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def backtrace_default?
|
|
57
|
+
@backtrace_level == BACKTRACE_DEFAULT
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def backtrace_none?
|
|
61
|
+
@backtrace_level == BACKTRACE_NONE
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -6,11 +6,24 @@ module Rack
|
|
|
6
6
|
# This class holds the client timings
|
|
7
7
|
class ClientTimerStruct < TimerStruct
|
|
8
8
|
|
|
9
|
+
def self.init_instrumentation
|
|
10
|
+
"<script type=\"text/javascript\">mPt=function(){var t=[];return{t:t,probe:function(n){t.push({d:new Date(),n:n})}}}()</script>"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.instrument(name,orig)
|
|
14
|
+
probe = "<script>mPt.probe('#{name}')</script>"
|
|
15
|
+
wrapped = probe
|
|
16
|
+
wrapped << orig
|
|
17
|
+
wrapped << probe
|
|
18
|
+
wrapped
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
|
|
9
22
|
def initialize(env={})
|
|
10
23
|
super
|
|
11
24
|
end
|
|
12
25
|
|
|
13
|
-
def init_from_form_data(env, page_struct)
|
|
26
|
+
def self.init_from_form_data(env, page_struct)
|
|
14
27
|
timings = []
|
|
15
28
|
clientTimes, clientPerf, baseTime = nil
|
|
16
29
|
form = env['rack.request.form_hash']
|
|
@@ -21,6 +34,26 @@ module Rack
|
|
|
21
34
|
baseTime = clientTimes['navigationStart'].to_i if clientTimes
|
|
22
35
|
return unless clientTimes && baseTime
|
|
23
36
|
|
|
37
|
+
probes = form['clientProbes']
|
|
38
|
+
translated = {}
|
|
39
|
+
if probes && probes != "null"
|
|
40
|
+
probes.each do |id, val|
|
|
41
|
+
name = val["n"]
|
|
42
|
+
translated[name] ||= {}
|
|
43
|
+
if translated[name][:start]
|
|
44
|
+
translated[name][:finish] = val["d"]
|
|
45
|
+
else
|
|
46
|
+
translated[name][:start] = val["d"]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
translated.each do |name, data|
|
|
52
|
+
h = {"Name" => name, "Start" => data[:start].to_i - baseTime}
|
|
53
|
+
h["Duration"] = data[:finish].to_i - data[:start].to_i if data[:finish]
|
|
54
|
+
timings.push(h)
|
|
55
|
+
end
|
|
56
|
+
|
|
24
57
|
clientTimes.keys.find_all{|k| k =~ /Start$/ }.each do |k|
|
|
25
58
|
start = clientTimes[k].to_i - baseTime
|
|
26
59
|
finish = clientTimes[k.sub(/Start$/, "End")].to_i - baseTime
|
|
@@ -34,8 +67,10 @@ module Rack
|
|
|
34
67
|
timings.push("Name" => k, "Start" => clientTimes[k].to_i - baseTime, "Duration" => -1)
|
|
35
68
|
end
|
|
36
69
|
|
|
37
|
-
|
|
38
|
-
|
|
70
|
+
rval = self.new
|
|
71
|
+
rval['RedirectCount'] = env['rack.request.form_hash']['clientPerformance']['navigation']['redirectCount']
|
|
72
|
+
rval['Timings'] = timings
|
|
73
|
+
rval
|
|
39
74
|
end
|
|
40
75
|
end
|
|
41
76
|
|