tuttle 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -2
  3. data/README.md +1 -1
  4. data/app/assets/images/tuttle/favicon.ico +0 -0
  5. data/app/controllers/tuttle/application_controller.rb +2 -5
  6. data/app/controllers/tuttle/cancancan_controller.rb +5 -2
  7. data/app/controllers/tuttle/gems_controller.rb +19 -0
  8. data/app/controllers/tuttle/rails_controller.rb +6 -0
  9. data/app/controllers/tuttle/ruby_controller.rb +23 -0
  10. data/app/helpers/tuttle/application_helper.rb +5 -0
  11. data/app/views/layouts/tuttle/application.html.erb +24 -7
  12. data/app/views/tuttle/cancancan/_rule_table.html.erb +1 -1
  13. data/app/views/tuttle/cancancan/index.html.erb +1 -1
  14. data/app/views/tuttle/cancancan/rule_tester.html.erb +2 -2
  15. data/app/views/tuttle/gems/http_clients.html.erb +35 -0
  16. data/app/views/tuttle/gems/json.html.erb +31 -0
  17. data/app/views/tuttle/gems/other.html.erb +16 -0
  18. data/app/views/tuttle/rails/cache.html.erb +27 -1
  19. data/app/views/tuttle/rails/database.html.erb +21 -0
  20. data/app/views/tuttle/rails/index.html.erb +16 -6
  21. data/app/views/tuttle/rails/instrumentation.html.erb +1 -1
  22. data/app/views/tuttle/rails/models.html.erb +1 -1
  23. data/app/views/tuttle/ruby/miscellaneous.html.erb +12 -0
  24. data/app/views/tuttle/ruby/tuning.html.erb +117 -0
  25. data/config/routes.rb +8 -1
  26. data/lib/tuttle.rb +1 -1
  27. data/lib/tuttle/engine.rb +48 -7
  28. data/lib/tuttle/version.rb +1 -1
  29. metadata +12 -108
  30. data/app/assets/stylesheets/scaffold.css +0 -56
  31. data/test/controllers/tuttle/cancancan_controller_test.rb +0 -60
  32. data/test/controllers/tuttle/devise_controller_test.rb +0 -12
  33. data/test/controllers/tuttle/home_controller_test.rb +0 -13
  34. data/test/controllers/tuttle/rails_controller_test.rb +0 -71
  35. data/test/controllers/tuttle/ruby_controller_test.rb +0 -12
  36. data/test/dummy/Gemfile.lock +0 -142
  37. data/test/dummy/README.rdoc +0 -261
  38. data/test/dummy/Rakefile +0 -7
  39. data/test/dummy/app/assets/javascripts/application.js +0 -15
  40. data/test/dummy/app/assets/stylesheets/application.css +0 -13
  41. data/test/dummy/app/controllers/application_controller.rb +0 -3
  42. data/test/dummy/app/helpers/application_helper.rb +0 -2
  43. data/test/dummy/app/models/ability.rb +0 -7
  44. data/test/dummy/app/models/user.rb +0 -6
  45. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  46. data/test/dummy/config.ru +0 -4
  47. data/test/dummy/config/application.rb +0 -52
  48. data/test/dummy/config/boot.rb +0 -11
  49. data/test/dummy/config/database.yml +0 -25
  50. data/test/dummy/config/environment.rb +0 -5
  51. data/test/dummy/config/environments/development.rb +0 -30
  52. data/test/dummy/config/environments/test.rb +0 -38
  53. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  54. data/test/dummy/config/initializers/devise.rb +0 -257
  55. data/test/dummy/config/initializers/inflections.rb +0 -15
  56. data/test/dummy/config/initializers/mime_types.rb +0 -5
  57. data/test/dummy/config/initializers/secret_token.rb +0 -7
  58. data/test/dummy/config/initializers/session_store.rb +0 -8
  59. data/test/dummy/config/initializers/tuttle.rb +0 -3
  60. data/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  61. data/test/dummy/config/locales/en.yml +0 -5
  62. data/test/dummy/config/routes.rb +0 -5
  63. data/test/dummy/db/migrate/20141229204528_devise_create_users.rb +0 -42
  64. data/test/dummy/db/schema.rb +0 -34
  65. data/test/dummy/public/404.html +0 -26
  66. data/test/dummy/public/422.html +0 -26
  67. data/test/dummy/public/500.html +0 -25
  68. data/test/dummy/public/favicon.ico +0 -0
  69. data/test/dummy/script/rails +0 -6
  70. data/test/dummy/test/fixtures/users.yml +0 -6
  71. data/test/dummy/test/models/user_test.rb +0 -7
  72. data/test/dummy/tmp/cache/assets/test/sprockets/00091e0cb6df543a8e704290f4dec8db +0 -0
  73. data/test/dummy/tmp/cache/assets/test/sprockets/11599cd5b5d6a0a58a5e98c0902e1997 +0 -0
  74. data/test/dummy/tmp/cache/assets/test/sprockets/9b2e26c1e54d4ff5ae04270e8f03907f +0 -0
  75. data/test/dummy/tmp/cache/assets/test/sprockets/a65793481a75afa9f660d1032ee66ef5 +0 -0
  76. data/test/dummy/tmp/cache/assets/test/sprockets/d9450766086a9f3f994e8c4a2273bfaa +0 -0
  77. data/test/dummy/tmp/cache/assets/test/sprockets/e117b0425a7b9daef8a213c1a2203f00 +0 -0
  78. data/test/integration/navigation_test.rb +0 -9
  79. data/test/test_helper.rb +0 -37
  80. data/test/tuttle_test.rb +0 -7
  81. data/test/unit/tuttle/note_test.rb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 73376a729eaa050431d5429bc44cbaf0ae395102
