rails_pulse 0.2.2 → 0.2.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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/rails_pulse/components/tags.css +2 -2
  3. data/app/controllers/concerns/chart_table_concern.rb +2 -0
  4. data/app/controllers/rails_pulse/application_controller.rb +1 -0
  5. data/app/controllers/rails_pulse/dashboard_controller.rb +12 -8
  6. data/app/controllers/rails_pulse/queries_controller.rb +12 -7
  7. data/app/controllers/rails_pulse/requests_controller.rb +8 -4
  8. data/app/controllers/rails_pulse/routes_controller.rb +13 -6
  9. data/app/models/concerns/rails_pulse/taggable.rb +63 -0
  10. data/app/models/rails_pulse/dashboard/charts/average_response_time.rb +12 -5
  11. data/app/models/rails_pulse/dashboard/charts/p95_response_time.rb +12 -5
  12. data/app/models/rails_pulse/dashboard/tables/slow_queries.rb +7 -0
  13. data/app/models/rails_pulse/dashboard/tables/slow_routes.rb +6 -0
  14. data/app/models/rails_pulse/queries/cards/average_query_times.rb +10 -6
  15. data/app/models/rails_pulse/queries/cards/execution_rate.rb +16 -10
  16. data/app/models/rails_pulse/queries/cards/percentile_query_times.rb +10 -6
  17. data/app/models/rails_pulse/queries/charts/average_query_times.rb +5 -2
  18. data/app/models/rails_pulse/queries/tables/index.rb +12 -2
  19. data/app/models/rails_pulse/requests/charts/average_response_times.rb +12 -6
  20. data/app/models/rails_pulse/routes/cards/average_response_times.rb +10 -6
  21. data/app/models/rails_pulse/routes/cards/error_rate_per_route.rb +10 -6
  22. data/app/models/rails_pulse/routes/cards/percentile_response_times.rb +10 -6
  23. data/app/models/rails_pulse/routes/cards/request_count_totals.rb +10 -6
  24. data/app/models/rails_pulse/routes/charts/average_response_times.rb +9 -5
  25. data/app/models/rails_pulse/routes/tables/index.rb +12 -2
  26. data/app/models/rails_pulse/summary.rb +55 -0
  27. data/app/views/layouts/rails_pulse/_global_filters.html.erb +9 -2
  28. data/app/views/rails_pulse/components/_active_filters.html.erb +36 -0
  29. data/app/views/rails_pulse/components/_page_header.html.erb +4 -0
  30. data/app/views/rails_pulse/dashboard/index.html.erb +4 -0
  31. data/app/views/rails_pulse/queries/index.html.erb +1 -1
  32. data/app/views/rails_pulse/requests/index.html.erb +1 -1
  33. data/app/views/rails_pulse/routes/index.html.erb +1 -1
  34. data/app/views/rails_pulse/tags/_tag_manager.html.erb +2 -2
  35. data/config/initializers/rails_charts_csp_patch.rb +9 -9
  36. data/lib/rails_pulse/cleanup_service.rb +8 -0
  37. data/lib/rails_pulse/engine.rb +25 -0
  38. data/lib/rails_pulse/version.rb +1 -1
  39. data/public/rails-pulse-assets/rails-pulse.css +1 -1
  40. data/public/rails-pulse-assets/rails-pulse.css.map +1 -1
  41. metadata +4 -3
  42. data/app/models/concerns/taggable.rb +0 -61
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8ed469f307dd71e912b46a4da0a0daa60abbdc262a8dbd12604db00a66335fe
4
- data.tar.gz: 8af5a6bf946a86e1bc277c1d719100ace739bb429c07969fd1e4ec31887d6f70
3
+ metadata.gz: d9f5f4407186848ab8ef3c75d8453dbe44d4f90fd641a50527b26cf9f4b10b82
4
+ data.tar.gz: 283484459f73560755c16519e808d754bf23d82edb05ef7b98fcc396bdf3ead2
5
5
  SHA512:
