rack-mini-profiler 0.1.1 → 0.1.8
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 +32 -0
- data/README.md +40 -15
- data/lib/html/includes.css +75 -1
- data/lib/html/includes.js +26 -2
- data/lib/html/includes.less +1 -1
- data/lib/html/profile_handler.js +9 -9
- 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/page_timer_struct.rb +7 -3
- data/lib/mini_profiler/profiler.rb +251 -135
- data/lib/mini_profiler/profiling_methods.rb +73 -0
- data/lib/mini_profiler/request_timer_struct.rb +40 -9
- data/lib/mini_profiler/sql_timer_struct.rb +16 -5
- data/lib/mini_profiler/storage/file_store.rb +8 -7
- data/lib/mini_profiler/storage/memory_store.rb +0 -4
- data/lib/mini_profiler_rails/railtie.rb +62 -11
- data/lib/patches/sql_patches.rb +152 -39
- data/lib/rack-mini-profiler.rb +3 -3
- data/rack-mini-profiler.gemspec +4 -5
- metadata +9 -8
- data/CHANGELOG.md +0 -7
- data/lib/html/MiniProfilerHandler.cs +0 -419
- data/lib/mini_profiler/body_add_proxy.rb +0 -45
data/CHANGELOG
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
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
|
+
9-July-2012 - Sam
|
|
11
|
+
|
|
12
|
+
* Cleaned up mechanism for profiling in production, all you need to do now
|
|
13
|
+
is call Rack::MiniProfiler.authorize_request to get profiling working in
|
|
14
|
+
production
|
|
15
|
+
* Added option to display full backtraces pp=full-backtrace
|
|
16
|
+
* Cleaned up railties, got rid of the post authorize callback
|
|
17
|
+
* Version 0.1.3
|
|
18
|
+
|
|
19
|
+
12-July-2012 - Sam
|
|
20
|
+
|
|
21
|
+
* Fixed incorrect profiling steps (was not indenting or measuring start time right
|
|
22
|
+
* Implemented native PG and MySql2 interceptors, this gives way more accurate times
|
|
23
|
+
* Refactored context so its a proper class and not a hash
|
|
24
|
+
* Added some more client probing built in to rails
|
|
25
|
+
* More tests
|
|
26
|
+
|
|
27
|
+
18-July-2012 - Sam
|
|
28
|
+
|
|
29
|
+
* Added First Paint time for chrome
|
|
30
|
+
* Bug fix to ensure non Rails installs have mini profiler
|
|
31
|
+
* Version 0.1.7
|
|
32
|
+
|
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` 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,15 +80,18 @@ 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
|
|
|
66
88
|
## Available Options
|
|
67
89
|
|
|
68
|
-
*
|
|
90
|
+
* 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
91
|
* 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'
|
|
92
|
+
* 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.
|
|
93
|
+
|
|
94
|
+
## Special query strings
|
|
71
95
|
|
|
96
|
+
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.
|
|
72
97
|
|
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:hidden;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
|
@@ -100,6 +100,18 @@ var MiniProfiler = (function ($) {
|
|
|
100
100
|
copy.navigation.redirectCount = clientPerformance.navigation.redirectCount;
|
|
101
101
|
}
|
|
102
102
|
clientPerformance = copy;
|
|
103
|
+
|
|
104
|
+
// hack to add chrome timings
|
|
105
|
+
if (window.chrome && window.chrome.loadTimes) {
|
|
106
|
+
var chromeTimes = window.chrome.loadTimes();
|
|
107
|
+
if (chromeTimes.firstPaintTime) {
|
|
108
|
+
clientPerformance.timing["First Paint Time"] = Math.round(chromeTimes.firstPaintTime * 1000);
|
|
109
|
+
}
|
|
110
|
+
if (chromeTimes.firstPaintTime) {
|
|
111
|
+
clientPerformance.timing["First Paint After Load Time"] = Math.round(chromeTimes.firstPaintAfterLoadTime * 1000);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
}
|
|
103
115
|
}
|
|
104
116
|
}
|
|
105
117
|
|
|
@@ -475,6 +487,18 @@ var MiniProfiler = (function ($) {
|
|
|
475
487
|
})();
|
|
476
488
|
}
|
|
477
489
|
|
|
490
|
+
// also fetch results after ExtJS requests, in case it is being used
|
|
491
|
+
if (typeof (Ext) != 'undefined' && typeof (Ext.Ajax) != 'undefined' && typeof (Ext.Ajax.on) != 'undefined') {
|
|
492
|
+
// Ext.Ajax is a singleton, so we just have to attach to its 'requestcomplete' event
|
|
493
|
+
Ext.Ajax.on('requestcomplete', function(e, xhr, settings) {
|
|
494
|
+
var stringIds = xhr.getResponseHeader('X-MiniProfiler-Ids');
|
|
495
|
+
if (stringIds) {
|
|
496
|
+
var ids = typeof JSON != 'undefined' ? JSON.parse(stringIds) : eval(stringIds);
|
|
497
|
+
fetchResults(ids);
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
478
502
|
// some elements want to be hidden on certain doc events
|
|
479
503
|
bindDocumentEvents();
|
|
480
504
|
};
|
|
@@ -581,7 +605,7 @@ var MiniProfiler = (function ($) {
|
|
|
581
605
|
|
|
582
606
|
for (var i = 0; i < clientTimings.Timings.length; i++) {
|
|
583
607
|
t = clientTimings.Timings[i];
|
|
584
|
-
var trivial = t.Name != "Dom Complete" && t.Name != "Response";
|
|
608
|
+
var trivial = t.Name != "Dom Complete" && t.Name != "Response" && t.Name != "First Paint Time";
|
|
585
609
|
trivial = t.Duration < 2 ? trivial : false;
|
|
586
610
|
list.push(
|
|
587
611
|
{
|
|
@@ -799,4 +823,4 @@ PR_TAG:"tag",PR_TYPE:S}})()
|
|
|
799
823
|
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
824
|
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
825
|
|
|
802
|
-
;
|
|
826
|
+
;
|
data/lib/html/includes.less
CHANGED
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>
|
|
@@ -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
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Rack
|
|
2
|
+
class MiniProfiler
|
|
3
|
+
class Config
|
|
4
|
+
|
|
5
|
+
def self.attr_accessor(*vars)
|
|
6
|
+
@attributes ||= []
|
|
7
|
+
@attributes.concat vars
|
|
8
|
+
super(*vars)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.attributes
|
|
12
|
+
@attributes
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attr_accessor :auto_inject, :base_url_path, :pre_authorize_cb, :position,
|
|
16
|
+
:backtrace_remove, :backtrace_filter, :skip_schema_queries,
|
|
17
|
+
:storage, :user_provider, :storage_instance, :storage_options, :skip_paths, :authorization_mode, :use_existing_jquery
|
|
18
|
+
|
|
19
|
+
def self.default
|
|
20
|
+
new.instance_eval {
|
|
21
|
+
@auto_inject = true # automatically inject on every html page
|
|
22
|
+
@base_url_path = "/mini-profiler-resources/"
|
|
23
|
+
|
|
24
|
+
# called prior to rack chain, to ensure we are allowed to profile
|
|
25
|
+
@pre_authorize_cb = lambda {|env| true}
|
|
26
|
+
|
|
27
|
+
# called after rack chain, to ensure we are REALLY allowed to profile
|
|
28
|
+
@position = 'left' # Where it is displayed
|
|
29
|
+
@skip_schema_queries = false
|
|
30
|
+
@storage = MiniProfiler::MemoryStore
|
|
31
|
+
@user_provider = Proc.new{|env| Rack::Request.new(env).ip}
|
|
32
|
+
@authorization_mode = :allow_all
|
|
33
|
+
@use_existing_jquery = false
|
|
34
|
+
self
|
|
35
|
+
}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def merge!(config)
|
|
39
|
+
return unless config
|
|
40
|
+
if Hash === config
|
|
41
|
+
config.each{|k,v| instance_variable_set "@#{k}",v}
|
|
42
|
+
else
|
|
43
|
+
self.class.attributes.each{ |k|
|
|
44
|
+
v = config.send k
|
|
45
|
+
instance_variable_set "@#{k}", v if v
|
|
46
|
+
}
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -16,7 +16,7 @@ module Rack
|
|
|
16
16
|
"Level" => 0,
|
|
17
17
|
"User" => "unknown user",
|
|
18
18
|
"HasUserViewed" => false,
|
|
19
|
-
"ClientTimings" =>
|
|
19
|
+
"ClientTimings" => nil,
|
|
20
20
|
"DurationMilliseconds" => 0,
|
|
21
21
|
"HasTrivialTimings" => true,
|
|
22
22
|
"HasAllTrivialTimigs" => false,
|
|
@@ -35,15 +35,19 @@ module Rack
|
|
|
35
35
|
def duration_ms
|
|
36
36
|
@attributes['Root']['DurationMilliseconds']
|
|
37
37
|
end
|
|
38
|
+
|
|
39
|
+
def root
|
|
40
|
+
@attributes['Root']
|
|
41
|
+
end
|
|
38
42
|
|
|
39
43
|
def to_json(*a)
|
|
40
44
|
attribs = @attributes.merge(
|
|
41
45
|
"Started" => '/Date(%d)/' % @attributes['Started'],
|
|
42
46
|
"DurationMilliseconds" => @attributes['Root']['DurationMilliseconds']
|
|
43
47
|
)
|
|
44
|
-
::JSON.generate(attribs,
|
|
48
|
+
::JSON.generate(attribs, :max_nesting => 100)
|
|
45
49
|
end
|
|
46
50
|
end
|
|
47
51
|
|
|
48
52
|
end
|
|
49
|
-
end
|
|
53
|
+
end
|