4
- data.tar.gz: 28f8cbd544f44c4313aab862c4851c73a1db19b2
3
+ metadata.gz: afd1a594a8f4791f9d32265d0c3845df82ede0f9
4
+ data.tar.gz: dd185815e582e48e5e9eeb56df7abcffc2a5fe3f
5
5
  SHA512:
6
- metadata.gz: d1adf98bdb6bee5241729f1d3f63fe837b7c8827940e149915a2b26c65d05e594d00a642039d5e4c2335efe3561db24db2bc43375f42d3a866b8c9519079f6f5
7
- data.tar.gz: cbc6476294b3e90d88ba033798f9e6854f5784ecb3b3c15ff78714eb1bdc4b628a2233efa472c93a3ab41d61b6a7f4b61234ce36bf1d5d4f82ddd46ef851d525
6
+ metadata.gz: b3dd8bb7b3411012cd4adba504ae9d80c9882b16f1ba34ad9219005ce572021102feac399a1bf4dd14e5b337f291fc93ab4d55ea83c8314d7d97439f4287a8b9
7
+ data.tar.gz: 1fd05873a8248f3ef3a04c0e3975345d648e9c89ea0c0213ef867372dcf949e081237587dbbe6b19be9b59707ede7ac1bcddca21bbe7cbd56ac6d6f1cae9dabd
@@ -1,6 +1,16 @@
1
+ ### 0.0.3
2
+
3
+ * Features
4
+ * Rails caching instrumentation
5
+ * Improved initialization/configuration approach
6
+ * Gem detection and reporting for HTTP clients and JSON libraries
7
+ * Ruby GC tuning stats and advice
8
+ * Favicon!
9
+ * Experimental Postgres stored-procedure cache inspection
10
+
1
11
  ### 0.0.2
2
12
 
3
- * features
13
+ * Features
4
14
  * Tuttle::Engine will now auto-mount routes
5
15
  * Engine configurable via initializer
6
16
  * ActiveSupport cache configuration inspection
@@ -8,7 +18,7 @@
8
18
 
9
19
  ### 0.0.1
10
20
 
11
- * features
21
+ * Features
12
22
  * Initial engine implementation with instrumentation monitoring
13
23
  * Rails inspection for general configuration, controllers, models, assets, helpers
14
24
  * Ruby VM inspection
data/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  Tuttle is a tool for assisting Rails developers by exposing runtime configuration information for your application. It is similar to the `/rails/info/routes` and `/rails/info/properties` information pages or the `rake routes` and `rake middleware` tasks.
9
9
 
