rails_vitals 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -1
  3. data/app/assets/stylesheets/rails_vitals/application.css +43 -0
  4. data/app/helpers/rails_vitals/application_helper.rb +23 -1
  5. data/app/views/rails_vitals/dashboard/index.html.erb +8 -16
  6. data/app/views/rails_vitals/explains/show.html.erb +9 -40
  7. data/app/views/rails_vitals/heatmap/index.html.erb +3 -4
  8. data/app/views/rails_vitals/models/index.html.erb +2 -3
  9. data/app/views/rails_vitals/n_plus_ones/index.html.erb +1 -3
  10. data/app/views/rails_vitals/n_plus_ones/show.html.erb +7 -8
  11. data/app/views/rails_vitals/playgrounds/index.html.erb +2 -0
  12. data/app/views/rails_vitals/requests/index.html.erb +6 -12
  13. data/app/views/rails_vitals/requests/show.html.erb +23 -25
  14. data/app/views/rails_vitals/shared/_empty_state.html.erb +3 -0
  15. data/app/views/rails_vitals/shared/_n1_indicator.html.erb +9 -0
  16. data/app/views/rails_vitals/shared/_page_header.html.erb +15 -0
  17. data/app/views/rails_vitals/shared/_score_badge.html.erb +3 -0
  18. data/lib/rails_vitals/analyzers/association_mapper.rb +1 -1
  19. data/lib/rails_vitals/analyzers/explain_analyzer.rb +59 -57
  20. data/lib/rails_vitals/analyzers/n_plus_one_aggregator.rb +13 -13
  21. data/lib/rails_vitals/analyzers/sql_tokenizer.rb +81 -81
  22. data/lib/rails_vitals/collector.rb +18 -18
  23. data/lib/rails_vitals/instrumentation/callback_instrumentation.rb +3 -3
  24. data/lib/rails_vitals/notifications/subscriber.rb +3 -3
  25. data/lib/rails_vitals/panel_renderer.rb +7 -11
  26. data/lib/rails_vitals/playground/sandbox.rb +2 -1
  27. data/lib/rails_vitals/request_record.rb +12 -12
  28. data/lib/rails_vitals/scorers/base_scorer.rb +3 -3
  29. data/lib/rails_vitals/scorers/composite_scorer.rb +3 -3
  30. data/lib/rails_vitals/scorers/query_scorer.rb +3 -3
  31. data/lib/rails_vitals/store.rb +2 -2
  32. data/lib/rails_vitals/version.rb +1 -1
  33. metadata +5 -1
@@ -7,7 +7,7 @@ module RailsVitals
7
7
 
8
8
  def initialize(collector, scorer)
9
9
  @collector = collector
10
- @scorer = scorer
10
+ @scorer = scorer
11
11
  end
12
12
 
13
13
  def render
@@ -132,10 +132,11 @@ module RailsVitals
132
132
  return "" if queries.empty?
133
133
 
134
134
  rows = queries.map do |q|
135
- sql = truncate(q[:sql], 45)
135
+ sql = truncate(q[:sql], 45)
136
136
  time_ms = q[:duration_ms].round(1)
137
+
137
138
  <<~HTML
138
- <div style="margin-bottom:6px;">
139
+ <div style="margin-bottom:8px;">
139
140
  <div style="color:#90cdf4;font-size:11px;">#{escape(sql)}</div>
140
141
  <div style="color:#68d391;font-size:10px;">#{time_ms}ms</div>
141
142
  </div>
@@ -189,12 +190,7 @@ module RailsVitals
189
190
  end
190
191
 
191
192
  def score_bg
192
- case @scorer.color
193
- when "green" then "#276749"
194
- when "blue" then "#2b6cb0"
195
- when "amber" then "#b7791f"
196
- else "#c53030"
197
- end
193
+ RailsVitals::ApplicationHelper.score_color_for(@scorer.color)
198
194
  end
199
195
 
200
196
  def n_plus_one_scorer
@@ -216,8 +212,8 @@ module RailsVitals
216
212
  <script>