6
- metadata.gz: eceb3af7e713b6049688e50a8fd79af7b2f09c7720158c8d15257235b0c7488ebe7c0eccfaab3cd5dfb5923f80e9a8bd8693d0a9fb2f4e021aca8846c4ac435c
7
- data.tar.gz: f982a50256d99968eb68fee89e6380d3f75511e6c3e8e878ddca375919f6a68a201f9ce46c6868e2425c127ae1862ca0d1895b0e01afea89a9af6a4e85d7f0f9
6
+ metadata.gz: b75fca5343d2080ecc547a5c8b68d2ec7ac431aea54505ad042721262c0f95c5955e229dcd338b011dfcdc208d7e6467b8b1c768efa83379efff5d7deaf13200
7
+ data.tar.gz: a8e5d530527ed56d61029707825dd74885a742b132b41d5471c981f544c922e0431a6813d61e73db01dc85b17681aeb25c53347358cf93586b1b36af7874ab99
@@ -75,8 +75,8 @@
75
75
  }
76
76
 
77
77
  .tag-add-button {
78
- padding: 0.25rem 0.5rem;
79
- font-size: 0.875rem;
78
+ padding: 0.2rem 0.5rem;
79
+ font-size: 0.8rem;
80
80
  line-height: 1.25;
81
81
  white-space: nowrap;
82
82
  }
@@ -38,6 +38,8 @@ module ChartTableConcern
38
38
  start_time: @start_time,
39
39
  end_time: @end_time,
40
40
  start_duration: @start_duration,
41
+ disabled_tags: session_disabled_tags,
42
+ show_non_tagged: session[:show_non_tagged] != false,
41
43
  **chart_options
42
44
  ).to_rails_chart
43
45
  end
@@ -17,6 +17,7 @@ module RailsPulse
17
17
  def set_global_filters
18
18
  if params[:clear] == "true"
19
19
  session.delete(:global_filters)
20
+ session[:show_non_tagged] = true # Reset show_non_tagged to default
20
21
  else
21
22
  filters = session[:global_filters] || {}
22
23
 
@@ -1,18 +1,22 @@
1
1
  module RailsPulse
2
2
  class DashboardController < ApplicationController
3
3
  def index
