rack-webprofiler 0.1.0.pre.alpha1

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.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +27 -0
  3. data/.gitignore +11 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +34 -0
  6. data/.rubocop_todo.yml +0 -0
  7. data/.travis.yml +23 -0
  8. data/CHANGELOG.md +39 -0
  9. data/CODE_OF_CONDUCT.md +74 -0
  10. data/Gemfile +15 -0
  11. data/LICENSE +21 -0
  12. data/README.md +94 -0
  13. data/Rakefile +17 -0
  14. data/bin/ci-prepare +16 -0
  15. data/bin/console +10 -0
  16. data/bin/setup +8 -0
  17. data/examples/README.md +56 -0
  18. data/examples/rack/config.ru +52 -0
  19. data/examples/sinatra/app.rb +37 -0
  20. data/examples/sinatra/config.ru +3 -0
  21. data/lib/rack/templates/404.erb +1 -0
  22. data/lib/rack/templates/assets/rwpt.css +9 -0
  23. data/lib/rack/templates/assets/rwpt.js +0 -0
  24. data/lib/rack/templates/async.erb +120 -0
  25. data/lib/rack/templates/panel/index.erb +29 -0
  26. data/lib/rack/templates/panel/layout.erb +17 -0
  27. data/lib/rack/templates/panel/show.erb +19 -0
  28. data/lib/rack/templates/profiler.erb +70 -0
  29. data/lib/rack/web_profiler/auto_configure/rails.rb +12 -0
  30. data/lib/rack/web_profiler/collector/debug_collector.rb +31 -0
  31. data/lib/rack/web_profiler/collector/erb_collector.rb +0 -0
  32. data/lib/rack/web_profiler/collector/performance_collector.rb +1 -0
  33. data/lib/rack/web_profiler/collector/rack/rack_collector.rb +23 -0
  34. data/lib/rack/web_profiler/collector/rack/request_collector.rb +33 -0
  35. data/lib/rack/web_profiler/collector/rails/active_record_collector.rb +25 -0
  36. data/lib/rack/web_profiler/collector/rails/logger_collector.rb +22 -0
  37. data/lib/rack/web_profiler/collector/rails/rails_collector.rb +25 -0
  38. data/lib/rack/web_profiler/collector/rails/request_collector.rb +50 -0
  39. data/lib/rack/web_profiler/collector/ruby_collector.rb +46 -0
  40. data/lib/rack/web_profiler/collector/sinatra/request_collector.rb +38 -0
  41. data/lib/rack/web_profiler/collector/sinatra/sinatra_collector.rb +25 -0
  42. data/lib/rack/web_profiler/collector/time_collector.rb +23 -0
  43. data/lib/rack/web_profiler/collector.rb +142 -0
  44. data/lib/rack/web_profiler/collectors.rb +88 -0
  45. data/lib/rack/web_profiler/config.rb +61 -0
  46. data/lib/rack/web_profiler/controller.rb +125 -0
  47. data/lib/rack/web_profiler/engine.rb +109 -0
  48. data/lib/rack/web_profiler/erb.rb +9 -0
  49. data/lib/rack/web_profiler/model/collection_record.rb +45 -0
  50. data/lib/rack/web_profiler/model.rb +35 -0
  51. data/lib/rack/web_profiler/request.rb +14 -0
  52. data/lib/rack/web_profiler/router.rb +71 -0
  53. data/lib/rack/web_profiler/version.rb +5 -0
  54. data/lib/rack/web_profiler.rb +70 -0
  55. data/lib/rack/webprofiler.rb +1 -0
  56. data/rack-webprofiler.gemspec +38 -0
  57. metadata +198 -0
