faultline-rails 0.5.0 → 1.0.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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +243 -121
  3. data/app/assets/stylesheets/faultline/dashboard.css +969 -0
  4. data/app/controllers/faultline/logged_exceptions_controller.rb +81 -8
  5. data/app/helpers/faultline/logged_exceptions_helper.rb +84 -5
  6. data/app/javascript/controllers/faultline_controller.js +349 -7
  7. data/app/javascript/controllers/faultline_detail_controller.js +98 -0
  8. data/app/javascript/faultline/controllers/sidebar_controller.js +21 -0
  9. data/app/javascript/faultline/controllers/theme_controller.js +48 -0
  10. data/app/views/faultline/logged_exceptions/_exceptions.html.erb +132 -84
  11. data/app/views/faultline/logged_exceptions/_show.html.erb +281 -60
  12. data/app/views/faultline/logged_exceptions/index.html.erb +192 -123
  13. data/app/views/faultline/logged_exceptions/show.html.erb +1 -1
  14. data/app/views/layouts/faultline/application.html.erb +119 -52
  15. data/faultline-rails.gemspec +1 -0
  16. data/lib/faultline/cleanup.rb +32 -0
  17. data/lib/faultline/configuration.rb +172 -4
  18. data/lib/faultline/engine.rb +22 -0
  19. data/lib/faultline/logger.rb +188 -0
  20. data/lib/faultline/notifications.rb +80 -0
  21. data/lib/faultline/version.rb +1 -1
  22. data/lib/faultline.rb +10 -0
  23. data/lib/generators/faultline/customize_generator.rb +117 -0
  24. data/lib/generators/faultline/install_generator.rb +15 -0
  25. data/lib/generators/faultline/templates/faultline.rb +70 -37
  26. data/lib/generators/faultline/templates/javascript/controllers/faultline_controller.js +310 -0
  27. data/lib/generators/faultline/templates/javascript/controllers/faultline_detail_controller.js +98 -0
  28. data/lib/generators/faultline/templates/views/faultline/logged_exceptions/_exceptions.html.erb +124 -0
  29. data/lib/generators/faultline/templates/views/faultline/logged_exceptions/_show.html.erb +297 -0
  30. data/lib/generators/faultline/templates/views/faultline/logged_exceptions/index.html.erb +113 -0
  31. data/lib/generators/faultline/templates/views/layouts/faultline/application.html.erb +135 -0
  32. data/lib/tasks/faultline.rake +147 -0
  33. metadata +17 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c846154434391fa5b6aff599c9c6f70dfd2d90690d5ce2050be6d284cd2d5c39
4
- data.tar.gz: 3191607d7ef2b2f0694d0a10e0a54899ddd4569dd007adba6d9f4e4bc09c50f2
3
+ metadata.gz: 870d33f7e1f9311ee4e932c60c0b430f91a5bf3f5e2e5c446bf69753647f8eda
4
+ data.tar.gz: 36a4dfce3b186ad20c60f849cc0d7a220579014bf44aa630dab6843d4bd68efa
5
5
  SHA512:
6
- metadata.gz: 89a84d8d6ff2955fa71be82b7deef6100e10953548ef381cde60b2e0df57bd3fa07403899900d8ce85bb1ee11ca66ee316472062e77baedceccde538812cf65b
7
- data.tar.gz: d63e16bf9eba501733ef42b694fb1315da801fa544579d2c5db999ee547841d2c7879247573f374303283e7aec100cbef436d4e9e5a608074270efebdda0567d
6
+ metadata.gz: f9311ba143ef33928040c5fcbe360fcd71fd2741d1f03f7793eac409545c988b9c3043c019f64217a0d907a7dde4d593cc5c9e0fffdd8aae9d4d0e334a0b3de2
7
+ data.tar.gz: 7cdae081decc10a6c3d8c406486aec7887fd89ee0d388c7da2da26ea8c7597fb62d34b56912feb7e20263fbb5d745409c36dd2aae57066a648d379e8caf10219
data/README.md CHANGED
@@ -1,14 +1,31 @@
1
1
  # Faultline Rails