4
- @average_query_times_metric_card = RailsPulse::Routes::Cards::AverageResponseTimes.new(route: nil).to_metric_card
5
- @percentile_response_times_metric_card = RailsPulse::Routes::Cards::PercentileResponseTimes.new(route: nil).to_metric_card
6
- @request_count_totals_metric_card = RailsPulse::Routes::Cards::RequestCountTotals.new(route: nil).to_metric_card
7
- @error_rate_per_route_metric_card = RailsPulse::Routes::Cards::ErrorRatePerRoute.new(route: nil).to_metric_card
4
+ # Get tag filter values from session
5
+ disabled_tags = session_disabled_tags
6
+ show_non_tagged = session[:show_non_tagged] != false
7
+
8
+ @average_query_times_metric_card = RailsPulse::Routes::Cards::AverageResponseTimes.new(route: nil, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
9
+ @percentile_response_times_metric_card = RailsPulse::Routes::Cards::PercentileResponseTimes.new(route: nil, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
10
+ @request_count_totals_metric_card = RailsPulse::Routes::Cards::RequestCountTotals.new(route: nil, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
11
+ @error_rate_per_route_metric_card = RailsPulse::Routes::Cards::ErrorRatePerRoute.new(route: nil, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
8
12
 
9
13
  # Generate chart data for inline rendering
10
- @average_response_time_chart_data = RailsPulse::Dashboard::Charts::AverageResponseTime.new.to_chart_data
11
- @p95_response_time_chart_data = RailsPulse::Dashboard::Charts::P95ResponseTime.new.to_chart_data
14
+ @average_response_time_chart_data = RailsPulse::Dashboard::Charts::AverageResponseTime.new(disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_chart_data
15
+ @p95_response_time_chart_data = RailsPulse::Dashboard::Charts::P95ResponseTime.new(disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_chart_data
12
16
 
13
17
  # Generate table data for inline rendering
14
- @slow_routes_table_data = RailsPulse::Dashboard::Tables::SlowRoutes.new.to_table_data
15
- @slow_queries_table_data = RailsPulse::Dashboard::Tables::SlowQueries.new.to_table_data
18
+ @slow_routes_table_data = RailsPulse::Dashboard::Tables::SlowRoutes.new(disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_table_data
19
+ @slow_queries_table_data = RailsPulse::Dashboard::Tables::SlowQueries.new(disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_table_data
16
20
  end
17
21
  end
18
22
  end
@@ -70,7 +70,8 @@ module RailsPulse
70
70
  def build_chart_ransack_params(ransack_params)
71
71
  base_params = ransack_params.except(:s).merge(
72
72
  period_start_gteq: Time.at(@start_time),
73
- period_start_lt: Time.at(@end_time)
73
+ period_start_lt: Time.at(@end_time),
74
+ summarizable_type_eq: "RailsPulse::Query"
74
75
  )
75
76
 
76
77
  # Only add duration filter if we have a meaningful threshold
@@ -78,8 +79,7 @@ module RailsPulse
78
79
 
79
80
  if show_action?
80
81
  base_params.merge(
81
- summarizable_id_eq: @query.id,
82
- summarizable_type_eq: "RailsPulse::Query"
82
+ summarizable_id_eq: @query.id
83
83
  )
84
84
  else
85
85
  base_params
@@ -123,7 +123,8 @@ module RailsPulse
123
123
  period_type: period_type,
124
124
  start_time: @start_time,
125
125
  params: params,
126
- disabled_tags: session_disabled_tags
126
+ disabled_tags: session_disabled_tags,
127
+ show_non_tagged: session[:show_non_tagged] != false
127
128
  ).to_table
128
129
  end
129
130
  end
@@ -133,9 +134,13 @@ module RailsPulse
133
134
  def setup_metric_cards
134
135
  return if turbo_frame_request?
135
136
 
136
- @average_query_times_metric_card = RailsPulse::Queries::Cards::AverageQueryTimes.new(query: @query).to_metric_card
137
- @percentile_query_times_metric_card = RailsPulse::Queries::Cards::PercentileQueryTimes.new(query: @query).to_metric_card
138
- @execution_rate_metric_card = RailsPulse::Queries::Cards::ExecutionRate.new(query: @query).to_metric_card
137
+ # Get tag filter values from session
138
+ disabled_tags = session_disabled_tags
139
+ show_non_tagged = session[:show_non_tagged] != false
140
+
141
+ @average_query_times_metric_card = RailsPulse::Queries::Cards::AverageQueryTimes.new(query: @query, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
142
+ @percentile_query_times_metric_card = RailsPulse::Queries::Cards::PercentileQueryTimes.new(query: @query, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
143
+ @execution_rate_metric_card = RailsPulse::Queries::Cards::ExecutionRate.new(query: @query, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
139
144
  end
140
145
 
141
146
  def show_action?
@@ -26,10 +26,14 @@ module RailsPulse
26
26
  def setup_metric_cards
27
27
  return if turbo_frame_request?
28
28
 
29
- @average_response_times_metric_card = RailsPulse::Routes::Cards::AverageResponseTimes.new(route: nil).to_metric_card
30
- @percentile_response_times_metric_card = RailsPulse::Routes::Cards::PercentileResponseTimes.new(route: nil).to_metric_card
31
- @request_count_totals_metric_card = RailsPulse::Routes::Cards::RequestCountTotals.new(route: nil).to_metric_card
32
- @error_rate_per_route_metric_card = RailsPulse::Routes::Cards::ErrorRatePerRoute.new(route: nil).to_metric_card
29
+ # Get tag filter values from session
30
+ disabled_tags = session_disabled_tags
31
+ show_non_tagged = session[:show_non_tagged] != false
32
+
33
+ @average_response_times_metric_card = RailsPulse::Routes::Cards::AverageResponseTimes.new(route: nil, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
34
+ @percentile_response_times_metric_card = RailsPulse::Routes::Cards::PercentileResponseTimes.new(route: nil, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
35
+ @request_count_totals_metric_card = RailsPulse::Routes::Cards::RequestCountTotals.new(route: nil, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
36
+ @error_rate_per_route_metric_card = RailsPulse::Routes::Cards::ErrorRatePerRoute.new(route: nil, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
33
37
  end
34
38
 
35
39
 
@@ -20,10 +20,14 @@ module RailsPulse
20
20
  def setup_metric_cards
21
21
  return if turbo_frame_request?
22
22
 
23
- @average_query_times_metric_card = RailsPulse::Routes::Cards::AverageResponseTimes.new(route: @route).to_metric_card
24
- @percentile_response_times_metric_card = RailsPulse::Routes::Cards::PercentileResponseTimes.new(route: @route).to_metric_card
25
- @request_count_totals_metric_card = RailsPulse::Routes::Cards::RequestCountTotals.new(route: @route).to_metric_card
26
- @error_rate_per_route_metric_card = RailsPulse::Routes::Cards::ErrorRatePerRoute.new(route: @route).to_metric_card
23
+ # Get tag filter values from session
24
+ disabled_tags = session_disabled_tags
25
+ show_non_tagged = session[:show_non_tagged] != false
26
+
27
+ @average_query_times_metric_card = RailsPulse::Routes::Cards::AverageResponseTimes.new(route: @route, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
28
+ @percentile_response_times_metric_card = RailsPulse::Routes::Cards::PercentileResponseTimes.new(route: @route, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
29
+ @request_count_totals_metric_card = RailsPulse::Routes::Cards::RequestCountTotals.new(route: @route, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
30
+ @error_rate_per_route_metric_card = RailsPulse::Routes::Cards::ErrorRatePerRoute.new(route: @route, disabled_tags: disabled_tags, show_non_tagged: show_non_tagged).to_metric_card
27
31
  end
28
32
 
29
33
  def chart_model
@@ -87,7 +91,9 @@ module RailsPulse
87
91
  if show_action?
88
92
  # Only show requests that belong to time periods where we have route summaries
89
93
  # This ensures the table data is consistent with the chart data
90
- base_query = apply_tag_filters(@ransack_query.result)
94
+ # Note: We don't apply tag filters here because we want to show all requests
95
+ # for this specific route, regardless of individual request tags
96
+ base_query = @ransack_query.result
91
97
  .joins(<<~SQL)
92
98
  INNER JOIN rails_pulse_summaries ON
93
99
  rails_pulse_summaries.summarizable_id = rails_pulse_requests.route_id AND
@@ -110,7 +116,8 @@ module RailsPulse
110
116
  period_type: period_type,
111
117
  start_time: @start_time,
112
118
  params: params,
113
- disabled_tags: session_disabled_tags
119
+ disabled_tags: session_disabled_tags,
120
+ show_non_tagged: session[:show_non_tagged] != false
114
121
  ).to_table
115
122
  end
116
123
  end
@@ -0,0 +1,63 @@
1
+ module RailsPulse
2
+ module Taggable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ # Callbacks
7
+ before_save :ensure_tags_is_array
8
+
9
+ # Scopes with table name qualification to avoid ambiguity
10
+ scope :with_tag, ->(tag) { where("#{table_name}.tags LIKE ?", "%#{tag}%") }
11
+ scope :without_tag, ->(tag) { where.not("#{table_name}.tags LIKE ?", "%#{tag}%") }
12
+ scope :with_tags, -> { where("#{table_name}.tags IS NOT NULL AND #{table_name}.tags != '[]'") }
13
+ end
14
+
15
+ # Tag management methods
16
+ def tag_list
17
+ parsed_tags || []
18
+ end
19
+
20
+ def tag_list=(value)
21
+ self.tags = value.to_json
22
+ end
23
+
24
+ def has_tag?(tag)
25
+ tag_list.include?(tag.to_s)
26
+ end
27
+
28
+ def add_tag(tag)
29
+ current_tags = tag_list
30
+ unless current_tags.include?(tag.to_s)
31
+ current_tags << tag.to_s
32
+ self.tag_list = current_tags
33
+ save
34
+ end
35
+ end
36
+
37
+ def remove_tag(tag)
38
+ current_tags = tag_list
39
+ if current_tags.include?(tag.to_s)
40
+ current_tags.delete(tag.to_s)
41
+ self.tag_list = current_tags
42
+ save
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ def parsed_tags
49
+ return [] if tags.nil? || tags.empty?
50
+ JSON.parse(tags)
51
+ rescue JSON::ParserError
52
+ []
53
+ end
54
+
55
+ def ensure_tags_is_array
56
+ if tags.nil?
57
+ self.tags = "[]"
58
+ elsif tags.is_a?(Array)
59
+ self.tags = tags.to_json
60
+ end
61
+ end
62
+ end
63
+ end
@@ -2,6 +2,11 @@ module RailsPulse
2
2
  module Dashboard
3
3
  module Charts
4
4
  class AverageResponseTime
5
+ def initialize(disabled_tags: [], show_non_tagged: true)
6
+ @disabled_tags = disabled_tags
7
+ @show_non_tagged = show_non_tagged
8
+ end
9
+
5
10
  def to_chart_data
6
11
  # Create a range of all dates in the past 2 weeks
7
12
  start_date = 2.weeks.ago.beginning_of_day.to_date
@@ -9,11 +14,13 @@ module RailsPulse
9
14
  date_range = (start_date..end_date)
10
15
 
11
16
  # Get the actual data from Summary records (routes)
12
- summaries = RailsPulse::Summary.where(
13
- summarizable_type: "RailsPulse::Route",
14
- period_type: "day",
15
- period_start: start_date.beginning_of_day..end_date.end_of_day
16
- )
17
+ summaries = RailsPulse::Summary
18
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
19
+ .where(
20
+ summarizable_type: "RailsPulse::Route",
21
+ period_type: "day",
22
+ period_start: start_date.beginning_of_day..end_date.end_of_day
23
+ )
17
24
 
18
25
  # Group by day manually for cross-database compatibility
19
26
  actual_data = {}
@@ -2,6 +2,11 @@ module RailsPulse
2
2
  module Dashboard
3
3
  module Charts
4
4
  class P95ResponseTime
5
+ def initialize(disabled_tags: [], show_non_tagged: true)
6
+ @disabled_tags = disabled_tags
7
+ @show_non_tagged = show_non_tagged
8
+ end
9
+
5
10
  def to_chart_data
6
11
  # Create a range of all dates in the past 2 weeks
7
12
  start_date = 2.weeks.ago.beginning_of_day.to_date
@@ -9,11 +14,13 @@ module RailsPulse
9
14
  date_range = (start_date..end_date)
10
15
 
11
16
  # Get the actual data from Summary records (queries for P95)
12
- summaries = RailsPulse::Summary.where(
13
- summarizable_type: "RailsPulse::Query",
14
- period_type: "day",
15
- period_start: start_date.beginning_of_day..end_date.end_of_day
16
- )
17
+ summaries = RailsPulse::Summary
18
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
19
+ .where(
20
+ summarizable_type: "RailsPulse::Query",
21
+ period_type: "day",
22
+ period_start: start_date.beginning_of_day..end_date.end_of_day
23
+ )
17
24
 
18
25
  actual_data = summaries
19
26
  .group_by_day(:period_start, time_zone: Time.zone)
@@ -3,6 +3,12 @@ module RailsPulse
3
3
  module Tables
4
4
  class SlowQueries
5
5
  include RailsPulse::FormattingHelper
6
+
7
+ def initialize(disabled_tags: [], show_non_tagged: true)
8
+ @disabled_tags = disabled_tags
9
+ @show_non_tagged = show_non_tagged
10
+ end
11
+
6
12
  def to_table_data
7
13
  # Get data for this week
8
14
  this_week_start = 1.week.ago.beginning_of_week
@@ -10,6 +16,7 @@ module RailsPulse
10
16
 
11
17
  # Fetch query data from Summary records for this week
12
18
  query_data = RailsPulse::Summary
19
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
13
20
  .joins("INNER JOIN rails_pulse_queries ON rails_pulse_queries.id = rails_pulse_summaries.summarizable_id")
14
21
  .where(
15
22
  summarizable_type: "RailsPulse::Query",
@@ -4,6 +4,11 @@ module RailsPulse
4
4
  class SlowRoutes
5
5
  include RailsPulse::FormattingHelper
6
6
 
7
+ def initialize(disabled_tags: [], show_non_tagged: true)
8
+ @disabled_tags = disabled_tags
9
+ @show_non_tagged = show_non_tagged
10
+ end
11
+
7
12
  def to_table_data
8
13
  # Get data for this week
9
14
  this_week_start = 1.week.ago.beginning_of_week
@@ -11,6 +16,7 @@ module RailsPulse
11
16
 
12
17
  # Fetch route data from Summary records for this week
13
18
  route_data = RailsPulse::Summary
19
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
14
20
  .joins("INNER JOIN rails_pulse_routes ON rails_pulse_routes.id = rails_pulse_summaries.summarizable_id")
15
21
  .where(
16
22
  summarizable_type: "RailsPulse::Route",
@@ -2,8 +2,10 @@ module RailsPulse
2
2
  module Queries
3
3
  module Cards
4
4
  class AverageQueryTimes
5
- def initialize(query: nil)
5
+ def initialize(query: nil, disabled_tags: [], show_non_tagged: true)
6
6
  @query = query
7
+ @disabled_tags = disabled_tags
8
+ @show_non_tagged = show_non_tagged
7
9
  end
8
10
 
9
11
  def to_metric_card
@@ -11,11 +13,13 @@ module RailsPulse
11
13
  previous_7_days = 14.days.ago.beginning_of_day
12
14
 
13
15
  # Single query to get all aggregated metrics with conditional sums
14
- base_query = RailsPulse::Summary.where(
15
- summarizable_type: "RailsPulse::Query",
16
- period_type: "day",
17
- period_start: 2.weeks.ago.beginning_of_day..Time.current
18
- )
16
+ base_query = RailsPulse::Summary
17
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
18
+ .where(
19
+ summarizable_type: "RailsPulse::Query",
20
+ period_type: "day",
21
+ period_start: 2.weeks.ago.beginning_of_day..Time.current
22
+ )
19
23
  base_query = base_query.where(summarizable_id: @query.id) if @query
20
24
 
21
25
  metrics = base_query.select(
@@ -2,8 +2,10 @@ module RailsPulse
2
2
  module Queries
3
3
  module Cards
4
4
  class ExecutionRate
5
- def initialize(query: nil)
5
+ def initialize(query: nil, disabled_tags: [], show_non_tagged: true)
6
6
  @query = query
7
+ @disabled_tags = disabled_tags
8
+ @show_non_tagged = show_non_tagged
7
9
  end
8
10
 
9
11
  def to_metric_card
@@ -12,20 +14,24 @@ module RailsPulse
12
14
 
13
15
  # Get the most common period type for this query, or fall back to "day"
14
16
  period_type = if @query
15
- RailsPulse::Summary.where(
16
- summarizable_type: "RailsPulse::Query",
17
- summarizable_id: @query.id
18
- ).group(:period_type).count.max_by(&:last)&.first || "day"
17
+ RailsPulse::Summary
18
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
19
+ .where(
20
+ summarizable_type: "RailsPulse::Query",
21
+ summarizable_id: @query.id
22
+ ).group(:period_type).count.max_by(&:last)&.first || "day"
19
23
  else
20
24
  "day"
21
25
  end
22
26
 
23
27
  # Single query to get all count metrics with conditional aggregation
24
- base_query = RailsPulse::Summary.where(
25
- summarizable_type: "RailsPulse::Query",
26
- period_type: period_type,
27
- period_start: 2.weeks.ago.beginning_of_day..Time.current
28
- )
28
+ base_query = RailsPulse::Summary
29
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
30
+ .where(
31
+ summarizable_type: "RailsPulse::Query",
32
+ period_type: period_type,
33
+ period_start: 2.weeks.ago.beginning_of_day..Time.current
34
+ )
29
35
  base_query = base_query.where(summarizable_id: @query.id) if @query
30
36
 
31
37
  metrics = base_query.select(
@@ -2,8 +2,10 @@ module RailsPulse
2
2
  module Queries
3
3
  module Cards
4
4
  class PercentileQueryTimes
5
- def initialize(query: nil)
5
+ def initialize(query: nil, disabled_tags: [], show_non_tagged: true)
6
6
  @query = query
7
+ @disabled_tags = disabled_tags
8
+ @show_non_tagged = show_non_tagged
7
9
  end
8
10
 
9
11
  def to_metric_card
@@ -11,11 +13,13 @@ module RailsPulse
11
13
  previous_7_days = 14.days.ago.beginning_of_day
12
14
 
13
15
  # Single query to get all P95 metrics with conditional aggregation
14
- base_query = RailsPulse::Summary.where(
15
- summarizable_type: "RailsPulse::Query",
16
- period_type: "day",
17
- period_start: 2.weeks.ago.beginning_of_day..Time.current
18
- )
16
+ base_query = RailsPulse::Summary
17
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
18
+ .where(
19
+ summarizable_type: "RailsPulse::Query",
20
+ period_type: "day",
21
+ period_start: 2.weeks.ago.beginning_of_day..Time.current
22
+ )
19
23
  base_query = base_query.where(summarizable_id: @query.id) if @query
20
24
 
21
25
  metrics = base_query.select(
@@ -2,18 +2,21 @@ module RailsPulse
2
2
  module Queries
3
3
  module Charts
4
4
  class AverageQueryTimes
5
- def initialize(ransack_query:, period_type: nil, query: nil, start_time: nil, end_time: nil, start_duration: nil)
5
+ def initialize(ransack_query:, period_type: nil, query: nil, start_time: nil, end_time: nil, start_duration: nil, disabled_tags: [], show_non_tagged: true)
6
6
  @ransack_query = ransack_query
7
7
  @period_type = period_type
8
8
  @query = query
9
9
  @start_time = start_time
10
10
  @end_time = end_time
11
11
  @start_duration = start_duration
12
+ @disabled_tags = disabled_tags
13
+ @show_non_tagged = show_non_tagged
12
14
  end
13
15
 
14
16
  def to_rails_chart
15
- # The ransack query already contains the correct filters, just add period_type
17
+ # The ransack query already contains the correct filters, just add period_type and tag filters
16
18
  summaries = @ransack_query.result(distinct: false)
19
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
17
20
  .where(period_type: @period_type)
18
21
  .group(:period_start)
19
22
  .having("AVG(avg_duration) > ?", @start_duration || 0)
@@ -2,13 +2,14 @@ module RailsPulse
2
2
  module Queries
3
3
  module Tables
4
4
  class Index
5
- def initialize(ransack_query:, period_type: nil, start_time:, params:, query: nil, disabled_tags: [])
5
+ def initialize(ransack_query:, period_type: nil, start_time:, params:, query: nil, disabled_tags: [], show_non_tagged: true)
6
6
  @ransack_query = ransack_query
7
7
  @period_type = period_type
8
8
  @start_time = start_time
9
9
  @params = params
10
10
  @query = query
11
11
  @disabled_tags = disabled_tags
12
+ @show_non_tagged = show_non_tagged
12
13
  end
13
14
 
14
15
  def to_table
@@ -23,10 +24,19 @@ module RailsPulse
23
24
  )
24
25
 
25
26
  # Apply tag filters by excluding queries with disabled tags
26
- @disabled_tags.each do |tag|
27
+ # Separate "non_tagged" from actual tags (it's a virtual tag)
28
+ actual_disabled_tags = @disabled_tags.reject { |tag| tag == "non_tagged" }
29
+
30
+ # Exclude queries with actual disabled tags
31
+ actual_disabled_tags.each do |tag|
27
32
  base_query = base_query.where.not("rails_pulse_queries.tags LIKE ?", "%#{tag}%")
28
33
  end
29
34
 
35
+ # Exclude non-tagged queries if show_non_tagged is false
36
+ unless @show_non_tagged
37
+ base_query = base_query.where("rails_pulse_queries.tags IS NOT NULL AND rails_pulse_queries.tags != '[]'")
38
+ end
39
+
30
40
  base_query = base_query.where(summarizable_id: @query.id) if @query
31
41
 
32
42
  # Apply grouping and aggregation
@@ -2,21 +2,27 @@ module RailsPulse
2
2
  module Requests
3
3
  module Charts
4
4
  class AverageResponseTimes
5
- def initialize(ransack_query:, period_type: nil, route: nil, start_time: nil, end_time: nil, start_duration: nil)
5
+ def initialize(ransack_query:, period_type: nil, route: nil, start_time: nil, end_time: nil, start_duration: nil, disabled_tags: [], show_non_tagged: true)
6
6
  @ransack_query = ransack_query
7
7
  @period_type = period_type
8
8
  @route = route
9
9
  @start_time = start_time
10
10
  @end_time = end_time
11
11
  @start_duration = start_duration
12
+ @disabled_tags = disabled_tags
13
+ @show_non_tagged = show_non_tagged
12
14
  end
13
15
 
14
16
  def to_rails_chart
15
- summaries = @ransack_query.result(distinct: false).where(
16
- summarizable_type: "RailsPulse::Request",
17
- summarizable_id: 0, # Overall request summaries
18
- period_type: @period_type
19
- )
17
+ # Note: Overall request summaries (summarizable_id: 0) are not filtered by tags
18
+ # as they aggregate all requests regardless of route tags
19
+ summaries = @ransack_query.result(distinct: false)
20
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
21
+ .where(
22
+ summarizable_type: "RailsPulse::Request",
23
+ summarizable_id: 0, # Overall request summaries
24
+ period_type: @period_type
25
+ )
20
26
 
21
27
  summaries = summaries
22
28
  .group(:period_start)
@@ -2,8 +2,10 @@ module RailsPulse
2
2
  module Routes
3
3
  module Cards
4
4
  class AverageResponseTimes
5
- def initialize(route:)
5
+ def initialize(route:, disabled_tags: [], show_non_tagged: true)
6
6
  @route = route
7
+ @disabled_tags = disabled_tags
8
+ @show_non_tagged = show_non_tagged
7
9
  end
8
10
 
9
11
  def to_metric_card
@@ -11,11 +13,13 @@ module RailsPulse
11
13
  previous_7_days = 14.days.ago.beginning_of_day
12
14
 
13
15
  # Single query to get all aggregated metrics with conditional sums
14
- base_query = RailsPulse::Summary.where(
15
- summarizable_type: "RailsPulse::Route",
16
- period_type: "day",
17
- period_start: 2.weeks.ago.beginning_of_day..Time.current
18
- )
16
+ base_query = RailsPulse::Summary
17
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
18
+ .where(
19
+ summarizable_type: "RailsPulse::Route",
20
+ period_type: "day",
21
+ period_start: 2.weeks.ago.beginning_of_day..Time.current
22
+ )
19
23
  base_query = base_query.where(summarizable_id: @route.id) if @route
20
24
 
21
25
  metrics = base_query.select(
@@ -2,8 +2,10 @@ module RailsPulse
2
2
  module Routes
3
3
  module Cards
4
4
  class ErrorRatePerRoute
5
- def initialize(route: nil)
5
+ def initialize(route: nil, disabled_tags: [], show_non_tagged: true)
6
6
  @route = route
7
+ @disabled_tags = disabled_tags
8
+ @show_non_tagged = show_non_tagged
7
9
  end
8
10
 
9
11
  def to_metric_card
@@ -11,11 +13,13 @@ module RailsPulse
11
13
  previous_7_days = 14.days.ago.beginning_of_day
12
14
 
13
15
  # Single query to get all error metrics with conditional aggregation
14
- base_query = RailsPulse::Summary.where(
15
- summarizable_type: "RailsPulse::Route",
16
- period_type: "day",
17
- period_start: 2.weeks.ago.beginning_of_day..Time.current
18
- )
16
+ base_query = RailsPulse::Summary
17
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
18
+ .where(
19
+ summarizable_type: "RailsPulse::Route",
20
+ period_type: "day",
21
+ period_start: 2.weeks.ago.beginning_of_day..Time.current
22
+ )
19
23
  base_query = base_query.where(summarizable_id: @route.id) if @route
20
24
 
21
25
  metrics = base_query.select(
@@ -2,8 +2,10 @@ module RailsPulse
2
2
  module Routes
3
3
  module Cards
4
4
  class PercentileResponseTimes
5
- def initialize(route: nil)
5
+ def initialize(route: nil, disabled_tags: [], show_non_tagged: true)
6
6
  @route = route
7
+ @disabled_tags = disabled_tags
8
+ @show_non_tagged = show_non_tagged
7
9
  end
8
10
 
9
11
  def to_metric_card
@@ -11,11 +13,13 @@ module RailsPulse
11
13
  previous_7_days = 14.days.ago.beginning_of_day
12
14
 
13
15
  # Single query to get all P95 metrics with conditional aggregation
14
- base_query = RailsPulse::Summary.where(
15
- summarizable_type: "RailsPulse::Route",
16
- period_type: "day",
17
- period_start: 2.weeks.ago.beginning_of_day..Time.current
18
- )
16
+ base_query = RailsPulse::Summary
17
+ .with_tag_filters(@disabled_tags, @show_non_tagged)
18
+ .where(
19
+ summarizable_type: "RailsPulse::Route",
20
+ period_type: "day",
21
+ period_start: 2.weeks.ago.beginning_of_day..Time.current
22
+ )
19
23
  base_query = base_query.where(summarizable_id: @route.id) if @route
20
24
 
21
25
  metrics = base_query.select(