action-audit 1.0.1
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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +17 -0
- data/CHANGELOG.md +29 -0
- data/CODE_OF_CONDUCT.md +25 -0
- data/LICENSE +21 -0
- data/README.md +232 -0
- data/Rakefile +12 -0
- data/docs/README.md +25 -0
- data/docs/api-reference.md +434 -0
- data/docs/configuration.md +230 -0
- data/docs/examples.md +609 -0
- data/docs/installation.md +114 -0
- data/docs/migration.md +571 -0
- data/docs/multi-engine.md +413 -0
- data/docs/troubleshooting.md +577 -0
- data/docs/usage.md +347 -0
- data/lib/action-audit.rb +3 -0
- data/lib/action_audit/audit_messages.rb +73 -0
- data/lib/action_audit/engine.rb +19 -0
- data/lib/action_audit/version.rb +5 -0
- data/lib/action_audit.rb +75 -0
- data/lib/generators/action_audit/install_generator.rb +25 -0
- data/lib/generators/action_audit/templates/README +25 -0
- data/lib/generators/action_audit/templates/action_audit.rb +17 -0
- data/lib/generators/action_audit/templates/audit.yml +30 -0
- data/sig/action_audit.rbs +4 -0
- metadata +146 -0
data/docs/migration.md
ADDED
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
# Migration Guide
|
|
2
|
+
|
|
3
|
+
Guide for migrating from other audit solutions to ActionAudit.
|
|
4
|
+
|
|
5
|
+
## Migration Overview
|
|
6
|
+
|
|
7
|
+
ActionAudit provides a lightweight, configuration-based approach to auditing that differs from database-backed audit solutions. This guide helps you migrate from various audit gems and custom solutions.
|
|
8
|
+
|
|
9
|
+
## From Manual Logging Solutions
|
|
10
|
+
|
|
11
|
+
### Before: Manual Rails.logger Calls
|
|
12
|
+
|
|
13
|
+
```ruby
|
|
14
|
+
# Old approach: Manual logging in each action
|
|
15
|
+
class UsersController < ApplicationController
|
|
16
|
+
def create
|
|
17
|
+
@user = User.create!(user_params)
|
|
18
|
+
Rails.logger.info "User created: #{@user.email} by #{current_user&.email}"
|
|
19
|
+
redirect_to @user
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def update
|
|
23
|
+
@user = User.find(params[:id])
|
|
24
|
+
old_email = @user.email
|
|
25
|
+
@user.update!(user_params)
|
|
26
|
+
Rails.logger.info "User #{@user.id} updated: #{old_email} -> #{@user.email}"
|
|
27
|
+
redirect_to @user
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def destroy
|
|
31
|
+
@user = User.find(params[:id])
|
|
32
|
+
user_email = @user.email
|
|
33
|
+
@user.destroy!
|
|
34
|
+
Rails.logger.info "User deleted: #{user_email} by #{current_user&.email}"
|
|
35
|
+
redirect_to users_path
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### After: ActionAudit Configuration
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
# New approach: Include ActionAudit
|
|
44
|
+
class UsersController < ApplicationController
|
|
45
|
+
include ActionAudit
|
|
46
|
+
|
|
47
|
+
def create
|
|
48
|
+
@user = User.create!(user_params)
|
|
49
|
+
# Automatic logging via audit.yml
|
|
50
|
+
redirect_to @user
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def update
|
|
54
|
+
@user = User.find(params[:id])
|
|
55
|
+
@user.update!(user_params)
|
|
56
|
+
# Automatic logging via audit.yml
|
|
57
|
+
redirect_to @user
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def destroy
|
|
61
|
+
@user = User.find(params[:id])
|
|
62
|
+
@user.destroy!
|
|
63
|
+
# Automatic logging via audit.yml
|
|
64
|
+
redirect_to users_path
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
# config/audit.yml
|
|
71
|
+
users:
|
|
72
|
+
create: "User created: %{email}"
|
|
73
|
+
update: "User %{id} updated"
|
|
74
|
+
destroy: "User deleted: %{id}"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
# config/initializers/action_audit.rb
|
|
79
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
80
|
+
user_info = defined?(current_user) && current_user ? " by #{current_user.email}" : ""
|
|
81
|
+
"#{message}#{user_info}"
|
|
82
|
+
end
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Migration Benefits:**
|
|
86
|
+
- **Centralized Configuration:** All audit messages in one place
|
|
87
|
+
- **Consistency:** Uniform message format across controllers
|
|
88
|
+
- **Maintainability:** Easy to update messages without touching controller code
|
|
89
|
+
- **DRY Principle:** No repeated logging code
|
|
90
|
+
|
|
91
|
+
## From Database Audit Gems
|
|
92
|
+
|
|
93
|
+
### From Audited Gem
|
|
94
|
+
|
|
95
|
+
The `audited` gem stores audit records in the database. ActionAudit focuses on logging instead.
|
|
96
|
+
|
|
97
|
+
#### Before: Audited Configuration
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
# Gemfile
|
|
101
|
+
gem 'audited'
|
|
102
|
+
|
|
103
|
+
# Model
|
|
104
|
+
class User < ApplicationRecord
|
|
105
|
+
audited only: [:name, :email], on: [:create, :update, :destroy]
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# Querying audit records
|
|
109
|
+
user.audits.where(action: 'create')
|
|
110
|
+
user.audits.last.audited_changes
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### After: ActionAudit Configuration
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
# Gemfile
|
|
117
|
+
gem 'action_audit'
|
|
118
|
+
|
|
119
|
+
# Controller
|
|
120
|
+
class UsersController < ApplicationController
|
|
121
|
+
include ActionAudit
|
|
122
|
+
|
|
123
|
+
def create
|
|
124
|
+
@user = User.create!(user_params)
|
|
125
|
+
# ActionAudit logs the action
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```yaml
|
|
131
|
+
# config/audit.yml
|
|
132
|
+
users:
|
|
133
|
+
create: "Created user %{email} with %{name}"
|
|
134
|
+
update: "Updated user %{id}: %{name}"
|
|
135
|
+
destroy: "Deleted user %{id}"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**Key Differences:**
|
|
139
|
+
- **Storage:** ActionAudit uses Rails logs, not database
|
|
140
|
+
- **Performance:** No database writes for audit records
|
|
141
|
+
- **Querying:** Use log analysis tools instead of ActiveRecord queries
|
|
142
|
+
- **Retention:** Managed by log rotation, not database cleanup
|
|
143
|
+
|
|
144
|
+
### From PaperTrail Gem
|
|
145
|
+
|
|
146
|
+
PaperTrail tracks changes to models with database storage.
|
|
147
|
+
|
|
148
|
+
#### Migration Strategy
|
|
149
|
+
|
|
150
|
+
1. **Keep PaperTrail for data versioning**
|
|
151
|
+
2. **Add ActionAudit for user action logging**
|
|
152
|
+
3. **Use both gems for different purposes**
|
|
153
|
+
|
|
154
|
+
```ruby
|
|
155
|
+
# Model: Keep PaperTrail for data history
|
|
156
|
+
class User < ApplicationRecord
|
|
157
|
+
has_paper_trail only: [:name, :email, :role]
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Controller: Add ActionAudit for action logging
|
|
161
|
+
class UsersController < ApplicationController
|
|
162
|
+
include ActionAudit
|
|
163
|
+
|
|
164
|
+
def update
|
|
165
|
+
@user = User.find(params[:id])
|
|
166
|
+
@user.update!(user_params)
|
|
167
|
+
# PaperTrail records the data change
|
|
168
|
+
# ActionAudit logs the user action
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Use Cases:**
|
|
174
|
+
- **PaperTrail:** Data versioning, rollbacks, change history
|
|
175
|
+
- **ActionAudit:** User actions, security logging, compliance
|
|
176
|
+
|
|
177
|
+
## From Custom Audit Solutions
|
|
178
|
+
|
|
179
|
+
### From Service Object Pattern
|
|
180
|
+
|
|
181
|
+
```ruby
|
|
182
|
+
# Before: Custom audit service
|
|
183
|
+
class AuditService
|
|
184
|
+
def self.log_user_action(action, user, target = nil)
|
|
185
|
+
message = build_message(action, user, target)
|
|
186
|
+
Rails.logger.info("[AUDIT] #{message}")
|
|
187
|
+
AuditRecord.create!(
|
|
188
|
+
action: action,
|
|
189
|
+
user: user,
|
|
190
|
+
target: target,
|
|
191
|
+
message: message
|
|
192
|
+
)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
private
|
|
196
|
+
|
|
197
|
+
def self.build_message(action, user, target)
|
|
198
|
+
case action
|
|
199
|
+
when :create_user
|
|
200
|
+
"User #{user.email} created user #{target.email}"
|
|
201
|
+
when :update_user
|
|
202
|
+
"User #{user.email} updated user #{target.id}"
|
|
203
|
+
# ... many more cases
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Usage in controllers
|
|
209
|
+
class UsersController < ApplicationController
|
|
210
|
+
def create
|
|
211
|
+
@user = User.create!(user_params)
|
|
212
|
+
AuditService.log_user_action(:create_user, current_user, @user)
|
|
213
|
+
redirect_to @user
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
```ruby
|
|
219
|
+
# After: ActionAudit
|
|
220
|
+
class UsersController < ApplicationController
|
|
221
|
+
include ActionAudit
|
|
222
|
+
|
|
223
|
+
def create
|
|
224
|
+
@user = User.create!(user_params)
|
|
225
|
+
params[:created_user_email] = @user.email
|
|
226
|
+
# ActionAudit handles the rest
|
|
227
|
+
redirect_to @user
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
```yaml
|
|
233
|
+
# config/audit.yml
|
|
234
|
+
users:
|
|
235
|
+
create: "User created: %{created_user_email}"
|
|
236
|
+
update: "User updated: %{id}"
|
|
237
|
+
destroy: "User deleted: %{id}"
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
```ruby
|
|
241
|
+
# config/initializers/action_audit.rb
|
|
242
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
243
|
+
user_email = defined?(current_user) && current_user ? current_user.email : "system"
|
|
244
|
+
"[AUDIT] User #{user_email}: #{message}"
|
|
245
|
+
end
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Migration Steps
|
|
249
|
+
|
|
250
|
+
### Step 1: Install ActionAudit
|
|
251
|
+
|
|
252
|
+
```ruby
|
|
253
|
+
# Gemfile
|
|
254
|
+
gem 'action_audit'
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
bundle install
|
|
259
|
+
rails generate action_audit:install
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Step 2: Identify Current Audit Points
|
|
263
|
+
|
|
264
|
+
Analyze your existing codebase to find:
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
# Find manual logging calls
|
|
268
|
+
grep -r "Rails.logger.*audit\|audit.*log" app/
|
|
269
|
+
|
|
270
|
+
# Find service object calls
|
|
271
|
+
grep -r "AuditService\|Audit.*log" app/
|
|
272
|
+
|
|
273
|
+
# Find existing audit gem usage
|
|
274
|
+
grep -r "audited\|paper_trail" app/
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Step 3: Map to ActionAudit Configuration
|
|
278
|
+
|
|
279
|
+
Create a mapping of your current audit points:
|
|
280
|
+
|
|
281
|
+
```yaml
|
|
282
|
+
# config/audit.yml
|
|
283
|
+
# Map your existing audit points to configuration
|
|
284
|
+
|
|
285
|
+
# From: Rails.logger.info "User #{user.email} created"
|
|
286
|
+
users:
|
|
287
|
+
create: "User created: %{email}"
|
|
288
|
+
|
|
289
|
+
# From: AuditService.log(:user_update, current_user, @user)
|
|
290
|
+
users:
|
|
291
|
+
update: "User updated: %{id}"
|
|
292
|
+
|
|
293
|
+
# From: audit_comment: "Deleted user account"
|
|
294
|
+
users:
|
|
295
|
+
destroy: "User deleted: %{id}"
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Step 4: Update Controllers Gradually
|
|
299
|
+
|
|
300
|
+
Migrate controllers one at a time:
|
|
301
|
+
|
|
302
|
+
```ruby
|
|
303
|
+
# Phase 1: Add ActionAudit alongside existing logging
|
|
304
|
+
class UsersController < ApplicationController
|
|
305
|
+
include ActionAudit
|
|
306
|
+
|
|
307
|
+
def create
|
|
308
|
+
@user = User.create!(user_params)
|
|
309
|
+
|
|
310
|
+
# Keep existing logging temporarily
|
|
311
|
+
Rails.logger.info "User created: #{@user.email}"
|
|
312
|
+
|
|
313
|
+
# ActionAudit will also log
|
|
314
|
+
redirect_to @user
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
```ruby
|
|
320
|
+
# Phase 2: Remove old logging after verification
|
|
321
|
+
class UsersController < ApplicationController
|
|
322
|
+
include ActionAudit
|
|
323
|
+
|
|
324
|
+
def create
|
|
325
|
+
@user = User.create!(user_params)
|
|
326
|
+
# Only ActionAudit logging now
|
|
327
|
+
redirect_to @user
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### Step 5: Configure Custom Formatting
|
|
333
|
+
|
|
334
|
+
Match your existing log format:
|
|
335
|
+
|
|
336
|
+
```ruby
|
|
337
|
+
# config/initializers/action_audit.rb
|
|
338
|
+
|
|
339
|
+
# If you had: "[AUDIT] User john@example.com: Created user jane@example.com"
|
|
340
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
341
|
+
user_email = defined?(current_user) && current_user ? current_user.email : "system"
|
|
342
|
+
"[AUDIT] User #{user_email}: #{message}"
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
ActionAudit.log_tag = nil # No additional tagging if you had custom format
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Step 6: Update Log Processing
|
|
349
|
+
|
|
350
|
+
If you have log processing tools, update them for ActionAudit format:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
# Old log format
|
|
354
|
+
[AUDIT] User john@example.com created user jane@example.com
|
|
355
|
+
|
|
356
|
+
# New ActionAudit format
|
|
357
|
+
[AUDIT] User john@example.com: User created: jane@example.com
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Update your log parsing scripts accordingly.
|
|
361
|
+
|
|
362
|
+
## Testing Migration
|
|
363
|
+
|
|
364
|
+
### Parallel Logging During Migration
|
|
365
|
+
|
|
366
|
+
Run both systems in parallel to verify migration:
|
|
367
|
+
|
|
368
|
+
```ruby
|
|
369
|
+
# Temporary parallel logging
|
|
370
|
+
class UsersController < ApplicationController
|
|
371
|
+
include ActionAudit
|
|
372
|
+
|
|
373
|
+
def create
|
|
374
|
+
@user = User.create!(user_params)
|
|
375
|
+
|
|
376
|
+
# Old system
|
|
377
|
+
AuditService.log_user_action(:create_user, current_user, @user)
|
|
378
|
+
|
|
379
|
+
# New system (ActionAudit automatic)
|
|
380
|
+
|
|
381
|
+
redirect_to @user
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Verification Script
|
|
387
|
+
|
|
388
|
+
```ruby
|
|
389
|
+
# Create: verify_migration.rb
|
|
390
|
+
require_relative 'config/environment'
|
|
391
|
+
|
|
392
|
+
# Test ActionAudit configuration
|
|
393
|
+
puts "Testing ActionAudit Configuration"
|
|
394
|
+
puts "=" * 40
|
|
395
|
+
|
|
396
|
+
# Check all your migrated audit points
|
|
397
|
+
test_cases = [
|
|
398
|
+
['users', 'create'],
|
|
399
|
+
['users', 'update'],
|
|
400
|
+
['users', 'destroy'],
|
|
401
|
+
['admin/users', 'create'],
|
|
402
|
+
['sessions', 'create']
|
|
403
|
+
]
|
|
404
|
+
|
|
405
|
+
test_cases.each do |controller, action|
|
|
406
|
+
message = ActionAudit::AuditMessages.lookup(controller, action)
|
|
407
|
+
status = message ? "✓" : "✗ MISSING"
|
|
408
|
+
puts "#{status} #{controller}/#{action}: #{message}"
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
# Test parameter interpolation
|
|
412
|
+
puts "\nTesting Parameter Interpolation"
|
|
413
|
+
puts "=" * 40
|
|
414
|
+
|
|
415
|
+
sample_params = { id: 123, email: 'test@example.com', name: 'Test User' }
|
|
416
|
+
test_message = ActionAudit::AuditMessages.lookup('users', 'create')
|
|
417
|
+
|
|
418
|
+
if test_message
|
|
419
|
+
begin
|
|
420
|
+
result = test_message % sample_params.symbolize_keys
|
|
421
|
+
puts "✓ Interpolation: #{result}"
|
|
422
|
+
rescue KeyError => e
|
|
423
|
+
puts "✗ Interpolation failed: #{e.message}"
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## Rollback Plan
|
|
429
|
+
|
|
430
|
+
Keep your migration reversible:
|
|
431
|
+
|
|
432
|
+
### Rollback to Manual Logging
|
|
433
|
+
|
|
434
|
+
```ruby
|
|
435
|
+
# Keep this code commented during migration
|
|
436
|
+
class UsersController < ApplicationController
|
|
437
|
+
# include ActionAudit # Comment out ActionAudit
|
|
438
|
+
|
|
439
|
+
def create
|
|
440
|
+
@user = User.create!(user_params)
|
|
441
|
+
|
|
442
|
+
# Uncomment manual logging if needed
|
|
443
|
+
Rails.logger.info "[AUDIT] User created: #{@user.email}"
|
|
444
|
+
|
|
445
|
+
redirect_to @user
|
|
446
|
+
end
|
|
447
|
+
end
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Feature Flags
|
|
451
|
+
|
|
452
|
+
Use feature flags to control migration:
|
|
453
|
+
|
|
454
|
+
```ruby
|
|
455
|
+
# config/initializers/action_audit.rb
|
|
456
|
+
if Rails.application.config.use_action_audit
|
|
457
|
+
# ActionAudit configuration
|
|
458
|
+
ActionAudit.log_tag = "AUDIT"
|
|
459
|
+
else
|
|
460
|
+
# Disable ActionAudit
|
|
461
|
+
module ActionAudit
|
|
462
|
+
def audit_request
|
|
463
|
+
# No-op when disabled
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
## Post-Migration Cleanup
|
|
470
|
+
|
|
471
|
+
### Remove Old Dependencies
|
|
472
|
+
|
|
473
|
+
```ruby
|
|
474
|
+
# Remove from Gemfile after successful migration
|
|
475
|
+
# gem 'audited'
|
|
476
|
+
# gem 'paper_trail' # Only if not needed for versioning
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
### Clean Up Old Code
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
# Find and remove old audit service calls
|
|
483
|
+
grep -r "AuditService\|OldAuditGem" app/ --exclude-dir=tmp
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### Update Documentation
|
|
487
|
+
|
|
488
|
+
Update your application documentation to reflect the new audit approach:
|
|
489
|
+
|
|
490
|
+
- How to add new audit messages
|
|
491
|
+
- Log format and location
|
|
492
|
+
- How to query audit logs
|
|
493
|
+
- Maintenance procedures
|
|
494
|
+
|
|
495
|
+
## Common Migration Issues
|
|
496
|
+
|
|
497
|
+
### Different Parameter Names
|
|
498
|
+
|
|
499
|
+
**Problem:** Old system used different parameter names.
|
|
500
|
+
|
|
501
|
+
```ruby
|
|
502
|
+
# Old system expected
|
|
503
|
+
AuditService.log(:user_created, user_id: @user.id, user_email: @user.email)
|
|
504
|
+
|
|
505
|
+
# ActionAudit expects params[:user_email]
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
**Solution:** Map parameters in controller:
|
|
509
|
+
|
|
510
|
+
```ruby
|
|
511
|
+
def create
|
|
512
|
+
@user = User.create!(user_params)
|
|
513
|
+
params[:user_email] = @user.email # Map for ActionAudit
|
|
514
|
+
redirect_to @user
|
|
515
|
+
end
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### Complex Audit Logic
|
|
519
|
+
|
|
520
|
+
**Problem:** Old system had complex conditional audit logic.
|
|
521
|
+
|
|
522
|
+
**Solution:** Use custom formatter or controller-level logic:
|
|
523
|
+
|
|
524
|
+
```ruby
|
|
525
|
+
# config/initializers/action_audit.rb
|
|
526
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
527
|
+
# Add complex logic here if needed
|
|
528
|
+
if controller == 'admin/users' && sensitive_action?(action)
|
|
529
|
+
alert_security_team(message)
|
|
530
|
+
end
|
|
531
|
+
|
|
532
|
+
message
|
|
533
|
+
end
|
|
534
|
+
```
|
|
535
|
+
|
|
536
|
+
### Database Audit Records
|
|
537
|
+
|
|
538
|
+
**Problem:** Need to maintain database audit records.
|
|
539
|
+
|
|
540
|
+
**Solution:** Create custom after_action alongside ActionAudit:
|
|
541
|
+
|
|
542
|
+
```ruby
|
|
543
|
+
class ApplicationController < ActionController::Base
|
|
544
|
+
include ActionAudit
|
|
545
|
+
|
|
546
|
+
after_action :create_audit_record, if: :should_audit_to_database?
|
|
547
|
+
|
|
548
|
+
private
|
|
549
|
+
|
|
550
|
+
def create_audit_record
|
|
551
|
+
# Create database record if needed
|
|
552
|
+
AuditRecord.create!(
|
|
553
|
+
controller: self.class.name,
|
|
554
|
+
action: action_name,
|
|
555
|
+
user: current_user,
|
|
556
|
+
timestamp: Time.current
|
|
557
|
+
)
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
def should_audit_to_database?
|
|
561
|
+
# Define when to create database records
|
|
562
|
+
%w[create update destroy].include?(action_name)
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
## Next Steps
|
|
568
|
+
|
|
569
|
+
- [See real-world examples](examples.md)
|
|
570
|
+
- [Check troubleshooting guide](troubleshooting.md)
|
|
571
|
+
- [Return to main documentation](README.md)
|