rack-mini-profiler 0.10.1 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|