10
- Tuttle is very much in alpha/proof-of-concept mode. The [tuttle-demo](github.com/dgynn/tuttle-demo) project shows it being used in a simple application.
10
+ Tuttle is very much in alpha/proof-of-concept mode. You can see it in action in a [simple demo application](http://tuttle-demo.herokuapp.com/). The [source code](https://github.com/dgynn/tuttle-demo) for that demo is also on GitHub.
11
11
 
12
12
  ## To use...
13
13
 
@@ -6,12 +6,9 @@ module Tuttle
6
6
 
7
7
  def check_reload_status
8
8
  return unless Tuttle::Engine.reload_needed && !Rails.configuration.eager_load
9
- Rails.logger.warn('Tuttle: Eager-loading application')
10
- # Rails::Application::Finisher defines an initializer that *would* execute
11
- # these two lines if eager_load were enabled
12
- # ActiveSupport.run_load_hooks(:before_eager_load, Rails.application)
9
+ Tuttle::Engine.logger.warn('Eager-loading application')
13
10
  ActiveSupport::Notifications.instrument 'tuttle.perform_eager_load' do
14
- Rails.configuration.eager_load_namespaces.each(&:eager_load!)
11
+ Rails.application.eager_load!
15
12
  Tuttle::Engine.reload_needed = false
16
13
  end
17
14
  end
@@ -9,12 +9,15 @@ module Tuttle
9
9
  end
10
10
 
11
11
  def rule_tester
12
+ @models = ActiveRecord::Base.descendants
12
13
  @action = params[:action_name] || 'read'
14
+
13
15
  subject_class = params[:subject_class]
14
16
  subject_id = params[:subject_id]
15
- if subject_class
17
+
18
+ if !subject_class.blank? && Kernel.const_defined?(subject_class)
16
19
  begin
17
- subject_klass = subject_class.constantize
20
+ subject_klass = Kernel.const_get(params[:subject_class])
18
21
  @subject = subject_klass.find(subject_id) unless subject_id.blank?
19
22
  @subject ||= subject_klass.new
20
23
  rescue
@@ -0,0 +1,19 @@
1
+ require_dependency 'tuttle/application_controller'
2
+
3
+ module Tuttle
4
+ class GemsController < ApplicationController
5
+
6
+ def http_clients
7
+
8
+ end
9
+
10
+ def json
11
+
12
+ end
13
+
14
+ def other
15
+
16
+ end
17
+
18
+ end
19
+ end
@@ -59,8 +59,14 @@ module Tuttle
59
59
  end
60
60
 
61
61
  def cache
62
+ # TODO: make cache instrumentation controllable - this will automatically turn in on in Rails < 4.2
63
+ # Instrumentation is always on in Rails 4.2+
64
+ if Rails::VERSION::STRING =~ /^4\.1\./ && !ActiveSupport::Cache::Store.instrument
65
+ ActiveSupport::Cache::Store.instrument=true
66
+ end
62
67
  @cache = Rails.cache
63
68
  @cache_events = Tuttle::Engine.events.select {|e| /cache_(read|write)\.active_support/ =~ e.name }
69
+ @tuttle_cache_events = Tuttle::Engine.cache_events
64
70
  end
65
71
 
66
72
  end
@@ -8,5 +8,28 @@ module Tuttle
8
8
  @filtered_env = ENV.to_hash.tap{ |h| h.each{ |k,_v| h[k] = '--FILTERED--' if /.*_(URL|PASSWORD|KEY|KEY_BASE)$/ =~ k } }
9
9
  end
10
10
 
11
+ def tuning
12
+ @gc_enabled = (GC.disable ? false : GC.enable)
13
+
14
+ # taken verbatim from the ruby 2.2 man page
15
+ @gc_params = {
16
+ 'RUBY_GC_HEAP_INIT_SLOTS' => 'Initial allocation slots. Introduced in Ruby 2.1, default: 10000.',
17
+ 'RUBY_GC_HEAP_FREE_SLOTS' => 'Prepare at least this amount of slots after GC. Allocate this number slots if there are not enough slots. Introduced in Ruby 2.1, default: 4096',
18
+ 'RUBY_GC_HEAP_GROWTH_FACTOR' => 'Increase allocation rate of heap slots by this factor. Introduced in Ruby 2.1, default: 1.8, minimum: 1.0 (no growth)',
19
+ 'RUBY_GC_HEAP_GROWTH_MAX_SLOTS' => 'Allocation rate is limited to this number of slots, preventing excessive allocation due to RUBY_GC_HEAP_GROWTH_FACTOR. Introduced in Ruby 2.1, default: 0 (no limit)',
20
+ 'RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR' => 'Perform a full GC when the number of old objects is more than R * N, where R is this factor and N is the number of old objects after the last full GC. Introduced in Ruby 2.1.1, default: 2.0',
21
+ 'RUBY_GC_MALLOC_LIMIT' => 'The initial limit of young generation allocation from the malloc-family. GC will start when this limit is reached. Default: 16MB',
22
+ 'RUBY_GC_MALLOC_LIMIT_MAX' => 'The maximum limit of young generation allocation from malloc before GC starts. Prevents excessive malloc growth due to RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR. Introduced in Ruby 2.1, default: 32MB.',
23
+ 'RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR' => 'Increases the limit of young generation malloc calls, reducing GC frequency but increasing malloc growth until RUBY_GC_MALLOC_LIMIT_MAX is reached. Introduced in Ruby 2.1, default: 1.4, minimum: 1.0 (no growth)',
24
+ 'RUBY_GC_OLDMALLOC_LIMIT' => 'The initial limit of old generation allocation from malloc, a full GC will start when this limit is reached. Introduced in Ruby 2.1, default: 16MB',
25
+ 'RUBY_GC_OLDMALLOC_LIMIT_MAX' => 'The maximum limit of old generation allocation from malloc before a full GC starts. Prevents excessive malloc growth due to RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR. Introduced in Ruby 2.1, default: 128MB',
26
+ 'RUBY_GC_OLDMALLOC_LIMIT_GROWTH_FACTOR' => 'Increases the limit of old generation malloc allocation, reducing full GC frequency but increasing malloc growth until RUBY_GC_OLDMALLOC_LIMIT_MAX is reached. Introduced in Ruby 2.1, default: 1.2, minimum: 1.0 (no growth)'
27
+ }
28
+ end
29
+
30
+ def miscellaneous
31
+
32
+ end
33
+
11
34
  end
12
35
  end
@@ -1,4 +1,9 @@
1
1
  module Tuttle
2
2
  module ApplicationHelper
3
+
4
+ def truth_label(is_true, true_label='true', false_label='false')
5
+ "<span class='label label-#{ is_true ? 'success':'danger'}'>#{ is_true ? true_label : false_label}</span>".html_safe
6
+ end
7
+
3
8
  end
4
9
  end
@@ -5,8 +5,10 @@
5
5
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1">
7
7
  <title>Tuttle</title>
8
- <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
9
- <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
8
+ <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css">
9
+ <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap-theme.min.css">
10
+ <link rel="icon" href="<%= image_path 'tuttle/favicon.ico' %>">
11
+
10
12
  <%= stylesheet_link_tag "tuttle/application", :media => "all" %>
11
13
  <%= csrf_meta_tags %>
12
14
  </head>
@@ -45,11 +47,26 @@
45
47
  <li class="dropdown">
46
48
  <a href="#" class="dropdown-toggle" data-toggle="dropdown">Gems <span class="caret"></span></a>
47
49
  <ul class="dropdown-menu" role="menu">
48
- <li><%= link_to 'Devise', devise_path if defined?(Devise) %></li>
49
- <li><%= link_to 'CanCanCan', cancancan_path if defined?(CanCanCan) %></li>
50
+ <%- if defined?(Devise) %>
51
+ <li><%= link_to 'Devise', devise_path %></li>
52
+ <%- end %>
53
+ <%- if defined?(CanCanCan) %>
54
+ <li><%= link_to 'CanCanCan', cancancan_path %></li>
55
+ <%- end %>
56
+ <li><%= link_to 'HTTP Clients', gems_http_clients_path %></li>
57
+ <li><%= link_to 'JSON', gems_json_path %></li>
58
+ <li><%= link_to 'Other', gems_other_path %></li>
59
+ </ul>
60
+ </li>
61
+ <li class="dropdown">
62
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">Ruby <span class="caret"></span></a>
63
+ <ul class="dropdown-menu" role="menu">
64
+ <li><%= link_to 'Overview', ruby_path %></li>
65
+ <li class="divider"></li>
66
+ <li><%= link_to 'Tuning', ruby_tuning_path %></li>
67
+ <li><%= link_to 'Miscellaneous', ruby_miscellaneous_path %></li>
50
68
  </ul>
51
69
  </li>
52
- <li><%= link_to 'Ruby', ruby_path %></li>
53
70
  </ul>
54
71
  </div>
55
72
  </div>
@@ -61,8 +78,8 @@
61
78
  </div>
62
79
  </div>
63
80
 
64
- <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
65
- <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
81
+ <script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
82
+ <script src="//maxcdn.bootstrapcdn.com/bootstrap/latest/js/bootstrap.min.js"></script>
66
83
  <script src="//cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.10.4/typeahead.bundle.min.js"></script>
67
84
  <%= javascript_include_tag "tuttle/application" =%>
68
85
  <%= content_for(:javascripts) =%>
@@ -21,7 +21,7 @@
21
21
  <%- subjects = rule.instance_variable_get('@subjects') %>
22
22
  <td>
23
23
  <% subjects.each do |s| %>
24
- <%= s.class <= Symbol ? s.to_s : s.name %>
24
+ <%= s %>
25
25
  <% end %>
26
26
  </td>
27
27
  <td><%= rule.conditions unless rule.conditions.empty? %></td>
@@ -32,7 +32,7 @@
32
32
  <%- subjects = rule.instance_variable_get('@subjects') %>
33
33
  <td>
34
34
  <% subjects.each do |s| %>
35
- <%= s.class <= Symbol ? s.to_s : s.name %>
35
+ <%= s %>
36
36
  <% end %>
37
37
  </td>
38
38
  <td><%= rule.conditions %></td>
@@ -11,13 +11,13 @@
11
11
  <div class="form-group">
12
12
  <label for="action_name" class="col-sm-2 control-label">Action</label>
13
13
  <div class="col-sm-10">
14
- <input type="text" class="form-control typeahead" name="action_name" id="action_name" value="<%= params[:action_name] || 'read' %>">
14
+ <input type="text" class="form-control typeahead" name="action_name" id="action_name" value="<%= @action %>">
15
15
  </div>
16
16
  </div>
17
17
  <div class="form-group">
18
18
  <label for="subject_class" class="col-sm-2 control-label">Subject Class</label>
19
19
  <div class="col-sm-10">
20
- <input type="text" class="form-control" name="subject_class" value="<%= @subject.try(:class) || params[:subject_class] %>">
20
+ <%= select_tag('subject_class',options_for_select(@models.collect(&:name).sort, params[:subject_class]),:include_blank=>true, :class => 'form-control') %>
21
21
  </div>
22
22
  </div>
23
23
  <div class="form-group">
@@ -0,0 +1,35 @@
1
+ <h1>HTTP Clients</h1>
2
+
3
+ <div class="panel panel-default">
4
+ <div class="panel-heading">
5
+ <h3 class="panel-title">HTTP Client Libraries</h3>
6
+ </div>
7
+ <div class="panel-body">
8
+ <p>
9
+ HTTP client libraries are used to make requests to remote servers often as REST or SOAP requests.
10
+ There are many libraries available with different features and purposes.
11
+ Often client libraries are pulled in as dependencies of other gems you've included.
12
+ </p>
13
+
14
+ <p>Libraries detected and loaded</p>
15
+ <ul>
16
+ <li>Net::HTTP (core ruby) <%= truth_label(defined?(Net::HTTP)) %></li>
17
+ <li>Excon: <%= truth_label(defined?(Excon)) %></li>
18
+ <li>HTTPI: <%= truth_label(defined?(HTTPI)) %></li>
19
+ <li>httpclient: <%= truth_label(defined?(HTTPClient)) %></li>
20
+ <li>Typhoeus: <%= truth_label(defined?(Typhoeus)) %></li>
21
+ <li>Faraday: <%= truth_label(defined?(Faraday)) %>
22
+ <%- if defined?(Faraday) %>
23
+ &mdash; (Default adapter: <%= Faraday.default_adapter %>)
24
+ <%- end %>
25
+ </li>
26
+ <li>Net::HTTP::Post::Multipart: <%= truth_label(defined?(Net::HTTP::Post::Multipart)) %></li>
27
+ <li>Patron: <%= truth_label(defined?(Patron::Session)) %></li>
28
+ <li>Savon: <%= truth_label(defined?(Savon)) %></li>
29
+ <li>Event Machine HttpRequest: <%= truth_label(defined?(EventMachine::HttpRequest)) %></li>
30
+ </ul>
31
+ <p></p>
32
+ </div>
33
+ <div class="panel-footer">
34
+ </div>
35
+ </div>
@@ -0,0 +1,31 @@
1
+ <h1>JSON Gems</h1>
2
+
3
+ <div class="panel panel-default">
4
+ <div class="panel-heading">
5
+ <h3 class="panel-title">JSON Libraries</h3>
6
+ </div>
7
+ <div class="panel-body">
8
+ <p>
9
+ There are a small number of libraries that are involved in JSON encoding and decoding.
10
+ Depending on the nature of the JSON you are decoding or objects you are encoding you may see a benefit by using the appropriate library.
11
+ </p>
12
+
13
+ <p>Libraries detected</p>
14
+ <ul>
15
+ <li>JSON Pure: <%= truth_label(defined?(JSON::Pure)) %></li>
16
+ <li>JSON: <%= truth_label(defined?(JSON) && !defined?(JSON::Pure)) %></li>
17
+ <li>Yajl: <%= truth_label(defined?(Yajl)) %></li>
18
+ <li>Oj: <%= truth_label(defined?(Oj)) %></li>
19
+ <li>
20
+ MultiJson: <%= truth_label(defined?(MultiJson)) %>
21
+ <%- if defined?(MultiJson) %>
22
+ &mdash; (Adapter: <%= MultiJson.adapter %>)
23
+ <%- end %>
24
+ </li>
25
+ <li>ActiveSupport::JSON: <%= truth_label(defined?(ActiveSupport::JSON)) %></li>
26
+ </ul>
27
+ <p></p>
28
+ </div>
29
+ <div class="panel-footer">
30
+ </div>
31
+ </div>
@@ -0,0 +1,16 @@
1
+ <h1>Other Gems</h1>
2
+
3
+ <div class="panel panel-default">
4
+ <div class="panel-heading">
5
+ <h3 class="panel-title">Performance Libraries</h3>
6
+ </div>
7
+ <div class="panel-body">
8
+ <p>
9
+ Various gems are often included in applications to eke out a bit more performance.
10
+ Here are various gems which may be helpful.
11
+ </p>
12
+ <p>fast_blank - <%= truth_label("TEST".methods.include?(:blank_as?), 'installed', 'not installed') %></p>
13
+ </div>
14
+ <div class="panel-footer">
15
+ </div>
16
+ </div>
@@ -75,7 +75,33 @@ DalliStore options
75
75
  <% end -%>
76
76
  </table>
77
77
 
78
+ <h3>Recent cache call locations</h3>
79
+
80
+ <table class="table">
81
+ <tr>
82
+ <th>Action</th>
83
+ <th>File</th>
84
+ <th>Line</th>
85
+ <th>Key</th>
86
+ <th>Hit?</th>
87
+ <th>Options</th>
88
+ <th>Time</th>
89
+ <th>TransactionID</th>
90
+ </tr>
91
+ <% @tuttle_cache_events.reverse.each do |event| -%>
92
+ <tr >
93
+ <td>Read</td>
94
+ <td><%= event.payload[:call_location_path] %></td>
95
+ <td><%= event.payload[:call_location_lineno] %></td>
96
+ <td><%= event.payload[:key] %></td>
97
+ <td><%= event.payload[:hit] %></td>
98
+ <td><%= event.payload.reject {|k,_v| %i(key hit call_location_path call_location_lineno).include?(k) } %></td>
99
+ <td><%= event.time.to_s(:db) %></td>
100
+ <td><%= event.transaction_id %></td>
101
+ </tr>
102
+ <% end -%>
103
+ </table>
104
+
78
105
  <%-
79
106
  # TODO: Track calls and record keys broken down by namespace
80
- # TODO: Possibly track calls with backtrace to identify calling location
81
107
  -%>
@@ -16,6 +16,27 @@
16
16
  <p>Schema Cache size = <%= @conn.schema_cache.size %></p>
17
17
 
18
18
  <%- if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) && @conn.class <= ActiveRecord::ConnectionAdapters::PostgreSQLAdapter -%>
