tuttle 0.0.2 → 0.0.3

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 (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 -%>