error_radar 0.1.0

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.
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'error_radar/version'
4
+ require 'error_radar/configuration'
5
+ require 'error_radar/tracking'
6
+ require 'error_radar/middleware'
7
+ require 'error_radar/server_monitor'
8
+ require 'error_radar/engine'
9
+
10
+ # Public entry point for the gem.
11
+ #
12
+ # ErrorRadar.configure do |c|
13
+ # c.authenticate = ->(controller) { controller.send(:authenticate_admin!) }
14
+ # c.current_user = ->(controller) { controller.current_admin&.email }
15
+ # end
16
+ #
17
+ # ErrorRadar.capture(exception, source: 'SomeJob', context: { post_id: 1 })
18
+ # ErrorRadar.notify('Custom problem', category: :external_api, severity: :warning)
19
+ # ErrorRadar.monitor('NightlyRakeTask') { do_work }
20
+ module ErrorRadar
21
+ class << self
22
+ def config
23
+ @config ||= Configuration.new
24
+ end
25
+
26
+ def configure
27
+ yield config
28
+ end
29
+
30
+ # Reset configuration — mostly useful in tests.
31
+ def reset_config!
32
+ @config = Configuration.new
33
+ end
34
+
35
+ def capture(exception, **kwargs)
36
+ Tracking.capture(exception, **kwargs)
37
+ end
38
+
39
+ def notify(message, **kwargs)
40
+ Tracking.notify(message, **kwargs)
41
+ end
42
+
43
+ def monitor(source, **kwargs, &block)
44
+ Tracking.monitor(source, **kwargs, &block)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rails/generators'
4
+ require 'rails/generators/migration'
5
+
6
+ module ErrorRadar
7
+ module Generators
8
+ # Run `bin/rails generate error_radar:install` to drop an initializer and the
9
+ # error_radar_error_logs migration into the host app.
10
+ class InstallGenerator < Rails::Generators::Base
11
+ include Rails::Generators::Migration
12
+
13
+ source_root File.expand_path('templates', __dir__)
14
+
15
+ def self.next_migration_number(dirname)
16
+ next_migration_number = current_migration_number(dirname) + 1
17
+ ActiveRecord::Migration.next_migration_number(next_migration_number)
18
+ end
19
+
20
+ def copy_initializer
21
+ template 'initializer.rb', 'config/initializers/error_radar.rb'
22
+ end
23
+
24
+ def copy_migration
25
+ migration_template 'create_error_radar_error_logs.rb.tt',
26
+ 'db/migrate/create_error_radar_error_logs.rb'
27
+ end
28
+
29
+ def show_readme
30
+ say "\nError Radar installed.", :green
31
+ say ' 1. Review config/initializers/error_radar.rb'
32
+ say ' 2. Mount the dashboard in config/routes.rb, e.g.:'
33
+ say " mount ErrorRadar::Engine, at: '/monitoring'", :yellow
34
+ say ' 3. Run: bin/rails db:migrate'
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateErrorRadarErrorLogs < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
4
+ def change
5
+ create_table :error_radar_error_logs do |t|
6
+ # Grouping / dedup key so repeated identical failures collapse into one task.
7
+ t.string :fingerprint, null: false
8
+
9
+ # Classification
10
+ t.integer :category, null: false, default: 0
11
+ t.integer :severity, null: false, default: 2
12
+ t.integer :status, null: false, default: 0
13
+
14
+ # What & where
15
+ t.string :error_class
16
+ t.string :source # job / service / class that raised
17
+ t.text :message
18
+ t.text :backtrace
19
+ t.json :context # arbitrary structured payload
20
+
21
+ # API specifics (3rd-party APIs, etc.)
22
+ t.integer :http_status
23
+ t.string :request_url, limit: 1000
24
+ t.integer :api_code
25
+ t.integer :api_subcode
26
+
27
+ # Occurrence tracking
28
+ t.integer :occurrences, null: false, default: 1
29
+ t.datetime :first_seen_at, null: false
30
+ t.datetime :last_seen_at, null: false
31
+
32
+ # Task workflow
33
+ t.datetime :resolved_at
34
+ t.string :resolved_by
35
+ t.text :resolution_note
36
+
37
+ t.timestamps
38
+ end
39
+
40
+ add_index :error_radar_error_logs, :fingerprint, unique: true
41
+ add_index :error_radar_error_logs, %i[status severity]
42
+ add_index :error_radar_error_logs, :category
43
+ add_index :error_radar_error_logs, :last_seen_at
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Configuration for the error_radar gem. All keys are optional; sensible
4
+ # defaults are shown. See https://github.com/chienbn9x/error_radar for details.
5
+ ErrorRadar.configure do |config|
6
+ # Master switch. Turn off in environments where you don't want to persist
7
+ # errors (e.g. test).
8
+ config.enabled = !Rails.env.test?
9
+
10
+ # --- Integrations (auto-detected; flip off if you don't want them) ---
11
+ config.install_middleware = true # Rack: capture web-layer exceptions
12
+ config.install_sidekiq = true # capture Sidekiq job failures (if Sidekiq present)
13
+ config.install_rails_admin = true # register the ErrorLog board (if RailsAdmin present)
14
+
15
+ # --- Dashboard access control ---
16
+ # Run as a before_action; raise/redirect inside to deny. Example with Devise:
17
+ # config.authenticate = ->(controller) { controller.send(:authenticate_admin!) }
18
+ # config.current_user = ->(controller) { controller.current_admin&.email }
19
+
20
+ # --- Custom classification ---
21
+ # Map your own exception types to a category. First non-nil wins.
22
+ # config.categorize { |e| :external_api if e.is_a?(MyApi::Error) }
23
+ #
24
+ # Pull extra columns (http_status / request_url / api_code / api_subcode) out
25
+ # of a custom exception:
26
+ # config.extract_details do |e|
27
+ # next unless e.is_a?(MyApi::Error)
28
+ # { http_status: e.status, request_url: e.url, api_code: e.code }
29
+ # end
30
+
31
+ # --- Sidekiq server health panel (optional) ---
32
+ # Leave empty to just list whatever processes are live. To assert that
33
+ # specific processes must always run, list them here:
34
+ # config.expected_servers = [
35
+ # { key: 'web', name: 'Web', tag: 'sidekiq_web', host: 'web', queue_hint: 'low' }
36
+ # ]
37
+ end
38
+
39
+ # --- Optional: capture ActiveJob failures across ALL queue adapters ---
40
+ # Add to app/jobs/application_job.rb (skip if you only use Sidekiq, since the
41
+ # Sidekiq integration above already covers it):
42
+ #
43
+ # class ApplicationJob < ActiveJob::Base
44
+ # include ErrorRadar::Integrations::ActiveJob
45
+ # end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: error_radar
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - chienbn9x
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2026-06-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '7.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '9'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '7.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '9'
33
+ - !ruby/object:Gem::Dependency
34
+ name: sqlite3
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.4'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.4'
47
+ description: Captures unhandled exceptions from controllers, Rack, Sidekiq and ActiveJob,
48
+ deduplicates them by fingerprint, and exposes a kanban dashboard (and optional RailsAdmin
49
+ board) to triage them as tasks.
50
+ email:
51
+ - chienbn9x@gmail.com
52
+ executables: []
53
+ extensions: []
54
+ extra_rdoc_files: []
55
+ files:
56
+ - CHANGELOG.md
57
+ - MIT-LICENSE
58
+ - README.md
59
+ - Rakefile
60
+ - app/controllers/error_radar/application_controller.rb
61
+ - app/controllers/error_radar/dashboard_controller.rb
62
+ - app/models/error_radar/application_record.rb
63
+ - app/models/error_radar/error_log.rb
64
+ - app/views/error_radar/dashboard/index.html.erb
65
+ - app/views/error_radar/dashboard/show.html.erb
66
+ - app/views/layouts/error_radar/application.html.erb
67
+ - config/routes.rb
68
+ - lib/error_radar.rb
69
+ - lib/error_radar/configuration.rb
70
+ - lib/error_radar/engine.rb
71
+ - lib/error_radar/integrations/active_job.rb
72
+ - lib/error_radar/integrations/rails_admin.rb
73
+ - lib/error_radar/integrations/sidekiq.rb
74
+ - lib/error_radar/middleware.rb
75
+ - lib/error_radar/server_monitor.rb
76
+ - lib/error_radar/tracking.rb
77
+ - lib/error_radar/version.rb
78
+ - lib/generators/error_radar/install/install_generator.rb
79
+ - lib/generators/error_radar/install/templates/create_error_radar_error_logs.rb.tt
80
+ - lib/generators/error_radar/install/templates/initializer.rb
81
+ homepage: https://github.com/chienbn9x/error_radar
82
+ licenses:
83
+ - MIT
84
+ metadata:
85
+ homepage_uri: https://github.com/chienbn9x/error_radar
86
+ source_code_uri: https://github.com/chienbn9x/error_radar
87
+ changelog_uri: https://github.com/chienbn9x/error_radar/blob/main/CHANGELOG.md
88
+ rubygems_mfa_required: 'true'
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '3.0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubygems_version: 3.4.10
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: Drop-in error tracking & task board for Rails apps.
108
+ test_files: []