19
+
20
+ <%- statement_pool = @conn.instance_variable_get(:@statements) %>
21
+ <%- if statement_pool.present? %>
22
+ <h3>Prepared Statement Pool</h3>
23
+ <p>Max = <%= statement_pool.instance_variable_get(:@max) %></p>
24
+ <p>Counter = <%= statement_pool.instance_variable_get(:@counter) %></p>
25
+ <h4>Cache</h4>
26
+ <ol>
27
+ <%- statement_pool.instance_variable_get(:@cache).each do |pid,cache| %>
28
+ <li>PID: <%= pid %>
29
+ <ol>
30
+ <%- cache.each do |k,v| %>
31
+ <li><%= v %> = <%= k %></li>
32
+ <%- end %>
33
+ </ol>
34
+ </li>
35
+ <%- end %>
36
+ </ol>
37
+ <%- end %>
38
+
39
+
19
40
  <h3>PostgreSQL-only Info</h3>
20
41
  <p>Database = <%= @conn.current_database %></p>
21
42
  <p>Schema = <%= @conn.current_schema %></p>
@@ -93,11 +93,21 @@ Log Level = <%= Rails.configuration.log_level %>
93
93
  <div class="tab-pane" id="initializers">
94
94
  <p>Rails initializers are blocks of code that run during application initialization.</p>