2
2
 
3
- Faultline is a production-friendly exception dashboard for Rails 8. It records unhandled application exceptions and gives your team a fast, searchable view of messages, requests, environments, and backtraces.
3
+ [![Gem Version](https://badge.fury.io/rb/faultline-rails.svg)](https://rubygems.org/gems/faultline-rails)
4
+ [![GitHub Sponsors](https://img.shields.io/badge/Sponsor-GitHub%20Sponsors-ea4aaa)](https://github.com/sponsors/tamiru)
4
5
 
5
- The dashboard is server-rendered and progressively enhanced with:
6
+ Faultline is a production-friendly exception dashboard for Rails 8. It records unhandled application exceptions and gives your team a fast, searchable view of messages, requests, environments, and backtraces.
6
7
 
7
- - **Tailwind CSS** layout that works with or without Tailwind installed.
8
- - **Ransack** for advanced search and sortable columns.
9
- - Turbo Frames for filtering and opening exception details without full-page navigation.
10
- - Turbo Streams for deleting one, many, or all exceptions.
11
- - Stimulus for loading state and small interaction behavior.
8
+ The dashboard features a polished dark/light theme, keyboard shortcuts, tabbed detail view, stats overview, and webhook notifications.
9
+
10
+ ## Features
11
+
12
+ - **Dark / Light theme** Toggle with the sun/moon button or press `t`. Remembers preference in localStorage.
13
+ - **Keyboard shortcuts** — Press `?` to see all shortcuts. Navigate with `j`/`k`, focus search with `/`, open details with `Enter`.
14
+ - **Stats overview** — Total, weekly, today, and unique class counts at a glance.
15
+ - **Advanced filters** — Exception type, controller, time range, and full-text search with debounced input.
16
+ - **Tabbed detail view** — Overview, Backtrace, Request, Environment, and User Info tabs.
17
+ - **Prev/Next navigation** — Navigate between exceptions without returning to the list.
18
+ - **Copy to clipboard** — One-click copy for exception ID, message, and backtrace.
19
+ - **Collapsible backtrace** — Long traces collapse automatically; expand on demand.
20
+ - **Metadata grid** — Structured detail cards for exception class, controller, action, time, IP, and user agent.
21
+ - **Page size selector** — Choose 25, 50, or 100 results per page.
22
+ - **Active filter pills** — See and dismiss active filters with one click.
23
+ - **RSS feed** — Subscribe to `/faultline/logged_exceptions/feed.rss`.
24
+ - **Webhook notifications** — POST to Slack, Discord, or custom endpoints on each new exception.
25
+ - **Telegram notifications** — Built-in notifier with rate limiting.
26
+ - **Sidekiq middleware** — Automatically logs background job exceptions.
27
+ - **Cleanup / Retention** — Auto-delete old exceptions via rake tasks.
28
+ - **Structured logging** — JSON log output with request context and metadata.
12
29
 
13
30
  ## Requirements
14
31
 
@@ -25,7 +42,7 @@ Add Faultline to your application:
25
42
  gem "faultline-rails"
26
43
  ```
27
44
 
28
- Run the install generator to set up everything in one step:
45
+ Run the install generator:
29
46
 
30
47
  ```bash
31
48
  bundle install
@@ -37,53 +54,74 @@ This will:
37
54
  1. Copy the database migration with proper indexes.
38
55
  2. Create a configuration initializer at `config/initializers/faultline.rb`.
39
56
  3. Mount the engine in your routes.
40
- 4. Add `rescue_from Exception, with: :log_exception_handler` to your `ApplicationController` for Rails 8 compatibility.
57
+ 4. Add `rescue_from Exception, with: :log_exception_handler` to `ApplicationController`.
41
58
 
42
59
  The dashboard is now available at `/faultline`.
43
60
 
44
- > **Note:** The generator mounts the engine at `/faultline` by default. You can change the mount path by editing `config/routes.rb`.
61
+ ### Modern UI setup
62
+
63
+ Generate the polished dark/light theme with keyboard shortcuts:
64
+
65
+ ```bash
66
+ bin/rails generate faultline:customize
67
+ bin/rails stimulus:manifest:update
68
+ ```
69
+
70
+ This generates:
71
+ - Self-contained layout with sidebar, topbar, and theme toggle
72
+ - Tabbed detail view with metadata grid
73
+ - Keyboard shortcuts dialog
74
+ - Stimulus controllers for theme, sidebar, and interactions
75
+
76
+ Options: `--layout-only`, `--views-only`, `--stimulus-only`, `--initializer-only`
45
77
 
46
78
  ## Start logging exceptions
47
79
 
48
80
  Include `Faultline::ExceptionLoggable` in your application controller:
49
81
 
50
82
  ```ruby
51
- # app/controllers/application_controller.rb
52
83
  class ApplicationController < ActionController::Base
53
84
  include Faultline::ExceptionLoggable
54
85
  end
55
86
  ```
56
87
 
57
- Faultline logs the exception and then re-raises it so Rails keeps its normal error handling, status codes, and error pages.
88
+ Faultline logs the exception and then re-raises it so Rails keeps its normal error handling.
58
89
 
59
- ### Rails 8+ compatibility
90
+ ### API controllers
60
91
 
61
- Faultline's initializer automatically adds `rescue_from Exception, with: :log_exception_handler` to your `ApplicationController`. This ensures exceptions are logged even when Rails' built-in `rescue_action` pattern is no longer used.
92
+ For `ActionController::API` subclasses (e.g., API namespaces):
62
93
 
63
- If you need to handle this manually:
94
+ ```ruby
95
+ class Api::V1::BaseController < ActionController::API
96
+ include Faultline::ExceptionLoggable
97
+ end
98
+ ```
99
+
100
+ ### Background jobs (Sidekiq)
101
+
102
+ Faultline automatically logs Sidekiq job exceptions when the middleware is configured:
64
103
 
65
104
  ```ruby
66
- class ApplicationController < ActionController::Base
67
- rescue_from Exception, with: :log_exception_handler
105
+ # config/initializers/sidekiq.rb
106
+ Sidekiq.configure_server do |config|
107
+ config.server_middleware do |chain|
108
+ chain.add FaultlineSidekiqMiddleware
109
+ end
68
110
  end
69
111
  ```
70
112
 
71
113
  ## Protect the dashboard
72
114
 
73
- The dashboard contains sensitive information, including request parameters, environment variables, and source paths. **Do not expose it to unauthenticated public users.**
115
+ The dashboard contains sensitive information. **Do not expose it to unauthenticated users.**
74
116
 
75
- By default, the dashboard returns `403 Forbidden` for all requests. Configure authentication in your initializer:
117
+ By default, the dashboard returns `403 Forbidden` for all requests. Configure authentication:
76
118
 
77
119
  ```ruby
78
120
  # config/initializers/faultline.rb
79
121
  Rails.application.config.to_prepare do
80
122
  Faultline.configure do |config|
81
123
  config.auth_block = lambda do |controller|
82
- # Return true if the user is authorized to view the dashboard.
83
- # Examples:
84
- controller.authenticate_user! # Devise
85
- # controller.current_user&.admin? # Custom auth
86
- # false # Block everyone (default)
124
+ controller.current_user&.admin?
87
125
  end
88
126
  end
89
127
  end
@@ -91,171 +129,255 @@ end
91
129
 
92
130
  ## Configuration
93
131
 
94
- Configure Faultline through the block-style DSL in your initializer:
95
-
96
132
  ```ruby
97
133
  # config/initializers/faultline.rb
98
134
  Rails.application.config.to_prepare do
99
135
  Faultline.configure do |config|
100
- # Dashboard title
101
- config.application_name = "Acme"
102
-
103
- # Items per page (default: 30)
104
- config.per_page = 50
136
+ # ─── General ─────────────────────────────────────────────
137
+ config.application_name = "My App" # Dashboard title
138
+ config.per_page = 50 # Items per page (default: 30)
105
139
 
106
- # Authentication block (see "Protect the dashboard" above)
140
+ # ─── Authentication ──────────────────────────────────────
107
141
  config.auth_block = lambda do |controller|
108
142
  controller.current_user&.admin?
109
143
  end
110
- end
111
- end
112
- ```
113
144
 
114
- You can also attach additional application data to each recorded exception:
145
+ # ─── Exception Data ──────────────────────────────────────
146
+ config.exception_data = lambda do |controller|
147
+ {
148
+ user_id: controller.current_user&.id,
149
+ request_id: controller.request.request_id,
150
+ environment: Rails.env
151
+ }
152
+ end
115
153
 
116
- ```ruby
117
- config.exception_data = lambda do |controller|
118
- {
119
- request_id: controller.request.request_id,
120
- user_id: controller.current_user&.id,
121
- user_email: controller.current_user&.email,
122
- environment: Rails.env
123
- }
154
+ # ─── Notifications ───────────────────────────────────────
155
+ config.after_create = lambda do |exception|
156
+ MyNotifier.alert(exception)
157
+ end
158
+
159
+ config.webhooks = ["https://hooks.slack.com/services/xxx"]
160
+ config.webhook_timeout = 5
161
+ config.webhook_headers = { "Authorization" => "Bearer token" }
162
+
163
+ # ─── Cleanup ─────────────────────────────────────────────
164
+ config.retention_days = 90 # Auto-delete after N days
165
+
166
+ # ─── Appearance ──────────────────────────────────────────
167
+ config.theme = "auto" # "light", "dark", or "auto"
168
+ config.body_class = "" # Custom body CSS class
169
+ config.use_host_layout = false # Use host app's layout
170
+
171
+ # ─── Advanced UI ─────────────────────────────────────────
172
+ config.show_stats = true # Stats overview cards
173
+ config.keyboard_shortcuts = true # Keyboard shortcuts
174
+ config.enable_navigation = true # Prev/next in detail view
175
+ config.backtrace_limit = 30 # Frames before collapse
176
+ config.show_metadata = true # Metadata grid
177
+ config.show_environment = false # Environment tab
178
+ config.show_request = true # Request params tab
179
+ config.page_size_options = [25, 50, 100] # Page size selector
180
+
181
+ # ─── Sidebar Links ───────────────────────────────────────
182
+ config.sidebar_links = [
183
+ { label: "GitHub", url: "https://github.com/myorg/myapp" },
184
+ { label: "Docs", url: "/docs" }
185
+ ]
186
+
187
+ # ─── Logging ─────────────────────────────────────────────
188
+ config.logging_enabled = true
189
+ config.log_level = :info # :debug, :info, :warn, :error, :fatal
190
+ config.log_file = "log/faultline.log" # JSON log file (nil = none)
191
+ config.log_backtrace = true
192
+ config.log_params = true
193
+ config.log_user_info = true
194
+ config.log_backtrace_limit = 20
195
+ config.deduplication_enabled = false
196
+ config.deduplication_window = 300 # Seconds
197
+ end
124
198
  end
125
199
  ```
126
200
 
127
- Exclude trusted private networks from the dashboard's local-request handling:
201
+ ## Keyboard shortcuts
128
202
 
129
- ```ruby
130
- class ApplicationController < ActionController::Base
131
- include Faultline::ExceptionLoggable
203
+ Press `?` in the dashboard to see all shortcuts:
132
204
 
133
- consider_local "10.0.0.0/8", "192.168.0.0/16"
134
- end
135
- ```
205
+ | Key | Action |
206
+ |---|---|
207
+ | `/` | Focus search |
208
+ | `j` or `↓` | Navigate down |
209
+ | `k` or `↑` | Navigate up |
210
+ | `Enter` | Open selected exception |
211
+ | `p` or `←` | Previous exception |
212
+ | `n` or `→` | Next exception |
213
+ | `t` | Toggle dark/light theme |
214
+ | `1`-`5` | Switch tabs |
215
+ | `Esc` | Close panel / Clear |
216
+ | `?` | Show shortcuts dialog |
136
217
 
137
- Rails' `filter_parameters` configuration is respected before request parameters are stored.
218
+ ## Search & Filter
138
219
 
139
- ## Search & Filter (Ransack)
220
+ - **Exception Type** Select dropdown, auto-submits on change
221
+ - **Controller** — Select dropdown, auto-submits on change
222
+ - **Time Range** — Today, 3 days, 7 days, 30 days
223
+ - **Search** — Full-text search with 400ms debounce
224
+ - **Active Filters** — Pills with one-click dismiss
140
225
 
141
- Faultline includes [Ransack](https://github.com/activerecord-hackery/ransack) for advanced search and filtering. The dashboard provides:
226
+ All filters work with Ransack for advanced search, or fall back to built-in scopes.
142
227
 
143
- - **Search form** — Search by exception class, controller name, and message text.
144
- - **Sortable columns** — Click column headers to sort by exception class, controller, action, or date.
145
- - **Sidebar filters** — Quick filter by exception class, controller/action, and time range (today, 3 days, 7 days, 30 days).
228
+ ## Notifications
146
229
 
147
- If your app doesn't include Ransack, Faultline falls back to the built-in sidebar filters automatically.
230
+ ### Webhooks
148
231
 
149
- ### Searching
232
+ ```ruby
233
+ config.webhooks = [
234
+ "https://hooks.slack.com/services/T00/B00/xxx",
235
+ "https://discord.com/api/webhooks/xxx"
236
+ ]
237
+ config.webhook_timeout = 5
238
+ config.webhook_headers = { "Authorization" => "Bearer token" }
239
+ ```
150
240
 
151
- Type in the search form fields and click "Search" to filter exceptions:
241
+ POST JSON to each URL on every new exception:
242
+ ```json
243
+ {
244
+ "exception_class": "RuntimeError",
245
+ "controller_name": "users",
246
+ "action_name": "show",
247
+ "message": "Something went wrong",
248
+ "created_at": "2026-08-22T12:00:00Z",
249
+ "dashboard_url": "http://localhost:3000/faultline/logged_exceptions/42"
250
+ }
251
+ ```
152
252
 
153
- - **Exception Class** — Search by exception type (e.g., `RuntimeError`, `ActiveRecord::RecordNotFound`)
154
- - **Controller** — Search by controller name (e.g., `users`, `posts`)
155
- - **Message** — Full-text search across exception messages
253
+ ### Telegram
156
254
 
157
- ### Sorting
255
+ Set `TELEGRAM_TOKEN` and `TELEGRAM_CHAT_ID` environment variables:
158
256
 
159
- Click any column header in the exceptions table to sort:
257
+ ```bash
258
+ export TELEGRAM_TOKEN="your-bot-token"
259
+ export TELEGRAM_CHAT_ID="your-chat-id"
260
+ ```
160
261
 
161
- - **Exception** — Sort alphabetically by exception class
162
- - **Controller** — Sort by controller name
163
- - **Action** — Sort by action name
164
- - **Date** — Sort by creation date (newest/oldest first)
262
+ Configure the notifier:
165
263
 
166
- ## Frontend setup
264
+ ```ruby
265
+ config.after_create = lambda do |exception|
266
+ Faultline::TelegramNotifier.new.notify(exception)
267
+ end
268
+ ```
167
269
 
168
- ### Hotwire (default)
270
+ Rate limiting: 10-minute cooldown per exception class + controller combination.
169
271
 
170
- Faultline includes `turbo-rails` and `stimulus-rails` as dependencies. If your Rails app already has Hotwire installed (the default for Rails 8), no extra setup is needed.
272
+ ## Cleanup / Retention
171
273
 
172
- If you need to install Hotwire:
274
+ ```ruby
275
+ config.retention_days = 90 # Auto-delete after 90 days
276
+ ```
277
+
278
+ Rake tasks:
173
279
 
174
280
  ```bash
175
- bin/rails turbo:install
176
- bin/rails stimulus:install
281
+ rake faultline:cleanup # Delete exceptions older than retention_days
282
+ rake faultline:stats # Show exception statistics
283
+ rake faultline:tail # Tail JSON logs in real-time
284
+ rake faultline:export # Export exceptions to JSON
285
+ rake faultline:test_webhook # Test webhook configuration
177
286
  ```
178
287
 
179
- ### Styling
288
+ ## Frontend setup
180
289
 
181
- Faultline ships with its own built-in CSS stylesheet that works out of the box. No Tailwind configuration is required.
290
+ ### Hotwire (default)
182
291
 
183
- #### Tailwind CSS
292
+ Faultline includes `turbo-rails` and `stimulus-rails` as dependencies. For Rails 8, no extra setup is needed.
184
293
 
185
- If your application uses Tailwind CSS, Faultline's views are already Tailwind-styled and will automatically use your Tailwind theme.
294
+ ### Styling
186
295
 
187
- If you want to configure the gem's view directory as a Tailwind source, use the absolute path returned by Bundler:
296
+ Faultline ships with its own CSS (`faultline/dashboard.css`) that works out of the box with dark/light themes.
188
297
 
189
- ```bash
190
- bundle show faultline-rails
191
- ```
298
+ #### Tailwind CSS
192
299
 
193
- For Tailwind CSS v4, add a source entry:
300
+ If your app uses Tailwind, add the gem's views as a source:
194
301
 
195
302
  ```css
303
+ /* Tailwind v4 */
196
304
  @import "tailwindcss";
197
- @source "/absolute/path/to/faultline-rails/app/views";
305
+ @source "/path/to/faultline-rails/app/views";
198
306
  ```
199
307
 
200
- For Tailwind CSS v3, add the gem path to `content` in `tailwind.config.js`:
308
+ #### Esbuild / Propshaft
201
309
 
202
- ```javascript
203
- const faultlinePath = "/absolute/path/to/faultline-rails"
310
+ The layout automatically detects your asset pipeline and loads `application.js`:
204
311
 
205
- module.exports = {
206
- content: [
207
- "./app/views/**/*.{erb,html}",
208
- `${faultlinePath}/app/views/**/*.html.erb`
209
- ]
210
- }
312
+ ```erb
313
+ <% if defined?(Propshaft) || Rails.application.assets&.find_asset("application.js") %>
314
+ <%= javascript_include_tag "application", "data-turbo-track": "reload", type: "module" %>
315
+ <% elsif respond_to?(:javascript_importmap_tags) %>
316
+ <%= javascript_importmap_tags %>
317
+ <% end %>
211
318
  ```
212
319
 
213
- #### Non-importmap projects
214
-
215
- Faultline works with **importmap**, **sprockets**, **propshaft**, or **no JS pipeline** at all. The layout adapts to your asset pipeline:
320
+ #### Importmap
216
321
 
217
- - If `javascript_importmap_tags` is available, it uses importmap.
218
- - If `turbo_refreshes_with` is available, it enables Turbo morph scrolling.
219
- - If neither is available, the dashboard works without JavaScript.
322
+ Works automatically. Run `stimulus:manifest:update` to register the faultline controllers.
220
323
 
221
- ### Bootstrap / Other CSS frameworks
324
+ ### Stimulus controllers
222
325
 
223
- Faultline's views use Tailwind CSS utility classes. To use Bootstrap or another framework:
326
+ Three controllers are included:
224
327
 
225
- 1. Override the views by copying them to your app:
226
- ```bash
227
- cp -r $(bundle show faultline-rails)/app/views/faultline app/views/faultline
228
- ```
229
- 2. Rewrite the Tailwind classes with your framework's classes.
230
- 3. The built-in CSS in `faultline/application.css` provides fallback styles.
328
+ | Controller | Registered as | Purpose |
329
+ |---|---|---|
330
+ | `faultline_controller.js` | `faultline` | Keyboard nav, search, tabs, copy, backtrace expand |
331
+ | `faultline_sidebar_controller.js` | `faultline-sidebar` | Mobile drawer toggle |
332
+ | `faultline_theme_controller.js` | `faultline-theme` | Dark/light/auto theme toggle |
231
333
 
232
- ## Dashboard features
233
-
234
- - **Search** — Full-text search across exception messages, classes, and controllers.
235
- - **Sortable columns** — Sort by exception class, controller, action, or date.
236
- - **Filter** — Filter by exception class, controller/action, or age.
237
- - **Exception details** — Open full exception details in a Turbo Frame.
238
- - **Delete** — Delete individual exceptions without leaving the page.
239
- - **Bulk delete** — Delete the currently visible result set.
240
- - **Clear history** — Clear the complete exception history.
241
- - **RSS feed** — Subscribe to `/faultline/logged_exceptions/feed.rss`.
334
+ Run `bin/rails stimulus:manifest:update` after installing to auto-register them.
242
335
 
243
336
  ## Data storage
244
337
 
245
- The engine creates a `faultline_logged_exceptions` table containing the exception class, controller/action, message, backtrace, request, environment, user information, user agent, remote IP, and timestamps.
338
+ The engine creates a `faultline_logged_exceptions` table with columns for exception class, controller/action, message, backtrace, request, environment, user information, user agent, remote IP, and timestamps.
246
339
 
247
340
  Exception records can contain secrets. Apply your normal database encryption, retention, backup, and access-control policies.
248
341
 
342
+ ## Generators
343
+
344
+ | Generator | Description |
345
+ |---|---|
346
+ | `rails generate faultline:install` | Full setup (migration, initializer, routes) |
347
+ | `rails generate faultline:install --modern` | Install + generate all customizations |
348
+ | `rails generate faultline:customize` | Generate customizable views, layout, and JS |
349
+ | `rails generate faultline:customize --layout-only` | Only the layout |
350
+ | `rails generate faultline:customize --views-only` | Only the views |
351
+ | `rails generate faultline:customize --stimulus-only` | Only the Stimulus controller |
352
+
249
353
  ## Development
250
354
 
251
- Run the test suite with:
355
+ Run the test suite:
252
356
 
253
357
  ```bash
254
- bin/rails test
358
+ cd /path/to/faultline-rails
359
+ RAILS_ENV=test bundle exec rails test
360
+ ```
361
+
362
+ Build the gem:
363
+
364
+ ```bash
365
+ gem build faultline-rails.gemspec
255
366
  ```
256
367
 
257
368
  The repository includes a Rails dummy application under `test/dummy` for engine integration testing.
258
369
 
370
+ ## Support
371
+
372
+ If you find Faultline useful, consider supporting the project:
373
+
374
+ - ⭐ **Star the repo** — Help others discover Faultline
375
+ - 🐛 **Report issues** — Help improve the gem
376
+ - 💡 **Contribute** — Submit pull requests
377
+ - 💰 **Sponsor** — [GitHub Sponsors](https://github.com/sponsors/tamiru)
378
+
379
+ Your support helps maintain and improve Faultline for the Rails community.
380
+
259
381
  ## License
260
382
 
261
383
  Faultline Rails is released under the [MIT License](MIT-LICENSE).