rails_error_dashboard 0.1.22 → 0.1.24
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.
- checksums.yaml +4 -4
- data/app/controllers/rails_error_dashboard/errors_controller.rb +18 -18
- data/app/helpers/rails_error_dashboard/application_helper.rb +11 -2
- data/app/models/rails_error_dashboard/application.rb +26 -3
- data/app/models/rails_error_dashboard/error_logs_record.rb +9 -10
- data/app/views/layouts/rails_error_dashboard.html.erb +6 -2
- data/app/views/rails_error_dashboard/errors/index.html.erb +1 -1
- data/db/migrate/20260106094233_add_application_to_error_logs.rb +2 -2
- data/lib/generators/rails_error_dashboard/install/install_generator.rb +10 -1
- data/lib/generators/rails_error_dashboard/install/templates/initializer.rb +6 -0
- data/lib/rails_error_dashboard/commands/log_error.rb +3 -3
- data/lib/rails_error_dashboard/engine.rb +14 -0
- data/lib/rails_error_dashboard/version.rb +1 -1
- data/lib/tasks/error_dashboard.rake +23 -23
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3ca536416dd8806b35ae7b3bda7aaad734d7d12f9af382db58db91ac8cfa3d3e
|
|
4
|
+
data.tar.gz: c015a441f1aea077f1cd742f008d1a5cc08749247e6e00714994a421c4a32e98
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2f7e9246fd8327c6f6a7109e6c283cc42ae4eeaa85125b0eddf96f53128d7560acefac4303b2367d7d82fb07287ac05907f8929a58644bf41768702dc6120951
|
|
7
|
+
data.tar.gz: 6b952f9198afcfeb7d40b44a118d29303eb8bac87cc52ca0635c394c111b05ce94f877f56cb498b87c036519b90a0a692dc03b3aab155c1265588be8c72eca50
|
|
@@ -6,6 +6,23 @@ module RailsErrorDashboard
|
|
|
6
6
|
|
|
7
7
|
before_action :authenticate_dashboard_user!
|
|
8
8
|
|
|
9
|
+
FILTERABLE_PARAMS = %i[
|
|
10
|
+
error_type
|
|
11
|
+
unresolved
|
|
12
|
+
platform
|
|
13
|
+
application_id
|
|
14
|
+
search
|
|
15
|
+
severity
|
|
16
|
+
timeframe
|
|
17
|
+
frequency
|
|
18
|
+
status
|
|
19
|
+
assigned_to
|
|
20
|
+
priority_level
|
|
21
|
+
hide_snoozed
|
|
22
|
+
sort_by
|
|
23
|
+
sort_direction
|
|
24
|
+
].freeze
|
|
25
|
+
|
|
9
26
|
def overview
|
|
10
27
|
# Get dashboard stats using Query
|
|
11
28
|
@stats = Queries::DashboardStats.call
|
|
@@ -266,24 +283,7 @@ module RailsErrorDashboard
|
|
|
266
283
|
end
|
|
267
284
|
|
|
268
285
|
def filter_params
|
|
269
|
-
|
|
270
|
-
error_type: params[:error_type],
|
|
271
|
-
unresolved: params[:unresolved],
|
|
272
|
-
platform: params[:platform],
|
|
273
|
-
application_id: params[:application_id],
|
|
274
|
-
search: params[:search],
|
|
275
|
-
severity: params[:severity],
|
|
276
|
-
timeframe: params[:timeframe],
|
|
277
|
-
frequency: params[:frequency],
|
|
278
|
-
# Phase 3: Workflow filter params
|
|
279
|
-
status: params[:status],
|
|
280
|
-
assigned_to: params[:assigned_to],
|
|
281
|
-
priority_level: params[:priority_level],
|
|
282
|
-
hide_snoozed: params[:hide_snoozed],
|
|
283
|
-
# Sorting params
|
|
284
|
-
sort_by: params[:sort_by],
|
|
285
|
-
sort_direction: params[:sort_direction]
|
|
286
|
-
}
|
|
286
|
+
params.permit(*FILTERABLE_PARAMS).to_h.symbolize_keys
|
|
287
287
|
end
|
|
288
288
|
|
|
289
289
|
def authenticate_dashboard_user!
|
|
@@ -81,6 +81,15 @@ module RailsErrorDashboard
|
|
|
81
81
|
RailsErrorDashboard.configuration.dashboard_username || ENV["USER"] || "unknown"
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
+
# Returns a sanitized hash of filter params safe for query links
|
|
85
|
+
# @param extra_keys [Array<Symbol>] Additional permitted keys for specific contexts
|
|
86
|
+
# @return [Hash] Whitelisted params for building URLs
|
|
87
|
+
def permitted_filter_params(extra_keys: [])
|
|
88
|
+
base_keys = RailsErrorDashboard::ErrorsController::FILTERABLE_PARAMS + %i[page per_page days]
|
|
89
|
+
allowed_keys = base_keys + Array(extra_keys)
|
|
90
|
+
params.permit(*allowed_keys).to_h.symbolize_keys
|
|
91
|
+
end
|
|
92
|
+
|
|
84
93
|
# Generates a sortable column header link
|
|
85
94
|
# @param label [String] The column label to display
|
|
86
95
|
# @param column [String] The column name to sort by
|
|
@@ -103,8 +112,8 @@ module RailsErrorDashboard
|
|
|
103
112
|
"⇅" # Unsorted indicator
|
|
104
113
|
end
|
|
105
114
|
|
|
106
|
-
# Preserve
|
|
107
|
-
link_params =
|
|
115
|
+
# Preserve whitelisted filter params while adding sort params
|
|
116
|
+
link_params = permitted_filter_params.merge(sort_by: column, sort_direction: new_direction)
|
|
108
117
|
|
|
109
118
|
link_to errors_path(link_params), class: "text-decoration-none" do
|
|
110
119
|
content_tag(:span, "#{label} ", class: current_sort == column ? "fw-bold" : "") +
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module RailsErrorDashboard
|
|
2
2
|
class Application < ActiveRecord::Base
|
|
3
|
-
self.table_name =
|
|
3
|
+
self.table_name = "rails_error_dashboard_applications"
|
|
4
4
|
|
|
5
5
|
# Associations
|
|
6
6
|
has_many :error_logs, dependent: :restrict_with_error
|
|
@@ -12,10 +12,33 @@ module RailsErrorDashboard
|
|
|
12
12
|
scope :ordered_by_name, -> { order(:name) }
|
|
13
13
|
|
|
14
14
|
# Class method for finding or creating with caching
|
|
15
|
+
# Caches application IDs (not objects) to avoid stale ActiveRecord references
|
|
16
|
+
# This is safer with transactional fixtures and database rollbacks
|
|
15
17
|
def self.find_or_create_by_name(name)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
# Try to find ID in cache
|
|
19
|
+
cached_id = Rails.cache.read("error_dashboard/application_id/#{name}")
|
|
20
|
+
if cached_id
|
|
21
|
+
# Verify the cached ID still exists in database
|
|
22
|
+
# (could have been deleted in tests with transactional rollback)
|
|
23
|
+
cached_record = find_by(id: cached_id)
|
|
24
|
+
return cached_record if cached_record
|
|
25
|
+
# Cache was stale, clear it
|
|
26
|
+
Rails.cache.delete("error_dashboard/application_id/#{name}")
|
|
18
27
|
end
|
|
28
|
+
|
|
29
|
+
# Try to find existing in database
|
|
30
|
+
found = find_by(name: name)
|
|
31
|
+
if found
|
|
32
|
+
# Cache the ID (not the object) for future lookups
|
|
33
|
+
Rails.cache.write("error_dashboard/application_id/#{name}", found.id, expires_in: 1.hour)
|
|
34
|
+
return found
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Create if not found
|
|
38
|
+
created = create!(name: name)
|
|
39
|
+
# Cache the ID (not the object)
|
|
40
|
+
Rails.cache.write("error_dashboard/application_id/#{name}", created.id, expires_in: 1.hour)
|
|
41
|
+
created
|
|
19
42
|
end
|
|
20
43
|
|
|
21
44
|
# Instance methods
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Abstract base class for models stored in the
|
|
3
|
+
# Abstract base class for models stored in the error dashboard database
|
|
4
4
|
#
|
|
5
5
|
# By default, this connects to the same database as the main application.
|
|
6
6
|
#
|
|
7
|
-
# To enable a separate error
|
|
7
|
+
# To enable a separate error dashboard database:
|
|
8
8
|
# 1. Set use_separate_database: true in the gem configuration
|
|
9
|
-
# 2.
|
|
10
|
-
# 3.
|
|
11
|
-
# 4. Run: rails db:
|
|
9
|
+
# 2. Set database: :error_dashboard (or your custom name) in the gem configuration
|
|
10
|
+
# 3. Configure error_dashboard settings in config/database.yml
|
|
11
|
+
# 4. Run: rails db:create
|
|
12
|
+
# 5. Run: rails db:migrate
|
|
12
13
|
#
|
|
13
14
|
# Benefits of separate database:
|
|
14
15
|
# - Performance isolation (error logging doesn't slow down user requests)
|
|
@@ -25,10 +26,8 @@ module RailsErrorDashboard
|
|
|
25
26
|
class ErrorLogsRecord < ActiveRecord::Base
|
|
26
27
|
self.abstract_class = true
|
|
27
28
|
|
|
28
|
-
#
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
connects_to database: { writing: :error_logs, reading: :error_logs }
|
|
32
|
-
end
|
|
29
|
+
# Database connection will be configured by the engine initializer
|
|
30
|
+
# after the user's configuration is loaded
|
|
31
|
+
# See lib/rails_error_dashboard/engine.rb
|
|
33
32
|
end
|
|
34
33
|
end
|
|
@@ -866,16 +866,20 @@
|
|
|
866
866
|
<% end %>
|
|
867
867
|
</button>
|
|
868
868
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="appSwitcher">
|
|
869
|
+
<%
|
|
870
|
+
base_route_params = request.path_parameters.slice(:controller, :action)
|
|
871
|
+
current_filter_params = permitted_filter_params
|
|
872
|
+
%>
|
|
869
873
|
<li>
|
|
870
874
|
<%= link_to "All Applications",
|
|
871
|
-
url_for(
|
|
875
|
+
url_for(base_route_params.merge(current_filter_params.except(:application_id))),
|
|
872
876
|
class: "dropdown-item #{'active' unless params[:application_id].present?}" %>
|
|
873
877
|
</li>
|
|
874
878
|
<li><hr class="dropdown-divider"></li>
|
|
875
879
|
<% @applications.each do |app_name, app_id| %>
|
|
876
880
|
<li>
|
|
877
881
|
<%= link_to app_name,
|
|
878
|
-
url_for(
|
|
882
|
+
url_for(base_route_params.merge(current_filter_params.merge(application_id: app_id))),
|
|
879
883
|
class: "dropdown-item #{params[:application_id].to_s == app_id.to_s ? 'active' : ''}" %>
|
|
880
884
|
</li>
|
|
881
885
|
<% end %>
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
<% active_filters.each do |filter| %>
|
|
159
159
|
<%
|
|
160
160
|
# Build URL without this specific filter
|
|
161
|
-
filter_params =
|
|
161
|
+
filter_params = permitted_filter_params.except(filter[:param])
|
|
162
162
|
%>
|
|
163
163
|
<%= link_to errors_path(filter_params), class: "badge bg-primary text-decoration-none filter-pill" do %>
|
|
164
164
|
<%= filter[:label] %>
|
|
@@ -7,11 +7,11 @@ class AddApplicationToErrorLogs < ActiveRecord::Migration[7.0]
|
|
|
7
7
|
add_index :rails_error_dashboard_error_logs, :application_id
|
|
8
8
|
|
|
9
9
|
add_index :rails_error_dashboard_error_logs,
|
|
10
|
-
[:application_id, :occurred_at],
|
|
10
|
+
[ :application_id, :occurred_at ],
|
|
11
11
|
name: 'index_error_logs_on_app_occurred'
|
|
12
12
|
|
|
13
13
|
add_index :rails_error_dashboard_error_logs,
|
|
14
|
-
[:application_id, :resolved],
|
|
14
|
+
[ :application_id, :resolved ],
|
|
15
15
|
name: 'index_error_logs_on_app_resolved'
|
|
16
16
|
end
|
|
17
17
|
|
|
@@ -18,6 +18,7 @@ module RailsErrorDashboard
|
|
|
18
18
|
class_option :async_logging, type: :boolean, default: false, desc: "Enable async error logging"
|
|
19
19
|
class_option :error_sampling, type: :boolean, default: false, desc: "Enable error sampling (reduce volume)"
|
|
20
20
|
class_option :separate_database, type: :boolean, default: false, desc: "Use separate database for errors"
|
|
21
|
+
class_option :database, type: :string, default: nil, desc: "Database name to use for errors (e.g., 'error_dashboard')"
|
|
21
22
|
# Advanced analytics options
|
|
22
23
|
class_option :baseline_alerts, type: :boolean, default: false, desc: "Enable baseline anomaly alerts"
|
|
23
24
|
class_option :similar_errors, type: :boolean, default: false, desc: "Enable fuzzy error matching"
|
|
@@ -185,6 +186,7 @@ module RailsErrorDashboard
|
|
|
185
186
|
@enable_async_logging = @selected_features&.dig(:async_logging) || options[:async_logging]
|
|
186
187
|
@enable_error_sampling = @selected_features&.dig(:error_sampling) || options[:error_sampling]
|
|
187
188
|
@enable_separate_database = @selected_features&.dig(:separate_database) || options[:separate_database]
|
|
189
|
+
@database_name = options[:database]
|
|
188
190
|
|
|
189
191
|
# Advanced Analytics
|
|
190
192
|
@enable_baseline_alerts = @selected_features&.dig(:baseline_alerts) || options[:baseline_alerts]
|
|
@@ -275,7 +277,14 @@ module RailsErrorDashboard
|
|
|
275
277
|
say " → Set PAGERDUTY_INTEGRATION_KEY in .env", :yellow if @enable_pagerduty
|
|
276
278
|
say " → Set WEBHOOK_URLS in .env", :yellow if @enable_webhooks
|
|
277
279
|
say " → Ensure Sidekiq/Solid Queue running", :yellow if @enable_async_logging
|
|
278
|
-
|
|
280
|
+
if @enable_separate_database
|
|
281
|
+
if @database_name
|
|
282
|
+
say " → Configure '#{@database_name}' database in database.yml", :yellow
|
|
283
|
+
else
|
|
284
|
+
say " → Configure database in database.yml and set config.database", :yellow
|
|
285
|
+
end
|
|
286
|
+
say " See docs/guides/DATABASE_OPTIONS.md for details", :yellow
|
|
287
|
+
end
|
|
279
288
|
|
|
280
289
|
say "\n"
|
|
281
290
|
say "Next Steps:", :cyan
|
|
@@ -153,6 +153,11 @@ RailsErrorDashboard.configure do |config|
|
|
|
153
153
|
# Errors will be stored in a dedicated database
|
|
154
154
|
# See docs/guides/DATABASE_OPTIONS.md for setup instructions
|
|
155
155
|
config.use_separate_database = true
|
|
156
|
+
<% if @database_name -%>
|
|
157
|
+
config.database = :<%= @database_name %>
|
|
158
|
+
<% else -%>
|
|
159
|
+
# config.database = :error_dashboard # Uncomment and set your database name
|
|
160
|
+
<% end -%>
|
|
156
161
|
# To disable: Set config.use_separate_database = false
|
|
157
162
|
|
|
158
163
|
<% else -%>
|
|
@@ -160,6 +165,7 @@ RailsErrorDashboard.configure do |config|
|
|
|
160
165
|
# Errors are stored in your main application database
|
|
161
166
|
# To enable: Set config.use_separate_database = true and configure database.yml
|
|
162
167
|
config.use_separate_database = false
|
|
168
|
+
# config.database = :error_dashboard # Database name when using separate database
|
|
163
169
|
|
|
164
170
|
<% end -%>
|
|
165
171
|
# ============================================================================
|
|
@@ -143,15 +143,15 @@ module RailsErrorDashboard
|
|
|
143
143
|
# Find or create application for multi-app support
|
|
144
144
|
def find_or_create_application
|
|
145
145
|
app_name = RailsErrorDashboard.configuration.application_name ||
|
|
146
|
-
ENV[
|
|
146
|
+
ENV["APPLICATION_NAME"] ||
|
|
147
147
|
(defined?(Rails) && Rails.application.class.module_parent_name) ||
|
|
148
|
-
|
|
148
|
+
"Rails Application"
|
|
149
149
|
|
|
150
150
|
Application.find_or_create_by_name(app_name)
|
|
151
151
|
rescue => e
|
|
152
152
|
RailsErrorDashboard::Logger.error("[RailsErrorDashboard] Failed to find/create application: #{e.message}")
|
|
153
153
|
# Fallback: try to find any application or create default
|
|
154
|
-
Application.first || Application.create!(name:
|
|
154
|
+
Application.first || Application.create!(name: "Default Application")
|
|
155
155
|
end
|
|
156
156
|
|
|
157
157
|
# Trigger notification callbacks for error logging
|
|
@@ -2,6 +2,20 @@ module RailsErrorDashboard
|
|
|
2
2
|
class Engine < ::Rails::Engine
|
|
3
3
|
isolate_namespace RailsErrorDashboard
|
|
4
4
|
|
|
5
|
+
# Configure database connection for error models
|
|
6
|
+
# This runs early, before middleware setup, but after database.yml is loaded
|
|
7
|
+
initializer "rails_error_dashboard.database", before: :load_config_initializers do
|
|
8
|
+
config.after_initialize do
|
|
9
|
+
if RailsErrorDashboard.configuration&.use_separate_database
|
|
10
|
+
database_name = RailsErrorDashboard.configuration&.database || :error_dashboard
|
|
11
|
+
|
|
12
|
+
RailsErrorDashboard::ErrorLogsRecord.connects_to(
|
|
13
|
+
database: { writing: database_name, reading: database_name }
|
|
14
|
+
)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
5
19
|
# Initialize the engine
|
|
6
20
|
initializer "rails_error_dashboard.middleware" do |app|
|
|
7
21
|
# Enable Flash middleware for Error Dashboard routes in API-only apps
|
|
@@ -10,11 +10,11 @@ namespace :error_dashboard do
|
|
|
10
10
|
# Use single SQL query with aggregates to avoid N+1 queries
|
|
11
11
|
# This fetches all app data + error counts in one query instead of 6N queries
|
|
12
12
|
apps = RailsErrorDashboard::Application
|
|
13
|
-
.select(
|
|
14
|
-
.select(
|
|
15
|
-
.select(
|
|
16
|
-
.joins(
|
|
17
|
-
.group(
|
|
13
|
+
.select("rails_error_dashboard_applications.*")
|
|
14
|
+
.select("COUNT(rails_error_dashboard_error_logs.id) as total_errors")
|
|
15
|
+
.select("COALESCE(SUM(CASE WHEN NOT rails_error_dashboard_error_logs.resolved THEN 1 ELSE 0 END), 0) as unresolved_errors")
|
|
16
|
+
.joins("LEFT JOIN rails_error_dashboard_error_logs ON rails_error_dashboard_error_logs.application_id = rails_error_dashboard_applications.id")
|
|
17
|
+
.group("rails_error_dashboard_applications.id")
|
|
18
18
|
.order(:name)
|
|
19
19
|
|
|
20
20
|
if apps.empty?
|
|
@@ -27,9 +27,9 @@ namespace :error_dashboard do
|
|
|
27
27
|
puts "\n#{apps.count} application(s) registered:\n\n"
|
|
28
28
|
|
|
29
29
|
# Calculate column widths using aggregated data (no additional queries)
|
|
30
|
-
name_width = [apps.map(&:name).map(&:length).max, 20].max
|
|
31
|
-
total_width = [apps.map(&:total_errors).map(&:to_s).map(&:length).max, 5].max
|
|
32
|
-
unresolved_width = [apps.map(&:unresolved_errors).map(&:to_s).map(&:length).max, 10].max
|
|
30
|
+
name_width = [ apps.map(&:name).map(&:length).max, 20 ].max
|
|
31
|
+
total_width = [ apps.map(&:total_errors).map(&:to_s).map(&:length).max, 5 ].max
|
|
32
|
+
unresolved_width = [ apps.map(&:unresolved_errors).map(&:to_s).map(&:length).max, 10 ].max
|
|
33
33
|
|
|
34
34
|
# Print header
|
|
35
35
|
printf "%-#{name_width}s %#{total_width}s %#{unresolved_width}s %s\n",
|
|
@@ -62,9 +62,9 @@ namespace :error_dashboard do
|
|
|
62
62
|
|
|
63
63
|
desc "Backfill application_id for existing errors"
|
|
64
64
|
task backfill_application: :environment do
|
|
65
|
-
app_name = ENV[
|
|
65
|
+
app_name = ENV["APP_NAME"] || ENV["APPLICATION_NAME"] ||
|
|
66
66
|
(defined?(Rails) && Rails.application.class.module_parent_name) ||
|
|
67
|
-
|
|
67
|
+
"Legacy Application"
|
|
68
68
|
|
|
69
69
|
puts "\n" + "=" * 80
|
|
70
70
|
puts "RAILS ERROR DASHBOARD - BACKFILL APPLICATION"
|
|
@@ -94,7 +94,7 @@ namespace :error_dashboard do
|
|
|
94
94
|
print "\nProceed with backfill? (y/N): "
|
|
95
95
|
confirmation = $stdin.gets.chomp.downcase
|
|
96
96
|
|
|
97
|
-
unless confirmation ==
|
|
97
|
+
unless confirmation == "y" || confirmation == "yes"
|
|
98
98
|
puts "\n✗ Backfill cancelled"
|
|
99
99
|
puts "\n" + "=" * 80 + "\n"
|
|
100
100
|
next
|
|
@@ -125,8 +125,8 @@ namespace :error_dashboard do
|
|
|
125
125
|
|
|
126
126
|
desc "Show application statistics and health metrics"
|
|
127
127
|
task app_stats: :environment do
|
|
128
|
-
app_id = ENV[
|
|
129
|
-
app_name = ENV[
|
|
128
|
+
app_id = ENV["APP_ID"]
|
|
129
|
+
app_name = ENV["APP_NAME"]
|
|
130
130
|
|
|
131
131
|
puts "\n" + "=" * 80
|
|
132
132
|
puts "RAILS ERROR DASHBOARD - APPLICATION STATISTICS"
|
|
@@ -135,16 +135,16 @@ namespace :error_dashboard do
|
|
|
135
135
|
# Find application
|
|
136
136
|
app = if app_id
|
|
137
137
|
RailsErrorDashboard::Application.find_by(id: app_id)
|
|
138
|
-
|
|
138
|
+
elsif app_name
|
|
139
139
|
RailsErrorDashboard::Application.find_by(name: app_name)
|
|
140
|
-
|
|
140
|
+
else
|
|
141
141
|
puts "\n✗ Please specify APP_ID or APP_NAME"
|
|
142
142
|
puts "\nExamples:"
|
|
143
143
|
puts " rails error_dashboard:app_stats APP_NAME='My App'"
|
|
144
144
|
puts " rails error_dashboard:app_stats APP_ID=1"
|
|
145
145
|
puts "\n" + "=" * 80 + "\n"
|
|
146
146
|
next
|
|
147
|
-
|
|
147
|
+
end
|
|
148
148
|
|
|
149
149
|
unless app
|
|
150
150
|
puts "\n✗ Application not found"
|
|
@@ -202,11 +202,11 @@ namespace :error_dashboard do
|
|
|
202
202
|
time_ago = Time.current - error.occurred_at
|
|
203
203
|
time_str = if time_ago < 3600
|
|
204
204
|
"#{(time_ago / 60).to_i}m ago"
|
|
205
|
-
|
|
205
|
+
elsif time_ago < 86400
|
|
206
206
|
"#{(time_ago / 3600).to_i}h ago"
|
|
207
|
-
|
|
207
|
+
else
|
|
208
208
|
"#{(time_ago / 86400).to_i}d ago"
|
|
209
|
-
|
|
209
|
+
end
|
|
210
210
|
puts " • #{error.error_type} (#{time_str}) - #{error.message.truncate(50)}"
|
|
211
211
|
end
|
|
212
212
|
end
|
|
@@ -216,8 +216,8 @@ namespace :error_dashboard do
|
|
|
216
216
|
|
|
217
217
|
desc "Clean up old resolved errors"
|
|
218
218
|
task cleanup_resolved: :environment do
|
|
219
|
-
days = ENV[
|
|
220
|
-
app_name = ENV[
|
|
219
|
+
days = ENV["DAYS"]&.to_i || 90
|
|
220
|
+
app_name = ENV["APP_NAME"]
|
|
221
221
|
|
|
222
222
|
puts "\n" + "=" * 80
|
|
223
223
|
puts "RAILS ERROR DASHBOARD - CLEANUP RESOLVED ERRORS"
|
|
@@ -225,7 +225,7 @@ namespace :error_dashboard do
|
|
|
225
225
|
puts "\nCleaning up resolved errors older than #{days} days"
|
|
226
226
|
|
|
227
227
|
scope = RailsErrorDashboard::ErrorLog.resolved
|
|
228
|
-
.where(
|
|
228
|
+
.where("resolved_at < ?", days.days.ago)
|
|
229
229
|
|
|
230
230
|
if app_name
|
|
231
231
|
app = RailsErrorDashboard::Application.find_by(name: app_name)
|
|
@@ -252,7 +252,7 @@ namespace :error_dashboard do
|
|
|
252
252
|
print "\nProceed with deletion? (y/N): "
|
|
253
253
|
confirmation = $stdin.gets.chomp.downcase
|
|
254
254
|
|
|
255
|
-
unless confirmation ==
|
|
255
|
+
unless confirmation == "y" || confirmation == "yes"
|
|
256
256
|
puts "\n✗ Cleanup cancelled"
|
|
257
257
|
puts "\n" + "=" * 80 + "\n"
|
|
258
258
|
next
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails_error_dashboard
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.24
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anjan Jagirdar
|
|
@@ -83,16 +83,16 @@ dependencies:
|
|
|
83
83
|
name: httparty
|
|
84
84
|
requirement: !ruby/object:Gem::Requirement
|
|
85
85
|
requirements:
|
|
86
|
-
- - "
|
|
86
|
+
- - ">="
|
|
87
87
|
- !ruby/object:Gem::Version
|
|
88
|
-
version:
|
|
88
|
+
version: 0.24.0
|
|
89
89
|
type: :runtime
|
|
90
90
|
prerelease: false
|
|
91
91
|
version_requirements: !ruby/object:Gem::Requirement
|
|
92
92
|
requirements:
|
|
93
|
-
- - "
|
|
93
|
+
- - ">="
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
|
-
version:
|
|
95
|
+
version: 0.24.0
|
|
96
96
|
- !ruby/object:Gem::Dependency
|
|
97
97
|
name: turbo-rails
|
|
98
98
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -386,7 +386,7 @@ metadata:
|
|
|
386
386
|
source_code_uri: https://github.com/AnjanJ/rails_error_dashboard
|
|
387
387
|
changelog_uri: https://github.com/AnjanJ/rails_error_dashboard/blob/main/CHANGELOG.md
|
|
388
388
|
post_install_message: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n
|
|
389
|
-
\ Rails Error Dashboard v0.1.
|
|
389
|
+
\ Rails Error Dashboard v0.1.24\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n\U0001F195
|
|
390
390
|
First time? Quick start:\n rails generate rails_error_dashboard:install\n rails
|
|
391
391
|
db:migrate\n # Add to config/routes.rb:\n mount RailsErrorDashboard::Engine
|
|
392
392
|
=> '/error_dashboard'\n\n\U0001F504 Upgrading from v0.1.x?\n rails db:migrate\n
|