95
95
  <p>Initializers can be provided by any Railtie, which includes Rails components themselves as well as many Gems.</p>
96
- <ol>
97
- <%- Rails.application.initializers.each do |initializer| %>
98
- <li><%= initializer.name %> - <%= initializer.instance_variable_get('@context').class.name %></li>
99
- <%- end %>
100
- </ol>
96
+ <table class="table table-condensed">
97
+ <tr><th>#</th><th>Name</th><th>Context Class</th><th>Group</th><th>After</th><th>Before</th></tr>
98
+ <%- idx = 0 %>
99
+ <%- Rails.application.initializers.tsort_each do |initializer| %>
100
+ <%- options = initializer.instance_variable_get('@options') %>
101
+ <tr>
102
+ <td><%= idx+=1 %></td>
103
+ <td><%= initializer.name %></td>
104
+ <td><%= initializer.instance_variable_get('@context').class.name %></td>
105
+ <td><%= options.try(:[],:group) %></td>
106
+ <td><%= options.try(:[],:after) %></td>
107
+ <td><%= options.try(:[],:before) %></td>
108
+ </tr>
109
+ <%- end %>
110
+ </table>
101
111
  </div>
102
112
  <div class="tab-pane" id="middleware">
103
113
  <p>The Rack middleware configuration shows the modules in the Rack stack that will process the request and response.</p>