217
213
  function rvToggle() {
218
214
  var expanded = document.getElementById('rv-expanded');
219
- var badge = document.getElementById('rv-badge');
220
- var arrow = badge.querySelector('span:last-child');
215
+ var badge = document.getElementById('rv-badge');
216
+ var arrow = badge.querySelector('span:last-child');
221
217
  if (expanded.style.display === 'none') {
222
218
  expanded.style.display = 'block';
223
219
  arrow.textContent = '▼';
@@ -50,6 +50,7 @@ module RailsVitals
50
50
 
51
51
  subscriber = ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
52
52
  next if RailsVitals::Notifications::Subscriber.internal_query?(payload[:sql])
53
+
53
54
  queries << {
54
55
  sql: payload[:sql],
55
56
  duration_ms: (payload[:duration].to_f / 1000).round(3)
@@ -60,7 +61,7 @@ module RailsVitals
60
61
  Timeout.timeout(2) do
61
62
  relation = build_relation(expression, model)
62
63
  relation = apply_limit(relation)
63
- records = relation.load
64
+ records = relation.load
64
65
 
65
66
  # Simulate association access — triggers N+1 if not eager loaded
66
67
  if access_associations.any?
@@ -6,20 +6,20 @@ module RailsVitals
6
6
  :callbacks, :total_callback_time_ms, :recorded_at
7
7
 
8
8
  def initialize(collector:, scorer:)
9
- @id = SecureRandom.hex(8)
10
- @controller = collector.controller
11
- @action = collector.action
12
- @http_method = collector.http_method
13
- @response_status = collector.response_status
14
- @duration_ms = collector.duration_ms
15
- @queries = collector.queries
16
- @callbacks = collector.callbacks
9
+ @id = SecureRandom.hex(8)
10
+ @controller = collector.controller
11
+ @action = collector.action
12
+ @http_method = collector.http_method
13
+ @response_status = collector.response_status
14
+ @duration_ms = collector.duration_ms
15
+ @queries = collector.queries
16
+ @callbacks = collector.callbacks
17
17
  @total_callback_time_ms = collector.total_callback_time_ms
18
- @score = scorer.score
19
- @label = scorer.label
20
- @color = scorer.color
18
+ @score = scorer.score
19
+ @label = scorer.label
20
+ @color = scorer.color
21
21
  @n_plus_one_patterns = build_n_plus_one_patterns(scorer)
22
- @recorded_at = Time.now
22
+ @recorded_at = Time.now
23
23
  end
24
24
 
25
25
  def endpoint
@@ -1,10 +1,10 @@
1
1
  module RailsVitals
2
2
  module Scorers
3
3
  class BaseScorer
4
- HEALTHY = (90..100)
4
+ HEALTHY = (90..100)
5
5
  ACCEPTABLE = (70..89)
6
- WARNING = (50..69)
7
- CRITICAL = (0..49)
6
+ WARNING = (50..69)
7
+ CRITICAL = (0..49)
8
8
 
9
9
  def initialize(collector)
10
10
  @collector = collector
@@ -3,14 +3,14 @@ module RailsVitals
3
3
  class CompositeScorer < BaseScorer
4
4
  # Weights will grow as we add more scorers
5
5
  WEIGHTS = {
6
- query: 0.40,
6
+ query: 0.40,
7
7
  n_plus_one: 0.60
8
8
  }.freeze
9
9
 
10
10
  def score
11
11
  clamp(
12
- (QueryScorer.new(@collector).score * WEIGHTS[:query]).round +
13
- (NPlusOneScorer.new(@collector).score * WEIGHTS[:n_plus_one]).round
12
+ (QueryScorer.new(@collector).score * WEIGHTS[:query]).round +
13
+ (NPlusOneScorer.new(@collector).score * WEIGHTS[:n_plus_one]).round
14
14
  )
15
15
  end
16
16
 
@@ -9,7 +9,7 @@ module RailsVitals
9
9
 
10
10
  def count_score
11
11
  count = @collector.total_query_count
12
- warn_threshold = RailsVitals.config.query_warn_threshold
12
+ warn_threshold = RailsVitals.config.query_warn_threshold
13
13
  critical_threshold = RailsVitals.config.query_critical_threshold
14
14
 
15
15
  if count <= warn_threshold
@@ -24,8 +24,8 @@ module RailsVitals
24
24
  end
25
25
 
26
26
  def time_score
27
- time_ms = @collector.total_db_time_ms
28
- warn_ms = RailsVitals.config.db_time_warn_ms
27
+ time_ms = @collector.total_db_time_ms
28
+ warn_ms = RailsVitals.config.db_time_warn_ms
29
29
  critical_ms = RailsVitals.config.db_time_critical_ms
30
30
 
31
31
  if time_ms <= warn_ms
@@ -1,9 +1,9 @@
1
1
  module RailsVitals
2
2
  class Store
3
3
  def initialize(size)
4
- @size = size
4
+ @size = size
5
5
  @records = []
6
- @mutex = Mutex.new
6
+ @mutex = Mutex.new
7
7
  end
8
8
 
9
9
  def push(record)
@@ -1,3 +1,3 @@
1
1
  module RailsVitals
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_vitals
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Sanchez
@@ -65,6 +65,10 @@ files:
65
65
  - app/views/rails_vitals/playgrounds/index.html.erb
66
66
  - app/views/rails_vitals/requests/index.html.erb
67
67
  - app/views/rails_vitals/requests/show.html.erb
68
+ - app/views/rails_vitals/shared/_empty_state.html.erb
69
+ - app/views/rails_vitals/shared/_n1_indicator.html.erb
70
+ - app/views/rails_vitals/shared/_page_header.html.erb
71
+ - app/views/rails_vitals/shared/_score_badge.html.erb
68
72
  - config/routes.rb
69
73
  - lib/rails_vitals.rb
70
74
  - lib/rails_vitals/analyzers/association_mapper.rb