@@ -0,0 +1,120 @@
1
+ <div id="rwpt<%= @token %>" class="rwpt-toolbar" style="display: none"></div>
2
+ <script>
3
+ /*<![CDATA[*/
4
+ APjs = (function() {
5
+ "use strict";
6
+ var noop = function() {},
7
+ profilerStorageKey = 'rack-webprofiler/',
8
+ request = function(url, onSuccess, onError, payload, options) {
9
+ var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
10
+ options = options || {};
11
+ options.maxTries = options.maxTries || 0;
12
+ xhr.open(options.method || 'GET', url, true);
13
+ xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
14
+ xhr.onreadystatechange = function(state) {
15
+ if (4 !== xhr.readyState) {
16
+ return null;
17
+ }
18
+ if (xhr.status == 404 && options.maxTries > 1) {
19
+ setTimeout(function() {
20
+ options.maxTries--;
21
+ request(url, onSuccess, onError, payload, options);
22
+ }, 500);
23
+ return null;
24
+ }
25
+ if (200 === xhr.status) {
26
+ (onSuccess || noop)(xhr);
27
+ } else {
28
+ (onError || noop)(xhr);
29
+ }
30
+ };
31
+ xhr.send(payload || '');
32
+ },
33
+ hasClass = function(el, klass) {
34
+ return el.className && el.className.match(new RegExp('\\b' + klass + '\\b'));
35
+ },
36
+ removeClass = function(el, klass) {
37
+ if (el.className) {
38
+ el.className = el.className.replace(new RegExp('\\b' + klass + '\\b'), ' ');
39
+ }
40
+ },
41
+ addClass = function(el, klass) {
42
+ if (!hasClass(el, klass)) {
43
+ el.className += " " + klass;
44
+ }
45
+ },
46
+ getPreference = function(name) {
47
+ if (!window.localStorage) {
48
+ return null;
49
+ }
50
+ return localStorage.getItem(profilerStorageKey + name);
51
+ },
52
+ setPreference = function(name, value) {
53
+ if (!window.localStorage) {
54
+ return null;
55
+ }
56
+ localStorage.setItem(profilerStorageKey + name, value);
57
+ };
58
+ return {
59
+ hasClass: hasClass,
60
+ removeClass: removeClass,
61
+ addClass: addClass,
62
+ getPreference: getPreference,
63
+ setPreference: setPreference,
64
+ request: request,
65
+ load: function(selector, url, onSuccess, onError, options) {
66
+ var el = document.getElementById(selector);
67
+ if (el && el.getAttribute('data-rwpturl') !== url) {
68
+ request(url, function(xhr) {
69
+ el.innerHTML = xhr.responseText;
70
+ el.setAttribute('data-rwpturl', url);
71
+ removeClass(el, 'loading');
72
+ (onSuccess || noop)(xhr, el);
73
+ }, function(xhr) {
74
+ (onError || noop)(xhr, el);
75
+ }, '', options);
76
+ }
77
+ return this;
78
+ },
79
+ toggle: function(selector, elOn, elOff) {
80
+ var i, style, tmp = elOn.style.display,
81
+ el = document.getElementById(selector);
82
+ elOn.style.display = elOff.style.display;
83
+ elOff.style.display = tmp;
84
+ if (el) {
85
+ el.style.display = 'none' === tmp ? 'none' : 'block';
86
+ }
87
+ return this;
88
+ }
89
+ }
90
+ })(); /*]]>*/
91
+ </script>
92
+ <script>
93
+ /*<![CDATA[*/
94
+ (function() {
95
+ APjs.load('rwpt<%= @token %>', '<%= @url %>', function(xhr, el) {
96
+ el.style.display = 'block';
97
+ return;
98
+
99
+ el.style.display = -1 !== xhr.responseText.indexOf('rwpt-toolbarreset') ? 'block' : 'none';
100
+ if (el.style.display == 'none') {
101
+ return;
102
+ }
103
+ if (APjs.getPreference('toolbar/displayState') == 'none') {
104
+ document.getElementById('rwptToolbarMainContent-<%= @token %>').style.display = 'none';
105
+ document.getElementById('rwptToolbarClearer-<%= @token %>').style.display = 'none';
106
+ document.getElementById('rwptMiniToolbar-<%= @token %>').style.display = 'block';
107
+ } else {
108
+ document.getElementById('rwptToolbarMainContent-<%= @token %>').style.display = 'block';
109
+ document.getElementById('rwptToolbarClearer-<%= @token %>').style.display = 'block';
110
+ document.getElementById('rwptMiniToolbar-<%= @token %>').style.display = 'none';
111
+ }
112
+ }, function(xhr) {
113
+ if (xhr.status !== 0) {
114
+ confirm('An error occurred while loading the web debug toolbar (' + xhr.status + ': ' + xhr.statusText + ').\\n\\nDo you want to open the profiler?') && (window.location = '<%= @url %>');
115
+ }
116
+ }, {
117
+ 'maxTries': 5
118
+ });
119
+ })(); /*]]>*/
120
+ </script>
@@ -0,0 +1,29 @@
1
+ # TODO list the 20 lastest requests
2
+
3
+ <table>
4
+ <thead>
5
+ <tr>
6
+ <th>token</th>
7
+ <th>method</th>
8
+ <th>status</th>
9
+ <th>url</th>
10
+ <th>ip</th>
11
+ <th>date</th>
12
+ </tr>
13
+ </thead>
14
+ <tbody>
15
+ <% @collections.each do |r| %>
16
+ <tr>
17
+ <td><a href="<%= WebProfiler::Router.url_for_profiler(r.token) %>"><%= r.token %></a></td>
18
+ <td><%= r.http_method %></td>
19
+ <td><%= r.http_status %></td>
20
+ <td><%= r.url %></td>
21
+ <td><%= r.ip %></td>
22
+ <td><span title="<%= r.created_at %>"><%= r.created_at.strftime('%Y-%m-%d %H:%M:%S') %></span></td>
23
+ </tr>
24
+ <% end %>
25
+ </tbody>
26
+ </table>
27
+
28
+
29
+ <a href="<%= WebProfiler::Router.url_for_clean_profiler %>">Cleanup database</a>
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Rack WebProfiler</title>
5
+ <style>
6
+ <%= partial 'assets/rwpt.css' %>
7
+ </style>
8
+ <script type="text/javascript">
9
+ <%= partial 'assets/rwpt.js' %>
10
+ </script>
11
+ </head>
12
+ <body>
13
+
14
+ <%= yield %>
15
+
16
+ </body>
17
+ </html>
@@ -0,0 +1,19 @@
1
+ <%= partial 'profiler.erb' %>
2
+
3
+ <% @collection.datas.each do |name, datas| %>
4
+ <div class="">
5
+ <h2><%= name %></h2>
6
+
7
+ <table>
8
+ <% datas[:datas].each do |k, v| %>
9
+ <tr>
10
+ <th><%= k %></th>
11
+ <td><%= v.inspect %></td>
12
+ </tr>
13
+ <% end %>
14
+ </table>
15
+ </div>
16
+ <% end %>
17
+
18
+
19
+ <a href="<%= WebProfiler::Router.url_for_profiler %>">All requests</a>
@@ -0,0 +1,70 @@
1
+ <style>
2
+ #rack-webprofiler {
3
+ position: fixed;
4
+ bottom: 0;
5
+ left: 0;
6
+ width: 100%;
7
+ height: 40px;
8
+
9
+ background-color: #1c1f33;
10
+ color: #f3fcf0;
11
+ font-family: "Helvetica Neue", Arial, sans-serif;
12
+ font-size: 14px;
13
+ }
14
+
15
+ #rack-webprofiler * {
16
+ margin: 0;
17
+ padding: 0;
18
+ }
19
+
20
+ #rack-webprofiler .rack-webprofiler_collectors {
21
+ height: 40px;
22
+ }
23
+
24
+ #rack-webprofiler .rack-webprofiler_collectors > .rack-webprofiler_collector {
25
+ float: left;
26
+ padding: 0 10px;
27
+ border: 1px solid #282f4c;
28
+ height: 38px;
29
+ line-height: 40px;
30
+ }
31
+
32
+ #rack-webprofiler .rack-webprofiler_collectors .rack-webprofiler_collector img {
33
+ width: 20px;
34
+ height: 20px;
35
+ position: relative;
36
+ top: 4px;
37
+ }
38
+ #rack-webprofiler .rack-webprofiler_collectors .rack-webprofiler_collector.error,
39
+ #rack-webprofiler .rack-webprofiler_collectors .rack-webprofiler_collector.success {
40
+ height: 35px;
41
+ border-bottom-style: solid;
42
+ border-bottom-width: 4px;
43
+ }
44
+ #rack-webprofiler .rack-webprofiler_collectors .rack-webprofiler_collector.error {
45
+ border-bottom-color: #ff2851;
46
+ }
47
+ #rack-webprofiler .rack-webprofiler_collectors .rack-webprofiler_collector.success {
48
+ border-bottom-color: #44db5e;
49
+ }
50
+ </style>
51
+ <%
52
+ datas = @collection.datas
53
+ token = @collection.token
54
+ %>
55
+ <div id="rack-webprofiler">
56
+ <div class="rack-webprofiler_collectors">
57
+
58
+ <% @collectors.each do |name, collector| %>
59
+ <div class="rack-webprofiler_collector rack-webprofiler_collectors_<%= name %> <%= datas[name.to_sym][:status] %>">
60
+ <% unless collector.icon.nil? %>
61
+ <img alt="" src="<%= collector.icon %>" />
62
+ <% end %>
63
+
64
+ <%= render_collector(collector.template, datas[name.to_sym][:datas]) %>
65
+ <%#= yield :tab %>
66
+ <a href="<%= WebProfiler::Router.url_for_profiler(token) %>">+</a>
67
+ </div>
68
+ <% end %>
69
+ </div>
70
+ </div>
@@ -0,0 +1,12 @@
1
+ module Rack
2
+ # AutoConfigure::Rails
3
+ class WebProfiler::AutoConfigure::Rails
4
+ class Engine < ::Rails::Engine # :nodoc:
5
+ initializer "rack-web_profiler.configure_middleware" do |app|
6
+ app.middleware.use Rack::WebProfiler do |c|
7
+ c.tmp_dir = File.expand_path(File.join(Rails.root, "tmp"), __FILE__)
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,31 @@
1
+ module Rack
2
+ class WebProfiler::Collector::DebugCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon nil
6
+
7
+ collector_name "debug"
8
+ position 1
9
+
10
+ collect do |request, response|
11
+ store :key, "value"
12
+ store :backtrace, "value"
13
+ end
14
+
15
+ template __FILE__, type: :DATA
16
+ end
17
+ end
18
+
19
+ # # @see also https://gist.github.com/ubermajestix/3644301
20
+ # module Object
21
+ # def inspect
22
+ # res = super
23
+ # # save the res on collector storage
24
+ # res
25
+ # end
26
+ # end
27
+
28
+ __END__
29
+ <% content_for :tab do %>
30
+ <%= data[:ruby_version] %>
31
+ <% end %>
File without changes
@@ -0,0 +1 @@
1
+ # See: https://github.com/noahd1/oink/blob/master/lib/oink/middleware.rb#L39
@@ -0,0 +1,23 @@
1
+ module Rack
2
+ class WebProfiler::Collector::Rack::RackCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon nil
6
+
7
+ collector_name "rack"
8
+ position 1
9
+
10
+ collect do |_request, _response|
11
+ store :rack_version, Rack.release
12
+ end
13
+
14
+ template __FILE__, type: :DATA
15
+
16
+ is_enabled? -> { !defined?(Rails) && !defined?(Sinatra) }
17
+ end
18
+ end
19
+
20
+ __END__
21
+ <%# content_for :tab do %>
22
+ <%= data[:rack_version] %>
23
+ <%# end %>
@@ -0,0 +1,33 @@
1
+ module Rack
2
+ class WebProfiler::Collector::Rack::RequestCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon nil
6
+
7
+ collector_name "rack_request"
8
+ position 2
9
+
10
+ collect do |request, response|
11
+ store :request_path, request.path
12
+ store :request_method, request.request_method
13
+ store :response_status, response.status
14
+
15
+ if response.successful?
16
+ status :success
17
+ elsif response.redirection?
18
+ status :warning
19
+ else
20
+ status :error
21
+ end
22
+ end
23
+
24
+ template __FILE__, type: :DATA
25
+
26
+ is_enabled? -> { !defined?(Rails) && !defined?(Sinatra) }
27
+ end
28
+ end
29
+
30
+ __END__
31
+ <%# content_for :tab do %>
32
+ <%= data[:response_status] %> | <%= data[:request_method] %> <%= data[:request_path] %>
33
+ <%# end %>
@@ -0,0 +1,25 @@
1
+ module Rack
2
+ class WebProfiler::Collector::Rails::ActiveRecordCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon nil
6
+
7
+ collector_name "rails_activerecord"
8
+ position 1
9
+
10
+ collect do |_request, _response|
11
+ store :sql_requests, []
12
+ end
13
+
14
+ template __FILE__, type: :DATA
15
+
16
+ is_enabled? -> { defined? ActiveRecord }
17
+ end
18
+ end
19
+
20
+ # See: https://github.com/noahd1/oink/blob/master/lib/oink/middleware.rb#L46
21
+
22
+ __END__
23
+ <%# content_for :tab do %>
24
+
25
+ <%# end %>
@@ -0,0 +1,22 @@
1
+ module Rack
2
+ class WebProfiler::Collector::Rails::LoggerCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon nil
6
+
7
+ collector_name "rails_logger"
8
+ position 1
9
+
10
+ collect do |_request, _response|
11
+ end
12
+
13
+ template __FILE__, type: :DATA
14
+
15
+ is_enabled? -> { defined? Rails }
16
+ end
17
+ end
18
+
19
+ __END__
20
+ <%# content_for :tab do %>
21
+
22
+ <%# end %>
@@ -0,0 +1,25 @@
1
+ module Rack
2
+ class WebProfiler::Collector::Rails::RailsCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon nil
6
+
7
+ collector_name "rails"
8
+ position 1
9
+
10
+ collect do |_request, _response|
11
+ store :rails_version, Rails.version
12
+ store :rails_env, Rails.env
13
+ store :rails_doc_url, "http://api.rubyonrails.org/v#{Rails.version}/"
14
+ end
15
+
16
+ template __FILE__, type: :DATA
17
+
18
+ is_enabled? -> { defined? Rails }
19
+ end
20
+ end
21
+
22
+ __END__
23
+ <%# content_for :tab do %>
24
+ <%= data[:rails_version] %> | <%= data[:rails_env] %>
25
+ <%# end %>
@@ -0,0 +1,50 @@
1
+ module Rack
2
+ class WebProfiler::Collector::Rails::RequestCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon nil
6
+
7
+ collector_name "rails_request"
8
+ position 1
9
+
10
+ collect do |request, response|
11
+ route, _matches, request_params = find_route(request)
12
+
13
+ store :request_path, request.path
14
+ store :request_method, request.request_method
15
+ store :request_params, request_params || {}
16
+ store :request_cookies, request.cookies
17
+ store :request_get, request.GET
18
+ store :request_post, request.POST
19
+ # store :rack_env, request.env.each { |k, v| v.to_s }
20
+ # puts request.env.map{ |k, v| k => v.to_s }
21
+ store :response_status, response.status
22
+ store :route_name, route.nil? ? nil : route.name
23
+
24
+ if response.successful?
25
+ status :success
26
+ elsif response.redirection?
27
+ status :warning
28
+ else
29
+ status :error
30
+ end
31
+ end
32
+
33
+ template __FILE__, type: :DATA
34
+
35
+ is_enabled? -> { defined? Rails }
36
+
37
+ class << self
38
+ def find_route(request)
39
+ Rails.application.routes.router.recognize(request) do |route, matches, params|
40
+ return [route, matches, params]
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ __END__
48
+ <%# content_for :tab do %>
49
+ <%= data[:response_status] %> | <%= data[:request_method] %> <%= data[:request_path] %>
50
+ <%# end %>
@@ -0,0 +1,46 @@
1
+ module Rack
2
+ class WebProfiler::Collector::RubyCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon <<-'ICON'
6
+ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB1ElEQVR4XqWTTWsTURSGn3tnpqJYbbKImjaV1IVEgwqpYKNuxK0tRCku/MK/oOBv8L904we4r+10Y0FdWEKsVrAZic2kxDZNwkyOlw51cDal9IXDGYZ5nvfexSgR4TBRxMHNIYMQBEBFozTRjoepb6ikgIUzyIV7T0mVbgGAV4f1ddAWvQ2Pthlt2bTbdX7Vv1D+HrF6Dy5UHpMqlqHzB/wGfK1Cf8dMhyMjaZRlEQQ9jg+fJpMt4OYRAO2Omea7T0gXr0O3A2EAtRoAiMAg3H2Xzo4TmudAQoZPZMmMXsSdQNRiFim/rcLWJqYCbAvm5sBxQCuA6OK2A+9eRVtp0EMsNeaxlQ2tl89InS1C0I8+rlWjrXUsMNBat4u2A7SBOoFHCE0FlBbG+FC4eYd0/goMAvA8aLYiQSQyB/TxfzewtMN24NPs/aC8ymUNLN/4yeTK+zf4a5/AGYLMKRD+a2/7LQOb5hieBD5rgH+S+df4qx/h6DEYOblnoLe9xSAMd5s3YniZZKLrIM0HMyLPX4hMV0Qqs9K4OiXVQk7ccwhQIhmSkpyRPDTw/UciM7Oycn5U3IkEvK9kHNmcvi31a5dkMX8gOJa4BlxKNB9Ysh986N/5L2oi0DPAz3KGAAAAAElFTkSuQmCC
7
+ ICON
8
+
9
+ collector_name "ruby"
10
+ position 0
11
+
12
+ collect do |_request, _response|
13
+ store :ruby_version, RUBY_VERSION
14
+ store :ruby_patchlevel, RUBY_PATCHLEVEL
15
+ store :ruby_release_date, RUBY_RELEASE_DATE
16
+ store :ruby_platform, RUBY_PLATFORM
17
+ store :ruby_revision, RUBY_REVISION
18
+ store :gems_list, gems_list
19
+ store :ruby_doc_url, "http://www.ruby-doc.org/core-#{RUBY_VERSION}/"
20
+ end
21
+
22
+ template __FILE__, type: :DATA
23
+
24
+ class << self
25
+ def gems_list
26
+ gems = []
27
+
28
+ Gem.loaded_specs.values.each do |g|
29
+ gems << {
30
+ name: g.name,
31
+ version: g.version.to_s,
32
+ homepage: g.homepage,
33
+ summary: g.summary,
34
+ }
35
+ end
36
+
37
+ gems
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ __END__
44
+ <%# content_for :tab do %>
45
+ <%= data[:ruby_version] %>
46
+ <%# end %>
@@ -0,0 +1,38 @@
1
+ module Rack
2
+ class WebProfiler::Collector::Sinatra::RequestCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon nil
6
+
7
+ collector_name "sinatra_request"
8
+ position 2
9
+
10
+ collect do |request, response|
11
+ store :request_path, request.path
12
+ store :request_method, request.request_method
13
+ store :request_cookies, request.cookies
14
+ store :request_get, request.GET
15
+ store :request_post, request.POST
16
+ # store :rack_env, request.env.each { |k, v| v.to_s }
17
+ # puts request.env.map{ |k, v| k => v.to_s }
18
+ store :response_status, response.status
19
+
20
+ if response.successful?
21
+ status :success
22
+ elsif response.redirection?
23
+ status :warning
24
+ else
25
+ status :error
26
+ end
27
+ end
28
+
29
+ template __FILE__, type: :DATA
30
+
31
+ is_enabled? -> { defined? Sinatra }
32
+ end
33
+ end
34
+
35
+ __END__
36
+ <%# content_for :tab do %>
37
+ <%= data[:response_status] %> | <%= data[:request_method] %> <%= data[:request_path] %>
38
+ <%# end %>
@@ -0,0 +1,25 @@
1
+ module Rack
2
+ class WebProfiler::Collector::Sinatra::SinatraCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon nil
6
+
7
+ collector_name "sinatra"
8
+ position 1
9
+
10
+ collect do |_request, _response|
11
+ store :sinatra_version, Sinatra::VERSION
12
+ store :sinatra_env, Sinatra::Base.environment
13
+ store :sinatra_doc_url, "http://www.sinatrarb.com/documentation.html"
14
+ end
15
+
16
+ template __FILE__, type: :DATA
17
+
18
+ is_enabled? -> { defined? Sinatra }
19
+ end
20
+ end
21
+
22
+ __END__
23
+ <%# content_for :tab do %>
24
+ <%= data[:sinatra_version] %> | <%= data[:sinatra_env] %>
25
+ <%# end %>
@@ -0,0 +1,23 @@
1
+ module Rack
2
+ class WebProfiler::Collector::TimeCollector
3
+ include Rack::WebProfiler::Collector::DSL
4
+
5
+ icon nil
6
+
7
+ collector_name "time"
8
+ position 3
9
+
10
+ collect do |request, _response|
11
+ store :runtime, request.runtime
12
+
13
+ status :warning if request.runtime >= 500
14
+ end
15
+
16
+ template __FILE__, type: :DATA
17
+ end
18
+ end
19
+
20
+ __END__
21
+ <%# content_for :tab do %>
22
+ <%= (data[:runtime] * 1000.0).round(2) %> ms
23
+ <%# end %>