@@ -120,7 +130,7 @@ Log Level = <%= Rails.configuration.log_level %>
120
130
  <ol>
121
131
  <%- # TODO: protected methods `ordered_railties` changed to return an array of arrays between rails 4.1.5 and 4.1.8. investigate and replace. -%>
122
132
  <%- ordered_railties = Rails.application.send(:ordered_railties) -%>
123
- <%- ordered_railties = ordered_railties[0] if ordered_railties.is_a?(Array) -%>
133
+ <%- ordered_railties = ordered_railties[0] if ordered_railties.is_a?(Array) && ordered_railties[0].is_a?(Array) -%>
124
134
  <%- ordered_railties.each do |railtie| %>
125
135
  <li><%= railtie.railtie_name %> - <%= railtie.class.name %></li>
126
136
  <%- end %>
@@ -15,7 +15,7 @@
15
15
  <td><%= event.name %></td>
16
16
  <td><%= event.time.to_s(:db) %></td>
17
17
  <td><%= number_with_precision(event.duration) %></td>
18
- <td><%= truncate(event.payload.to_s, length: 250) %></td>
18
+ <td><%= truncate(event.payload.to_s, length: 250) rescue 'Payload not captured' %></td>
19
19
  <td><%= event.transaction_id %></td>
20
20
  </tr>
21
21
  <% end -%>