rack-mini-profiler 0.10.1 → 0.10.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -16
- data/README.md +86 -7
- data/lib/html/includes.js +8 -6
- data/lib/html/profile_handler.js +1 -1
- data/lib/html/share.html +4 -4
- data/lib/mini_profiler/asset_version.rb +1 -1
- data/lib/mini_profiler/config.rb +3 -2
- data/lib/mini_profiler/profiler.rb +39 -17
- data/lib/mini_profiler/storage/file_store.rb +1 -1
- data/lib/mini_profiler/timer_struct/base.rb +3 -0
- data/lib/mini_profiler/timer_struct/page.rb +10 -3
- data/lib/mini_profiler/version.rb +1 -1
- data/lib/mini_profiler_rails/railtie.rb +11 -4
- data/lib/patches/db/activerecord.rb +1 -1
- data/lib/patches/db/mysql2.rb +0 -2
- data/lib/patches/db/oracle_enhanced.rb +0 -2
- data/lib/patches/db/pg.rb +0 -2
- data/lib/patches/sql_patches.rb +40 -24
- data/lib/rack-mini-profiler.rb +1 -1
- data/rack-mini-profiler.gemspec +0 -2
- metadata +3 -31
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b5ecd2f33ab275645797ab70ae9ba6cfe498ca87
|
|
4
|
+
data.tar.gz: eacfe92f9cad96c73505efff1b319531ad327426
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0b7dbc766bb2e93d055a6710b661cc26d49a3ea3ed8bf3dc78604cfbcded5e08b75a22fd05623a38f0af05dccb3103f5d53aabda4eea69690df17292cf3a4012
|
|
7
|
+
data.tar.gz: 1d84e3daf3b7a27bbd22b563c8ff2b70ccdf6de6d39a9707357e4229886ff901b7496230cfc3707702064a66caa3cc5123f5492c78c649bf8b288a03262151f5
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 0.10.1 2017-02-08
|
|
4
|
+
|
|
5
|
+
- [FIX] improve turbolinks support
|
|
6
|
+
- [FEATURE] make location of mini_profiler injection customizable
|
|
7
|
+
|
|
3
8
|
## 0.10.1 2016-05-18
|
|
4
9
|
|
|
5
10
|
- [FEATURE] push forward the security checks so no work is ever done if a valid production
|
|
@@ -84,31 +89,31 @@
|
|
|
84
89
|
- [REMOVED] Ripped out flamegraph so it can be isolated into a gem
|
|
85
90
|
- [REMOVED] Ripped out pp=sample it just was never really used
|
|
86
91
|
|
|
87
|
-
## 1.30 - 2013-08-30
|
|
92
|
+
## 0.1.30 - 2013-08-30
|
|
88
93
|
- [ADDED] Rack::MiniProfiler.counter_method(klass,name) for injecting counters
|
|
89
94
|
- [FIXED] Counters were not shifting the table correctly
|
|
90
95
|
|
|
91
|
-
## 1.29 - 2013-08-20
|
|
96
|
+
## 0.1.29 - 2013-08-20
|
|
92
97
|
- [ADDED] Implemented exception tracing using TracePoint see pp=trace-exceptions
|
|
93
98
|
- [FIXED] SOLR patching had an incorrect monkey patch
|
|
94
99
|
|
|
95
|
-
## 1.28 -
|
|
100
|
+
## 0.1.28 - 2013-07-30
|
|
96
101
|
- [FIXED] Diagnostics in abstract storage was raising not implemented killing
|
|
97
102
|
?pp=env and others
|
|
98
103
|
- [FIXED] SOLR xml unescaped by mistake
|
|
99
104
|
|
|
100
|
-
## 1.27 - 2013-06-26
|
|
105
|
+
## 0.1.27 - 2013-06-26
|
|
101
106
|
- [ADDED] Rack::MiniProfiler.config.backtrace_threshold_ms
|
|
102
107
|
- [ADDED] jQuery 2.0 support
|
|
103
108
|
- [FIXED] Disabled global ajax handlers on MP requests @JP
|
|
104
109
|
|
|
105
|
-
## 1.26 - 2013-04-11
|
|
110
|
+
## 0.1.26 - 2013-04-11
|
|
106
111
|
- [IMPROVED] Allow Rack::MiniProfilerRails.initialize!(Rails.application), for post config intialization
|
|
107
112
|
|
|
108
|
-
## 1.25 - 2013-04-08
|
|
113
|
+
## 0.1.25 - 2013-04-08
|
|
109
114
|
- [FIXED] Missed flamegraph.html from build
|
|
110
115
|
|
|
111
|
-
## 1.24 - 2013-04-08
|
|
116
|
+
## 0.1.24 - 2013-04-08
|
|
112
117
|
- [ADDED] Flame Graph Support see: http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-miniprofiler
|
|
113
118
|
- [ADDED] New toggle_shortcut and start_hidden options
|
|
114
119
|
- [ADDED] Mongoid support
|
|
@@ -124,36 +129,36 @@
|
|
|
124
129
|
- [FIXED] HTML5 implicit <body> tags
|
|
125
130
|
- [FIXED] pp=enable
|
|
126
131
|
|
|
127
|
-
## 1.22 - 2012-09-20
|
|
132
|
+
## 0.1.22 - 2012-09-20
|
|
128
133
|
- [FIXED] Permission issue in the gem
|
|
129
134
|
|
|
130
|
-
##
|
|
135
|
+
## 2012-09-17
|
|
131
136
|
- [IMPROVED] Allow rack-mini-profiler to be sourced from github
|
|
132
137
|
- [IMPROVED] Extracted the pp=profile-gc-time out, the object space profiler needs to disable gc
|
|
133
138
|
|
|
134
|
-
## 1.21 - 2012-09-17
|
|
139
|
+
## 0.1.21 - 2012-09-17
|
|
135
140
|
- [ADDED] New MemchacedStore
|
|
136
141
|
- [ADDED] Rails 4 support
|
|
137
142
|
|
|
138
143
|
## 2012-09-12 (Sam Saffron)
|
|
139
144
|
- [ADDED] pp=profile-gc: allows you to profile the GC in Ruby 1.9.3
|
|
140
145
|
|
|
141
|
-
## 1.19 - 2012-09-10 (Sam Saffron)
|
|
146
|
+
## 0.1.19 - 2012-09-10 (Sam Saffron)
|
|
142
147
|
- [FIXED] Compatibility issue with Ruby 1.8.7
|
|
143
148
|
|
|
144
|
-
## 1.17 - 2012-09-09 (Sam Saffron)
|
|
149
|
+
## 0.1.17 - 2012-09-09 (Sam Saffron)
|
|
145
150
|
- [FIXED] pp=sample was bust unless stacktrace was installed
|
|
146
151
|
|
|
147
|
-
## 1.16 - 2012-09-05 (Sam Saffron)
|
|
152
|
+
## 0.1.16 - 2012-09-05 (Sam Saffron)
|
|
148
153
|
- [IMPROVED] Implemented stacktrace properly
|
|
149
154
|
- [FIXED] Long standing problem specs (issue with memory store)
|
|
150
155
|
- [FIXED] Issue where profiler would be dumped when you got a 404 in production (and any time rails is bypassed)
|
|
151
156
|
|
|
152
|
-
## 1.15.pre - 2012-09-04 (Sam Saffron)
|
|
157
|
+
## 0.1.15.pre - 2012-09-04 (Sam Saffron)
|
|
153
158
|
- [FIXED] Annoying bug where client settings were not sticking
|
|
154
159
|
- [FIXED] Long standing issue with Rack::ConditionalGet stopping MiniProfiler from working properly
|
|
155
160
|
|
|
156
|
-
## 1.13.pre - 2012-09-03 (Sam Saffron)
|
|
161
|
+
## 0.1.13.pre - 2012-09-03 (Sam Saffron)
|
|
157
162
|
- [ADDED] Setting: config.backtrace_ignores = [] - an array of regexes that match on caller lines that get ignored
|
|
158
163
|
- [ADDED] Setting: config.backtrace_includes = [] - an array of regexes that get included in the trace by default
|
|
159
164
|
- [ADDED] pp=normal-backtrace to clear the "sticky" state
|
|
@@ -162,7 +167,7 @@
|
|
|
162
167
|
- [IMPROVED] Changed "pp=sample" to work with "caller" no need for stack trace gem
|
|
163
168
|
- [FIXED] pg gem prepared statements were not being logged correctly
|
|
164
169
|
|
|
165
|
-
## 1.12.pre - 2012-08-20 (Sam Saffron)
|
|
170
|
+
## 0.1.12.pre - 2012-08-20 (Sam Saffron)
|
|
166
171
|
- [IMPROVED] Cap X-MiniProfiler-Ids at 10, otherwise the header can get killed
|
|
167
172
|
|
|
168
173
|
## 2012-08-10 (Sam Saffron)
|
data/README.md
CHANGED
|
@@ -6,7 +6,9 @@ Middleware that displays speed badge for every html page. Designed to work both
|
|
|
6
6
|
|
|
7
7
|
#### Features
|
|
8
8
|
|
|
9
|
-
*
|
|
9
|
+
* Database profiling - Currently supports Mysql2, Postgres, Oracle (oracle_enhanced ~> 1.5.0) and Mongoid3 (with fallback support to ActiveRecord)
|
|
10
|
+
* Call-stack profiling - Flame graphs showing time spent by gem
|
|
11
|
+
* Memory profiling - Per-request memory usage, GC stats, and global allocation metrics
|
|
10
12
|
|
|
11
13
|
#### Learn more
|
|
12
14
|
|
|
@@ -36,14 +38,24 @@ gem 'rack-mini-profiler'
|
|
|
36
38
|
|
|
37
39
|
NOTE: Be sure to require rack_mini_profiler below the `pg` and `mysql` gems in your Gemfile. rack_mini_profiler will identify these gems if they are loaded to insert instrumentation. If included too early no SQL will show up.
|
|
38
40
|
|
|
41
|
+
You can also include optional libraries to enable additional features.
|
|
42
|
+
```ruby
|
|
43
|
+
# For memory profiling (requires Ruby MRI 2.1+)
|
|
44
|
+
gem 'memory_profiler'
|
|
45
|
+
|
|
46
|
+
# For call-stack profiling flamegraphs (requires Ruby MRI 2.0.0+)
|
|
47
|
+
gem 'flamegraph'
|
|
48
|
+
gem 'stackprof' # For Ruby MRI 2.1+
|
|
49
|
+
gem 'fast_stack' # For Ruby MRI 2.0
|
|
50
|
+
```
|
|
51
|
+
|
|
39
52
|
#### Rails
|
|
40
53
|
|
|
41
|
-
All you have to do is include the Gem and you're good to go in development. See notes below for use in production.
|
|
54
|
+
All you have to do is to include the Gem and you're good to go in development. See notes below for use in production.
|
|
42
55
|
|
|
43
56
|
#### Rails and manual initialization
|
|
44
57
|
|
|
45
|
-
In case you need to make sure rack_mini_profiler initialized after all other gems
|
|
46
|
-
Or you want to execute some code before rack_mini_profiler required.
|
|
58
|
+
In case you need to make sure rack_mini_profiler initialized is after all other gems, or you want to execute some code before rack_mini_profiler required:
|
|
47
59
|
|
|
48
60
|
```ruby
|
|
49
61
|
gem 'rack-mini-profiler', require: false
|
|
@@ -88,6 +100,40 @@ class MyApp < Sinatra::Base
|
|
|
88
100
|
end
|
|
89
101
|
```
|
|
90
102
|
|
|
103
|
+
#### Hanami
|
|
104
|
+
For working with hanami, you need to use rack integration. Also, you need to add `Hanami::View::Rendering::Partial#render` method for profile:
|
|
105
|
+
|
|
106
|
+
```ruby
|
|
107
|
+
# config.ru
|
|
108
|
+
require 'rack-mini-profiler'
|
|
109
|
+
Rack::MiniProfiler.profile_method(Hanami::View::Rendering::Partial, :render) { "Render partial #{@options[:partial]}" }
|
|
110
|
+
|
|
111
|
+
use Rack::MiniProfiler
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### Patching ActiveRecord
|
|
115
|
+
|
|
116
|
+
A typical web application spends a lot of time querying the database. rack_mini_profiler will detect the ORM that is available
|
|
117
|
+
and apply patches to properly collect query statistics.
|
|
118
|
+
|
|
119
|
+
To make this work, declare the orm's gem before declaring `rack-mini-profiler` in the `Gemfile`:
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
gem 'pg'
|
|
123
|
+
gem 'mongoid'
|
|
124
|
+
gem 'rack-mini-profiler'
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
If you wish to override this behavior, the environment variable `RACK_MINI_PROFILER_PATCH` is available.
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
export RACK_MINI_PROFILER_PATCH="pg,mongoid"
|
|
132
|
+
# or
|
|
133
|
+
export RACK_MINI_PROFILER_PATCH="false"
|
|
134
|
+
# initializers/rack_profiler.rb: SqlPatches.patch %w(mongo)
|
|
135
|
+
```
|
|
136
|
+
|
|
91
137
|
### Flamegraphs
|
|
92
138
|
|
|
93
139
|
To generate [flamegraphs](http://samsaffron.com/archive/2013/03/19/flame-graphs-in-ruby-miniprofiler):
|
|
@@ -95,8 +141,30 @@ To generate [flamegraphs](http://samsaffron.com/archive/2013/03/19/flame-graphs-
|
|
|
95
141
|
* add the [**flamegraph**](https://github.com/SamSaffron/flamegraph) gem to your Gemfile
|
|
96
142
|
* visit a page in your app with `?pp=flamegraph`
|
|
97
143
|
|
|
98
|
-
Flamegraph generation is supported in MRI 2.0
|
|
144
|
+
Flamegraph generation is supported in Ruby MRI 2.0+
|
|
145
|
+
|
|
146
|
+
### Memory Profiling
|
|
147
|
+
|
|
148
|
+
Memory allocations can be measured (using the [memory_profiler](https://github.com/SamSaffron/memory_profiler) gem)
|
|
149
|
+
which will show allocations broken down by gem, file location, and class and will also highlight `String` allocations.
|
|
150
|
+
(Requires Ruby MRI 2.1.0+)
|
|
151
|
+
|
|
152
|
+
Add `?pp=profile-memory` to the URL of any request while Rack::MiniProfiler is enabled to generate the report.
|
|
153
|
+
|
|
154
|
+
Additional query parameters can be used to filter the results.
|
|
155
|
+
|
|
156
|
+
* `memory_profiler_allow_files` - filename pattern to include (default is all files)
|
|
157
|
+
* `memory_profiler_ignore_files` - filename pattern to exclude (default is no exclusions)
|
|
158
|
+
* `memory_profiler_top` - number of results per section (defaults to 50)
|
|
159
|
+
|
|
160
|
+
The allow/ignore patterns will be treated as regular expressions.
|
|
99
161
|
|
|
162
|
+
Example: `?pp=profile-memory&memory_profiler_allow_files=active_record|app`
|
|
163
|
+
|
|
164
|
+
There are two additional `pp` options that can be used to analyze memory which do not require the `memory_profiler` gem
|
|
165
|
+
|
|
166
|
+
* Use `?pp=profile-gc` to report on Garbage Collection statistics (requires Ruby MRI 1.9.3+)
|
|
167
|
+
* Use `?pp=analyze-memory` to report on ObjectSpace statistics (requires Ruby 2.0.0+)
|
|
100
168
|
|
|
101
169
|
## Access control in non-development environments
|
|
102
170
|
|
|
@@ -153,7 +221,7 @@ end
|
|
|
153
221
|
|
|
154
222
|
`MemoryStore` stores results in a processes heap - something that does not work well in a multi process environment.
|
|
155
223
|
`FileStore` stores results in the file system - something that may not work well in a multi machine environment.
|
|
156
|
-
`RedisStore`/`MemcacheStore` work in multi process and multi machine environments (`RedisStore` only saves results for up to 24 hours so it won't continue to fill up Redis).
|
|
224
|
+
`RedisStore`/`MemcacheStore` work in multi process and multi machine environments (`RedisStore` only saves results for up to 24 hours so it won't continue to fill up Redis). You will need to add `gem redis`/`gem dalli` respectively to your `Gemfile` to use these stores.
|
|
157
225
|
|
|
158
226
|
Additionally you may implement an `AbstractStore` for your own provider.
|
|
159
227
|
|
|
@@ -184,6 +252,16 @@ Rails.application.config.to_prepare do
|
|
|
184
252
|
end
|
|
185
253
|
```
|
|
186
254
|
|
|
255
|
+
### Profiling arbitrary block of code
|
|
256
|
+
|
|
257
|
+
It is also possible to profile any arbitrary block of code by passing a block to `Rack::MiniProfiler.step(name, opts=nil)`.
|
|
258
|
+
|
|
259
|
+
```ruby
|
|
260
|
+
Rack::MiniProfiler.step('Adding two elements') do
|
|
261
|
+
result = 1 + 2
|
|
262
|
+
end
|
|
263
|
+
```
|
|
264
|
+
|
|
187
265
|
### Using in SPA applications
|
|
188
266
|
|
|
189
267
|
Single page applications built using Ember, Angular or other frameworks need some special care, as routes often change without a full page load.
|
|
@@ -234,6 +312,7 @@ disable_env_dump|`false`|`true` disables `?pp=env`, which prevents sending ENV v
|
|
|
234
312
|
base_url_path|`'/mini-profiler-resources/'`|Path for assets; added as a prefix when naming assets and sought when responding to requests.
|
|
235
313
|
collapse_results|`true`|If multiple timing results exist in a single page, collapse them till clicked.
|
|
236
314
|
max_traces_to_show|20|Maximum number of mini profiler timing blocks to show on one page
|
|
315
|
+
html_container|`body`|The HTML container (as a jQuery selector) to inject the mini_profiler UI into
|
|
237
316
|
|
|
238
317
|
### Custom middleware ordering (required if using `Rack::Deflate` with Rails)
|
|
239
318
|
|
|
@@ -281,7 +360,7 @@ c.pre_authorize_cb = lambda { |env|
|
|
|
281
360
|
Rails.env.development? || Rails.env.production?
|
|
282
361
|
}
|
|
283
362
|
tmp = Rails.root.to_s + "/tmp/miniprofiler"
|
|
284
|
-
FileUtils.mkdir_p(tmp) unless File.
|
|
363
|
+
FileUtils.mkdir_p(tmp) unless File.exist?(tmp)
|
|
285
364
|
c.storage_options = {:path => tmp}
|
|
286
365
|
c.storage = ::Rack::MiniProfiler::FileStore
|
|
287
366
|
config.middleware.use(::Rack::MiniProfiler)
|
data/lib/html/includes.js
CHANGED
|
@@ -64,7 +64,7 @@ var MiniProfiler = (function () {
|
|
|
64
64
|
$('body').append(data);
|
|
65
65
|
success();
|
|
66
66
|
}
|
|
67
|
-
});
|
|
67
|
+
}, "text");
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
|
|
@@ -404,7 +404,7 @@ var MiniProfiler = (function () {
|
|
|
404
404
|
});
|
|
405
405
|
|
|
406
406
|
if (typeof Turbolinks !== 'undefined' && Turbolinks.supported) {
|
|
407
|
-
$(document).bind('page:change.mini-profiler', function() {
|
|
407
|
+
$(document).bind('page:change.mini-profiler turbolinks:load.mini-profiler', function() {
|
|
408
408
|
unbindDocumentEvents();
|
|
409
409
|
});
|
|
410
410
|
}
|
|
@@ -467,8 +467,8 @@ var MiniProfiler = (function () {
|
|
|
467
467
|
|
|
468
468
|
if (options.authorized) {
|
|
469
469
|
// all fetched profilings will go in here
|
|
470
|
-
container = $('<div class="profiler-results"/>').appendTo(
|
|
471
|
-
|
|
470
|
+
container = $('<div class="profiler-results"/>').appendTo(options.htmlContainer);
|
|
471
|
+
|
|
472
472
|
// MiniProfiler.RenderIncludes() sets which corner to render in - default is upper left
|
|
473
473
|
container.addClass("profiler-" + options.renderPosition);
|
|
474
474
|
|
|
@@ -634,6 +634,7 @@ var MiniProfiler = (function () {
|
|
|
634
634
|
var controls = script.getAttribute('data-controls') === 'true';
|
|
635
635
|
var authorized = script.getAttribute('data-authorized') === 'true';
|
|
636
636
|
var startHidden = script.getAttribute('data-start-hidden') === 'true';
|
|
637
|
+
var htmlContainer = script.getAttribute('data-html-container');
|
|
637
638
|
|
|
638
639
|
return {
|
|
639
640
|
ids: ids,
|
|
@@ -648,7 +649,8 @@ var MiniProfiler = (function () {
|
|
|
648
649
|
authorized: authorized,
|
|
649
650
|
toggleShortcut: toggleShortcut,
|
|
650
651
|
startHidden: startHidden,
|
|
651
|
-
collapseResults: collapseResults
|
|
652
|
+
collapseResults: collapseResults,
|
|
653
|
+
htmlContainer: htmlContainer
|
|
652
654
|
};
|
|
653
655
|
})();
|
|
654
656
|
|
|
@@ -731,7 +733,7 @@ var MiniProfiler = (function () {
|
|
|
731
733
|
}
|
|
732
734
|
|
|
733
735
|
|
|
734
|
-
if (major === 2 || (major === 1 && minor >= 7)) {
|
|
736
|
+
if (major === 3 || major === 2 || (major === 1 && minor >= 7)) {
|
|
735
737
|
MiniProfiler.jQuery = $ = jQuery;
|
|
736
738
|
$(deferInit);
|
|
737
739
|
} else {
|
data/lib/html/profile_handler.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
<script async type="text/javascript" id="mini-profiler" src="{path}includes.js?v={version}" data-version="{version}" data-path="{path}" data-current-id="{currentId}" data-ids="{ids}" data-position="{position}" data-trivial="{showTrivial}" data-children="{showChildren}" data-max-traces="{maxTracesToShow}" data-controls="{showControls}" data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}" data-start-hidden="{startHidden}" data-collapse-results="{collapseResults}"></script>
|
|
1
|
+
<script async type="text/javascript" id="mini-profiler" src="{path}includes.js?v={version}" data-version="{version}" data-path="{path}" data-current-id="{currentId}" data-ids="{ids}" data-position="{position}" data-trivial="{showTrivial}" data-children="{showChildren}" data-max-traces="{maxTracesToShow}" data-controls="{showControls}" data-authorized="{authorized}" data-toggle-shortcut="{toggleShortcut}" data-start-hidden="{startHidden}" data-collapse-results="{collapseResults}" data-html-container="{htmlContainer}"></script>
|
data/lib/html/share.html
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<html>
|
|
2
2
|
<head>
|
|
3
|
-
<title
|
|
4
|
-
<script type='text/javascript' src='
|
|
5
|
-
<script type='text/javascript'> var profiler =
|
|
6
|
-
|
|
3
|
+
<title><%= name %> (<%= duration %> ms) - Profiling Results</title>
|
|
4
|
+
<script type='text/javascript' src='<%= path %>jquery.1.7.1.js?v=<%= version %>'></script>
|
|
5
|
+
<script type='text/javascript'> var profiler = <%= json %>; </script>
|
|
6
|
+
<%= includes %>
|
|
7
7
|
</head>
|
|
8
8
|
<body>
|
|
9
9
|
<div class='profiler-result-full'></div>
|
data/lib/mini_profiler/config.rb
CHANGED
|
@@ -18,12 +18,12 @@ module Rack
|
|
|
18
18
|
:flamegraph_sample_rate, :logger, :pre_authorize_cb, :skip_paths,
|
|
19
19
|
:skip_schema_queries, :storage, :storage_failure, :storage_instance,
|
|
20
20
|
:storage_options, :user_provider
|
|
21
|
-
attr_accessor :skip_sql_param_names, :max_sql_param_length
|
|
21
|
+
attr_accessor :skip_sql_param_names, :suppress_encoding, :max_sql_param_length
|
|
22
22
|
|
|
23
23
|
# ui accessors
|
|
24
24
|
attr_accessor :collapse_results, :max_traces_to_show, :position,
|
|
25
25
|
:show_children, :show_controls, :show_trivial, :start_hidden,
|
|
26
|
-
:toggle_shortcut
|
|
26
|
+
:toggle_shortcut, :html_container
|
|
27
27
|
|
|
28
28
|
# Deprecated options
|
|
29
29
|
attr_accessor :use_existing_jquery
|
|
@@ -63,6 +63,7 @@ module Rack
|
|
|
63
63
|
@show_trivial = false
|
|
64
64
|
@start_hidden = false
|
|
65
65
|
@toggle_shortcut = 'Alt+P'
|
|
66
|
+
@html_container = 'body'
|
|
66
67
|
|
|
67
68
|
self
|
|
68
69
|
}
|
|
@@ -22,7 +22,7 @@ module Rack
|
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
def share_template
|
|
25
|
-
@share_template ||= ::File.read(::File.expand_path("../html/share.html", ::File.dirname(__FILE__)))
|
|
25
|
+
@share_template ||= ERB.new(::File.read(::File.expand_path("../html/share.html", ::File.dirname(__FILE__))))
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def current
|
|
@@ -109,14 +109,14 @@ module Rack
|
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
def generate_html(page_struct, env, result_json = page_struct.to_json)
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
112
|
+
path = "#{env['RACK_MINI_PROFILER_ORIGINAL_SCRIPT_NAME']}#{@config.base_url_path}"
|
|
113
|
+
version = MiniProfiler::ASSET_VERSION
|
|
114
|
+
json = result_json
|
|
115
|
+
includes = get_profile_script(env)
|
|
116
|
+
name = page_struct[:name]
|
|
117
|
+
duration = page_struct.duration_ms.round(1).to_s
|
|
118
|
+
|
|
119
|
+
MiniProfiler.share_template.result(binding)
|
|
120
120
|
end
|
|
121
121
|
|
|
122
122
|
def serve_html(env)
|
|
@@ -253,6 +253,10 @@ module Rack
|
|
|
253
253
|
env['HTTP_IF_NONE_MATCH'] = ''
|
|
254
254
|
end
|
|
255
255
|
|
|
256
|
+
orig_accept_encoding = env['HTTP_ACCEPT_ENCODING']
|
|
257
|
+
# Prevent response body from being compressed
|
|
258
|
+
env['HTTP_ACCEPT_ENCODING'] = 'identity' if config.suppress_encoding
|
|
259
|
+
|
|
256
260
|
if query_string =~ /pp=flamegraph/
|
|
257
261
|
unless defined?(Flamegraph) && Flamegraph.respond_to?(:generate)
|
|
258
262
|
|
|
@@ -279,6 +283,7 @@ module Rack
|
|
|
279
283
|
end
|
|
280
284
|
ensure
|
|
281
285
|
trace.disable if trace
|
|
286
|
+
env['HTTP_ACCEPT_ENCODING'] = orig_accept_encoding if config.suppress_encoding
|
|
282
287
|
end
|
|
283
288
|
|
|
284
289
|
skip_it = current.discard
|
|
@@ -292,6 +297,14 @@ module Rack
|
|
|
292
297
|
# we must do this here, otherwise current[:discard] is not being properly treated
|
|
293
298
|
if trace_exceptions
|
|
294
299
|
body.close if body.respond_to? :close
|
|
300
|
+
|
|
301
|
+
query_params = Rack::Utils.parse_nested_query(query_string)
|
|
302
|
+
trace_exceptions_filter = query_params['trace_exceptions_filter']
|
|
303
|
+
if trace_exceptions_filter
|
|
304
|
+
trace_exceptions_regex = Regexp.new(trace_exceptions_filter)
|
|
305
|
+
exceptions.reject! { |ex| ex.class.name =~ trace_exceptions_regex }
|
|
306
|
+
end
|
|
307
|
+
|
|
295
308
|
return client_settings.handle_cookie(dump_exceptions exceptions)
|
|
296
309
|
end
|
|
297
310
|
|
|
@@ -392,13 +405,21 @@ module Rack
|
|
|
392
405
|
end
|
|
393
406
|
|
|
394
407
|
def dump_exceptions(exceptions)
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
408
|
+
body = "Exceptions raised during request\n\n"
|
|
409
|
+
if exceptions.empty?
|
|
410
|
+
body << "No exceptions raised"
|
|
411
|
+
else
|
|
412
|
+
body << "Exceptions: (#{exceptions.size} total)\n"
|
|
413
|
+
exceptions.group_by(&:class).each do |klass, exceptions|
|
|
414
|
+
body << " #{klass.name} (#{exceptions.size})\n"
|
|
415
|
+
end
|
|
400
416
|
|
|
401
|
-
|
|
417
|
+
body << "\nBacktraces\n"
|
|
418
|
+
exceptions.each_with_index do |e, i|
|
|
419
|
+
body << "##{i+1}: #{e.class} - \"#{e.message}\"\n #{e.backtrace.join("\n ")}\n\n"
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
text_result(body)
|
|
402
423
|
end
|
|
403
424
|
|
|
404
425
|
def dump_env(env)
|
|
@@ -565,7 +586,7 @@ Append the following to your query string:
|
|
|
565
586
|
def get_profile_script(env)
|
|
566
587
|
path = if ENV["PASSENGER_BASE_URI"] then
|
|
567
588
|
# added because the SCRIPT_NAME workaround below then
|
|
568
|
-
# breaks running under a prefix as permitted by Passenger.
|
|
589
|
+
# breaks running under a prefix as permitted by Passenger.
|
|
569
590
|
"#{ENV['PASSENGER_BASE_URI']}#{@config.base_url_path}"
|
|
570
591
|
elsif env["action_controller.instance"]
|
|
571
592
|
# Rails engines break SCRIPT_NAME; the following appears to discard SCRIPT_NAME
|
|
@@ -586,7 +607,8 @@ Append the following to your query string:
|
|
|
586
607
|
:authorized => true,
|
|
587
608
|
:toggleShortcut => @config.toggle_shortcut,
|
|
588
609
|
:startHidden => @config.start_hidden,
|
|
589
|
-
:collapseResults => @config.collapse_results
|
|
610
|
+
:collapseResults => @config.collapse_results,
|
|
611
|
+
:htmlContainer => @config.html_container
|
|
590
612
|
}
|
|
591
613
|
|
|
592
614
|
if current && current.page_struct
|
|
@@ -44,7 +44,7 @@ module Rack
|
|
|
44
44
|
@path = args[:path]
|
|
45
45
|
@expires_in_seconds = args[:expires_in] || EXPIRES_IN_SECONDS
|
|
46
46
|
raise ArgumentError.new :path unless @path
|
|
47
|
-
FileUtils.mkdir_p(@path) unless ::File.
|
|
47
|
+
FileUtils.mkdir_p(@path) unless ::File.exist?(@path)
|
|
48
48
|
|
|
49
49
|
@timer_struct_cache = FileCache.new(@path, "mp_timers")
|
|
50
50
|
@timer_struct_lock = Mutex.new
|
|
@@ -57,12 +57,19 @@ module Rack
|
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def to_json(*a)
|
|
60
|
-
|
|
60
|
+
::JSON.generate(@attributes.merge(self.extra_json))
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def as_json(options = nil)
|
|
64
|
+
super(options).merge!(extra_json)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def extra_json
|
|
68
|
+
{
|
|
61
69
|
:started => '/Date(%d)/' % @attributes[:started],
|
|
62
70
|
:duration_milliseconds => @attributes[:root][:duration_milliseconds],
|
|
63
71
|
:custom_timing_names => @attributes[:custom_timing_stats].keys.sort
|
|
64
|
-
|
|
65
|
-
::JSON.generate(attribs, :max_nesting => 100)
|
|
72
|
+
}
|
|
66
73
|
end
|
|
67
74
|
end
|
|
68
75
|
end
|
|
@@ -28,10 +28,6 @@ module Rack::MiniProfilerRails
|
|
|
28
28
|
c.skip_paths << app.config.assets.prefix
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
-
if Rails.env.development?
|
|
32
|
-
c.skip_schema_queries = true
|
|
33
|
-
end
|
|
34
|
-
|
|
35
31
|
unless Rails.env.development? || Rails.env.test?
|
|
36
32
|
c.authorization_mode = :whitelist
|
|
37
33
|
end
|
|
@@ -88,6 +84,17 @@ module Rack::MiniProfilerRails
|
|
|
88
84
|
Rack::MiniProfilerRails.initialize!(app)
|
|
89
85
|
end
|
|
90
86
|
|
|
87
|
+
# Suppress compression when Rack::Deflater is lower in the middleware
|
|
88
|
+
# stack than Rack::MiniProfiler
|
|
89
|
+
config.after_initialize do |app|
|
|
90
|
+
middlewares = app.middleware.middlewares
|
|
91
|
+
if Rack::MiniProfiler.config.suppress_encoding.nil? &&
|
|
92
|
+
middlewares.include?(Rack::Deflater) &&
|
|
93
|
+
middlewares.index(Rack::Deflater) > middlewares.index(Rack::MiniProfiler)
|
|
94
|
+
Rack::MiniProfiler.config.suppress_encoding = true
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
91
98
|
# TODO: Implement something better here
|
|
92
99
|
# config.after_initialize do
|
|
93
100
|
#
|
data/lib/patches/db/mysql2.rb
CHANGED
data/lib/patches/db/pg.rb
CHANGED
data/lib/patches/sql_patches.rb
CHANGED
|
@@ -1,16 +1,4 @@
|
|
|
1
1
|
class SqlPatches
|
|
2
|
-
def self.unpatched?
|
|
3
|
-
!patched?
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
def self.patched?
|
|
7
|
-
@patched
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def self.patched=(val)
|
|
11
|
-
@patched = val
|
|
12
|
-
end
|
|
13
|
-
|
|
14
2
|
def self.correct_version?(required_version, klass)
|
|
15
3
|
Gem::Dependency.new('', required_version).match?('', klass::VERSION)
|
|
16
4
|
rescue NameError
|
|
@@ -32,17 +20,45 @@ class SqlPatches
|
|
|
32
20
|
def self.elapsed_time(start_time)
|
|
33
21
|
((Time.now - start_time).to_f * 1000).round(1)
|
|
34
22
|
end
|
|
23
|
+
|
|
24
|
+
def self.sql_patches
|
|
25
|
+
patches = []
|
|
26
|
+
|
|
27
|
+
patches << 'mysql2' if defined?(Mysql2::Client) && Mysql2::Client.class == Class
|
|
28
|
+
patches << 'pg' if defined?(PG::Result) && PG::Result.class == Class
|
|
29
|
+
patches << 'oracle_enhanced' if defined?(ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter) && ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class == Class &&
|
|
30
|
+
SqlPatches.correct_version?('~> 1.5.0', ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter)
|
|
31
|
+
# if the adapters were directly patched, don't patch again
|
|
32
|
+
return patches unless patches.empty?
|
|
33
|
+
patches << 'sequel' if defined?(Sequel::Database) && Sequel::Database.class == Class
|
|
34
|
+
patches << 'activerecord' if defined?(ActiveRecord) && ActiveRecord.class == Module
|
|
35
|
+
|
|
36
|
+
patches
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.other_patches
|
|
40
|
+
patches = []
|
|
41
|
+
patches << 'mongo' if defined?(Mongo::Server::Connection) && Mongo.class == Module
|
|
42
|
+
patches << 'moped' if defined?(Moped::Node) && Moped::Node.class == Class
|
|
43
|
+
patches << 'plucky' if defined?(Plucky::Query) && Plucky::Query.class == Class
|
|
44
|
+
patches << 'rsolr' if defined?(RSolr::Connection) && RSolr::Connection.class == Class && RSolr::VERSION[0] != "0"
|
|
45
|
+
patches << 'nobrainer' if defined?(NoBrainer) && NoBrainer.class == Module
|
|
46
|
+
patches << 'riak' if defined?(Riak) && Riak.class == Module
|
|
47
|
+
patches << 'neo4j' if defined?(Neo4j::Core) && Neo4j::Core::Query.class == Class
|
|
48
|
+
patches
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def self.all_patch_files
|
|
52
|
+
env_var = ENV["RACK_MINI_PROFILER_PATCH"]
|
|
53
|
+
return [] if env_var == "false"
|
|
54
|
+
env_var ? env_var.split(",").map(&:strip) : sql_patches + other_patches
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.patch(patch_files = all_patch_files)
|
|
58
|
+
patch_files.each do |patch_file|
|
|
59
|
+
require "patches/db/#{patch_file}"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
35
62
|
end
|
|
36
63
|
|
|
37
|
-
|
|
38
|
-
require 'patches/db/pg' if defined?(PG::Result) && PG::Result.class == Class
|
|
39
|
-
require 'patches/db/oracle_enhanced' if defined?(ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter) && ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class == Class && SqlPatches.correct_version?('~> 1.5.0', ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter)
|
|
40
|
-
require 'patches/db/mongo' if defined?(Mongo::Server::Connection) && Mongo.class == Module
|
|
41
|
-
require 'patches/db/moped' if defined?(Moped::Node) && Moped::Node.class == Class
|
|
42
|
-
require 'patches/db/plucky' if defined?(Plucky::Query) && Plucky::Query.class == Class
|
|
43
|
-
require 'patches/db/rsolr' if defined?(RSolr::Connection) && RSolr::Connection.class == Class && RSolr::VERSION[0] != "0"
|
|
44
|
-
require 'patches/db/sequel' if SqlPatches.unpatched? && defined?(Sequel::Database) && Sequel::Database.class == Class
|
|
45
|
-
require 'patches/db/activerecord' if SqlPatches.unpatched? && defined?(ActiveRecord) && ActiveRecord.class == Module
|
|
46
|
-
require 'patches/db/nobrainer' if defined?(NoBrainer) && NoBrainer.class == Module
|
|
47
|
-
require 'patches/db/riak' if defined?(Riak) && Riak.class == Module
|
|
48
|
-
require 'patches/db/neo4j' if defined?(Neo4j::Core) && Neo4j::Core::Query.class == Class
|
|
64
|
+
SqlPatches.patch
|
data/lib/rack-mini-profiler.rb
CHANGED
|
@@ -31,6 +31,6 @@ require 'mini_profiler/profiler'
|
|
|
31
31
|
require 'patches/sql_patches'
|
|
32
32
|
require 'patches/net_patches'
|
|
33
33
|
|
|
34
|
-
if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i >= 3
|
|
34
|
+
if defined?(::Rails) && defined?(::Rails::VERSION) && ::Rails::VERSION::MAJOR.to_i >= 3
|
|
35
35
|
require 'mini_profiler_rails/railtie'
|
|
36
36
|
end
|
data/rack-mini-profiler.gemspec
CHANGED
|
@@ -30,8 +30,6 @@ Gem::Specification.new do |s|
|
|
|
30
30
|
s.add_development_dependency 'therubyracer'
|
|
31
31
|
s.add_development_dependency 'less'
|
|
32
32
|
s.add_development_dependency 'flamegraph'
|
|
33
|
-
s.add_development_dependency 'guard'
|
|
34
|
-
s.add_development_dependency 'guard-rspec'
|
|
35
33
|
|
|
36
34
|
s.require_paths = ["lib"]
|
|
37
35
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack-mini-profiler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.10.
|
|
4
|
+
version: 0.10.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sam Saffron
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date:
|
|
13
|
+
date: 2017-02-08 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: rack
|
|
@@ -152,34 +152,6 @@ dependencies:
|
|
|
152
152
|
- - ">="
|
|
153
153
|
- !ruby/object:Gem::Version
|
|
154
154
|
version: '0'
|
|
155
|
-
- !ruby/object:Gem::Dependency
|
|
156
|
-
name: guard
|
|
157
|
-
requirement: !ruby/object:Gem::Requirement
|
|
158
|
-
requirements:
|
|
159
|
-
- - ">="
|
|
160
|
-
- !ruby/object:Gem::Version
|
|
161
|
-
version: '0'
|
|
162
|
-
type: :development
|
|
163
|
-
prerelease: false
|
|
164
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
165
|
-
requirements:
|
|
166
|
-
- - ">="
|
|
167
|
-
- !ruby/object:Gem::Version
|
|
168
|
-
version: '0'
|
|
169
|
-
- !ruby/object:Gem::Dependency
|
|
170
|
-
name: guard-rspec
|
|
171
|
-
requirement: !ruby/object:Gem::Requirement
|
|
172
|
-
requirements:
|
|
173
|
-
- - ">="
|
|
174
|
-
- !ruby/object:Gem::Version
|
|
175
|
-
version: '0'
|
|
176
|
-
type: :development
|
|
177
|
-
prerelease: false
|
|
178
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
179
|
-
requirements:
|
|
180
|
-
- - ">="
|
|
181
|
-
- !ruby/object:Gem::Version
|
|
182
|
-
version: '0'
|
|
183
155
|
description: Profiling toolkit for Rack applications with Rails integration. Client
|
|
184
156
|
Side profiling, DB profiling and Server profiling.
|
|
185
157
|
email: sam.saffron@gmail.com
|
|
@@ -258,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
258
230
|
version: '0'
|
|
259
231
|
requirements: []
|
|
260
232
|
rubyforge_project:
|
|
261
|
-
rubygems_version: 2.5.
|
|
233
|
+
rubygems_version: 2.5.2
|
|
262
234
|
signing_key:
|
|
263
235
|
specification_version: 4
|
|
264
236
|
summary: Profiles loading speed for rack applications.
|