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
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
Complete API documentation for the ActionAudit gem.
|
|
4
|
+
|
|
5
|
+
## Module: ActionAudit
|
|
6
|
+
|
|
7
|
+
The main module that provides auditing functionality when included in controllers.
|
|
8
|
+
|
|
9
|
+
### Class Methods
|
|
10
|
+
|
|
11
|
+
#### `ActionAudit.log_formatter`
|
|
12
|
+
|
|
13
|
+
**Type:** `Proc` or `nil`
|
|
14
|
+
|
|
15
|
+
**Description:** Custom formatter for audit log messages.
|
|
16
|
+
|
|
17
|
+
**Signature:**
|
|
18
|
+
```ruby
|
|
19
|
+
ActionAudit.log_formatter = ->(controller_path, action_name, interpolated_message) { "formatted string" }
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Parameters:**
|
|
23
|
+
- `controller_path` (String): The normalized controller path (e.g., "admin/users")
|
|
24
|
+
- `action_name` (String): The controller action name (e.g., "create")
|
|
25
|
+
- `interpolated_message` (String): The audit message with parameters interpolated
|
|
26
|
+
|
|
27
|
+
**Returns:** String that will be logged
|
|
28
|
+
|
|
29
|
+
**Default:** `nil` (uses default formatting)
|
|
30
|
+
|
|
31
|
+
**Example:**
|
|
32
|
+
```ruby
|
|
33
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
34
|
+
"[#{Time.current.iso8601}] #{controller}/#{action} | #{message}"
|
|
35
|
+
end
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
#### `ActionAudit.log_tag`
|
|
39
|
+
|
|
40
|
+
**Type:** `String`, `Array`, or `nil`
|
|
41
|
+
|
|
42
|
+
**Description:** Tag(s) to be used with `Rails.logger.tagged()`.
|
|
43
|
+
|
|
44
|
+
**Default:** `nil` (no tagging)
|
|
45
|
+
|
|
46
|
+
**Examples:**
|
|
47
|
+
```ruby
|
|
48
|
+
ActionAudit.log_tag = "AUDIT"
|
|
49
|
+
ActionAudit.log_tag = ["AUDIT", "SECURITY"]
|
|
50
|
+
ActionAudit.log_tag = nil # Disable tagging
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Instance Methods (Private)
|
|
54
|
+
|
|
55
|
+
These methods are automatically added to controllers when `ActionAudit` is included.
|
|
56
|
+
|
|
57
|
+
#### `audit_request`
|
|
58
|
+
|
|
59
|
+
**Description:** The main auditing method called via `after_action` callback.
|
|
60
|
+
|
|
61
|
+
**Behavior:**
|
|
62
|
+
1. Determines controller path and action name
|
|
63
|
+
2. Looks up audit message from configuration
|
|
64
|
+
3. Interpolates message with controller parameters
|
|
65
|
+
4. Logs the formatted message
|
|
66
|
+
|
|
67
|
+
**Called automatically:** Yes (via `after_action`)
|
|
68
|
+
|
|
69
|
+
#### `interpolate_message(message, params)`
|
|
70
|
+
|
|
71
|
+
**Description:** Interpolates audit message with controller parameters.
|
|
72
|
+
|
|
73
|
+
**Parameters:**
|
|
74
|
+
- `message` (String): The audit message template
|
|
75
|
+
- `params` (ActionController::Parameters): Controller parameters for interpolation
|
|
76
|
+
|
|
77
|
+
**Returns:** String with interpolated values
|
|
78
|
+
|
|
79
|
+
**Error Handling:**
|
|
80
|
+
- Missing parameters: Logs interpolation error alongside original message
|
|
81
|
+
- Invalid message types: Converts to string
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Class: ActionAudit::AuditMessages
|
|
86
|
+
|
|
87
|
+
Registry class for managing audit messages, similar to I18n backend.
|
|
88
|
+
|
|
89
|
+
### Class Methods
|
|
90
|
+
|
|
91
|
+
#### `messages`
|
|
92
|
+
|
|
93
|
+
**Returns:** Hash containing all loaded audit messages
|
|
94
|
+
|
|
95
|
+
**Example:**
|
|
96
|
+
```ruby
|
|
97
|
+
ActionAudit::AuditMessages.messages
|
|
98
|
+
# => {
|
|
99
|
+
# "admin" => {
|
|
100
|
+
# "users" => {
|
|
101
|
+
# "create" => "Created user %{email}"
|
|
102
|
+
# }
|
|
103
|
+
# }
|
|
104
|
+
# }
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### `lookup(controller_path, action_name)`
|
|
108
|
+
|
|
109
|
+
**Description:** Look up an audit message for a specific controller/action combination.
|
|
110
|
+
|
|
111
|
+
**Parameters:**
|
|
112
|
+
- `controller_path` (String): Controller path (e.g., "admin/users")
|
|
113
|
+
- `action_name` (String): Action name (e.g., "create")
|
|
114
|
+
|
|
115
|
+
**Returns:** String message template or `nil` if not found
|
|
116
|
+
|
|
117
|
+
**Example:**
|
|
118
|
+
```ruby
|
|
119
|
+
ActionAudit::AuditMessages.lookup("admin/users", "create")
|
|
120
|
+
# => "Created user %{email}"
|
|
121
|
+
|
|
122
|
+
ActionAudit::AuditMessages.lookup("nonexistent", "action")
|
|
123
|
+
# => nil
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
#### `load_from_file(file_path)`
|
|
127
|
+
|
|
128
|
+
**Description:** Load audit messages from a YAML file.
|
|
129
|
+
|
|
130
|
+
**Parameters:**
|
|
131
|
+
- `file_path` (String): Absolute path to YAML file
|
|
132
|
+
|
|
133
|
+
**Behavior:**
|
|
134
|
+
- Merges loaded messages with existing ones
|
|
135
|
+
- Handles missing files gracefully
|
|
136
|
+
- Validates YAML structure
|
|
137
|
+
|
|
138
|
+
**Example:**
|
|
139
|
+
```ruby
|
|
140
|
+
ActionAudit::AuditMessages.load_from_file("/path/to/audit.yml")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### `load_from_engines`
|
|
144
|
+
|
|
145
|
+
**Description:** Automatically discover and load audit messages from all Rails engines.
|
|
146
|
+
|
|
147
|
+
**Behavior:**
|
|
148
|
+
- Loads from main application `config/audit.yml`
|
|
149
|
+
- Loads from each mounted engine's `config/audit.yml`
|
|
150
|
+
- Called automatically during Rails initialization
|
|
151
|
+
|
|
152
|
+
**Example:**
|
|
153
|
+
```ruby
|
|
154
|
+
ActionAudit::AuditMessages.load_from_engines
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### `add_message(controller_path, action_name, message)`
|
|
158
|
+
|
|
159
|
+
**Description:** Programmatically add an audit message.
|
|
160
|
+
|
|
161
|
+
**Parameters:**
|
|
162
|
+
- `controller_path` (String): Controller path (e.g., "admin/users")
|
|
163
|
+
- `action_name` (String): Action name (e.g., "create")
|
|
164
|
+
- `message` (String): Audit message template
|
|
165
|
+
|
|
166
|
+
**Example:**
|
|
167
|
+
```ruby
|
|
168
|
+
ActionAudit::AuditMessages.add_message("admin/users", "create", "Created user %{email}")
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### `clear!`
|
|
172
|
+
|
|
173
|
+
**Description:** Clear all loaded audit messages. Primarily used for testing.
|
|
174
|
+
|
|
175
|
+
**Example:**
|
|
176
|
+
```ruby
|
|
177
|
+
ActionAudit::AuditMessages.clear!
|
|
178
|
+
ActionAudit::AuditMessages.messages
|
|
179
|
+
# => {}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Class: ActionAudit::Engine
|
|
185
|
+
|
|
186
|
+
Rails engine that provides automatic configuration loading and integration.
|
|
187
|
+
|
|
188
|
+
### Behavior
|
|
189
|
+
|
|
190
|
+
- **Namespace:** Isolated as `ActionAudit`
|
|
191
|
+
- **Initializer:** Runs after `:load_config_initializers`
|
|
192
|
+
- **Development Mode:** Automatically reloads configurations when files change
|
|
193
|
+
- **Integration:** Seamlessly integrates with Rails application and engines
|
|
194
|
+
|
|
195
|
+
### Initializers
|
|
196
|
+
|
|
197
|
+
#### `action_audit.load_audit_messages`
|
|
198
|
+
|
|
199
|
+
Automatically loads audit messages from all engines during Rails startup.
|
|
200
|
+
|
|
201
|
+
#### Development Mode Configuration
|
|
202
|
+
|
|
203
|
+
In development mode, configurations are reloaded on each request to support hot reloading.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## Configuration File Format
|
|
208
|
+
|
|
209
|
+
### YAML Structure
|
|
210
|
+
|
|
211
|
+
Audit messages are defined in `config/audit.yml` using nested YAML structure:
|
|
212
|
+
|
|
213
|
+
```yaml
|
|
214
|
+
# Top-level keys are controller namespaces or direct controllers
|
|
215
|
+
namespace:
|
|
216
|
+
controller:
|
|
217
|
+
action: "Message template with %{parameter}"
|
|
218
|
+
|
|
219
|
+
# Examples:
|
|
220
|
+
admin:
|
|
221
|
+
users:
|
|
222
|
+
create: "Admin created user %{email}"
|
|
223
|
+
update: "Admin updated user %{id}"
|
|
224
|
+
|
|
225
|
+
sessions:
|
|
226
|
+
create: "User logged in with %{email}"
|
|
227
|
+
destroy: "User logged out"
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Controller Path Mapping
|
|
231
|
+
|
|
232
|
+
Controller class names are automatically converted to audit message paths:
|
|
233
|
+
|
|
234
|
+
| Controller Class | Audit Path |
|
|
235
|
+
|------------------|------------|
|
|
236
|
+
| `UsersController` | `users` |
|
|
237
|
+
| `Admin::UsersController` | `admin/users` |
|
|
238
|
+
| `API::V1::WebhooksController` | `api/v1/webhooks` |
|
|
239
|
+
| `Manage::Settings::PreferencesController` | `manage/settings/preferences` |
|
|
240
|
+
|
|
241
|
+
### Parameter Interpolation
|
|
242
|
+
|
|
243
|
+
Use `%{parameter_name}` syntax for parameter interpolation:
|
|
244
|
+
|
|
245
|
+
```yaml
|
|
246
|
+
users:
|
|
247
|
+
create: "Created user %{email} with role %{role}"
|
|
248
|
+
update: "Updated user %{id}"
|
|
249
|
+
destroy: "Deleted user %{id}"
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Supported Parameter Sources:**
|
|
253
|
+
- Direct controller parameters (`params[:email]`)
|
|
254
|
+
- Nested parameters (automatically flattened)
|
|
255
|
+
- Strong parameters (converted safely)
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Error Handling
|
|
260
|
+
|
|
261
|
+
### Missing Messages
|
|
262
|
+
|
|
263
|
+
If no audit message is configured for a controller/action:
|
|
264
|
+
- **Behavior:** No log entry is created (silent skip)
|
|
265
|
+
- **Impact:** No performance penalty or errors
|
|
266
|
+
|
|
267
|
+
### Missing Parameters
|
|
268
|
+
|
|
269
|
+
If a parameter referenced in the message template is missing:
|
|
270
|
+
- **Behavior:** Original message is logged with error information
|
|
271
|
+
- **Format:** `"Original message (interpolation error: key{param} not found)"`
|
|
272
|
+
- **Impact:** Audit still occurs with error context
|
|
273
|
+
|
|
274
|
+
### Invalid YAML
|
|
275
|
+
|
|
276
|
+
If `config/audit.yml` has syntax errors:
|
|
277
|
+
- **Behavior:** Rails logs warning during startup
|
|
278
|
+
- **Impact:** That particular configuration file is skipped
|
|
279
|
+
- **Recovery:** Fix YAML syntax and restart (or reload in development)
|
|
280
|
+
|
|
281
|
+
### File System Issues
|
|
282
|
+
|
|
283
|
+
If audit configuration files are unreadable:
|
|
284
|
+
- **Behavior:** Files are silently skipped
|
|
285
|
+
- **Impact:** Only affects that specific engine's configuration
|
|
286
|
+
- **Recovery:** Fix file permissions and restart
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Performance Characteristics
|
|
291
|
+
|
|
292
|
+
### Memory Usage
|
|
293
|
+
|
|
294
|
+
- **Message Storage:** All audit messages loaded into memory at startup
|
|
295
|
+
- **Typical Usage:** < 1MB for large applications with extensive audit configurations
|
|
296
|
+
- **Scaling:** Linear with number of configured audit messages
|
|
297
|
+
|
|
298
|
+
### Runtime Performance
|
|
299
|
+
|
|
300
|
+
- **Message Lookup:** O(1) hash lookup by controller path and action
|
|
301
|
+
- **Parameter Interpolation:** Standard Ruby string interpolation performance
|
|
302
|
+
- **Logging Overhead:** Equivalent to standard Rails logging
|
|
303
|
+
|
|
304
|
+
### Initialization Time
|
|
305
|
+
|
|
306
|
+
- **Configuration Loading:** O(n) where n is number of engines with audit configs
|
|
307
|
+
- **YAML Parsing:** Standard Ruby YAML parsing performance
|
|
308
|
+
- **Typical Impact:** < 100ms additional startup time
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## Testing Support
|
|
313
|
+
|
|
314
|
+
### RSpec Integration
|
|
315
|
+
|
|
316
|
+
ActionAudit works seamlessly with RSpec controller tests:
|
|
317
|
+
|
|
318
|
+
```ruby
|
|
319
|
+
RSpec.describe UsersController, type: :controller do
|
|
320
|
+
describe "#create" do
|
|
321
|
+
it "logs user creation" do
|
|
322
|
+
expect(Rails.logger).to receive(:info).with(/Created user.*john@example\.com/)
|
|
323
|
+
post :create, params: { user: { email: "john@example.com" } }
|
|
324
|
+
end
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Test Configuration
|
|
330
|
+
|
|
331
|
+
For testing environments:
|
|
332
|
+
|
|
333
|
+
```ruby
|
|
334
|
+
# In test environment
|
|
335
|
+
ActionAudit::AuditMessages.clear! # Clear messages
|
|
336
|
+
ActionAudit.log_formatter = nil # Use default formatting
|
|
337
|
+
ActionAudit.log_tag = nil # Disable tagging
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Stubbing
|
|
341
|
+
|
|
342
|
+
To disable auditing in specific tests:
|
|
343
|
+
|
|
344
|
+
```ruby
|
|
345
|
+
before do
|
|
346
|
+
allow(controller).to receive(:audit_request)
|
|
347
|
+
end
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
## Thread Safety
|
|
353
|
+
|
|
354
|
+
ActionAudit is thread-safe:
|
|
355
|
+
|
|
356
|
+
- **Message Registry:** Read-only after initialization
|
|
357
|
+
- **Configuration Loading:** Happens during Rails initialization (single-threaded)
|
|
358
|
+
- **Runtime Usage:** No shared mutable state during request processing
|
|
359
|
+
|
|
360
|
+
---
|
|
361
|
+
|
|
362
|
+
## Rails Version Compatibility
|
|
363
|
+
|
|
364
|
+
| Rails Version | ActionAudit Support |
|
|
365
|
+
|---------------|-------------------|
|
|
366
|
+
| 6.0.x | ✅ Fully supported |
|
|
367
|
+
| 6.1.x | ✅ Fully supported |
|
|
368
|
+
| 7.0.x | ✅ Fully supported |
|
|
369
|
+
| 7.1.x | ✅ Fully supported |
|
|
370
|
+
| 8.0.x | ✅ Fully supported |
|
|
371
|
+
|
|
372
|
+
---
|
|
373
|
+
|
|
374
|
+
## Ruby Version Compatibility
|
|
375
|
+
|
|
376
|
+
| Ruby Version | ActionAudit Support |
|
|
377
|
+
|-------------|-------------------|
|
|
378
|
+
| 3.1.x | ✅ Fully supported |
|
|
379
|
+
| 3.2.x | ✅ Fully supported |
|
|
380
|
+
| 3.3.x | ✅ Fully supported |
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## Dependencies
|
|
385
|
+
|
|
386
|
+
### Runtime Dependencies
|
|
387
|
+
|
|
388
|
+
- **Rails** (`>= 6.0`): Core Rails framework
|
|
389
|
+
- **ActiveSupport** (`>= 6.0`): For `Concern` and core extensions
|
|
390
|
+
|
|
391
|
+
### Development Dependencies
|
|
392
|
+
|
|
393
|
+
- **RSpec** (`~> 3.0`): Testing framework
|
|
394
|
+
- **RSpec-Rails** (`~> 6.0`): Rails integration for RSpec
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## Migration from Other Solutions
|
|
399
|
+
|
|
400
|
+
### From Manual Logging
|
|
401
|
+
|
|
402
|
+
```ruby
|
|
403
|
+
# Before: Manual logging
|
|
404
|
+
def create
|
|
405
|
+
@user = User.create!(user_params)
|
|
406
|
+
Rails.logger.info "Created user #{@user.email}"
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
# After: ActionAudit
|
|
410
|
+
class UsersController < ApplicationController
|
|
411
|
+
include ActionAudit
|
|
412
|
+
|
|
413
|
+
def create
|
|
414
|
+
@user = User.create!(user_params)
|
|
415
|
+
# Automatic logging via audit.yml configuration
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### From Other Audit Gems
|
|
421
|
+
|
|
422
|
+
ActionAudit provides a lightweight, configuration-based approach compared to database-backed audit solutions. Migration typically involves:
|
|
423
|
+
|
|
424
|
+
1. Configuring audit messages in YAML
|
|
425
|
+
2. Including `ActionAudit` in controllers
|
|
426
|
+
3. Removing previous audit gem dependencies
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
## Next Steps
|
|
431
|
+
|
|
432
|
+
- [See real-world examples](examples.md)
|
|
433
|
+
- [Learn about troubleshooting](troubleshooting.md)
|
|
434
|
+
- [Check installation guide](installation.md)
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# Configuration Guide
|
|
2
|
+
|
|
3
|
+
ActionAudit provides flexible configuration options for customizing how audit messages are formatted and logged.
|
|
4
|
+
|
|
5
|
+
## Audit Messages Configuration
|
|
6
|
+
|
|
7
|
+
### Basic Structure
|
|
8
|
+
|
|
9
|
+
Audit messages are defined in `config/audit.yml` using a nested structure that mirrors your controller hierarchy:
|
|
10
|
+
|
|
11
|
+
```yaml
|
|
12
|
+
# config/audit.yml
|
|
13
|
+
namespace:
|
|
14
|
+
controller:
|
|
15
|
+
action: "Audit message with %{parameter} interpolation"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Controller Path Mapping
|
|
19
|
+
|
|
20
|
+
ActionAudit automatically converts controller class names to audit message paths:
|
|
21
|
+
|
|
22
|
+
- `UsersController` → `users`
|
|
23
|
+
- `Admin::UsersController` → `admin/users`
|
|
24
|
+
- `API::V1::WebhooksController` → `api/v1/webhooks`
|
|
25
|
+
|
|
26
|
+
### Parameter Interpolation
|
|
27
|
+
|
|
28
|
+
Use `%{parameter_name}` syntax to interpolate controller parameters into audit messages:
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
users:
|
|
32
|
+
create: "Created user %{email} with role %{role}"
|
|
33
|
+
update: "Updated user %{id}"
|
|
34
|
+
destroy: "Deleted user %{id}"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The gem will automatically extract these values from `params` in your controller.
|
|
38
|
+
|
|
39
|
+
### Example Configuration
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
# config/audit.yml
|
|
43
|
+
|
|
44
|
+
# Admin interface
|
|
45
|
+
admin:
|
|
46
|
+
users:
|
|
47
|
+
create: "Admin created user %{email}"
|
|
48
|
+
update: "Admin updated user %{id}"
|
|
49
|
+
destroy: "Admin deleted user %{id}"
|
|
50
|
+
activate: "Admin activated user %{id}"
|
|
51
|
+
deactivate: "Admin deactivated user %{id}"
|
|
52
|
+
|
|
53
|
+
accounts:
|
|
54
|
+
create: "Admin created account %{name}"
|
|
55
|
+
update: "Admin updated account %{id} with %{name}"
|
|
56
|
+
destroy: "Admin deleted account %{id}"
|
|
57
|
+
|
|
58
|
+
# User authentication
|
|
59
|
+
sessions:
|
|
60
|
+
create: "User logged in with %{email}"
|
|
61
|
+
destroy: "User %{user_id} logged out"
|
|
62
|
+
|
|
63
|
+
# API endpoints
|
|
64
|
+
api:
|
|
65
|
+
v1:
|
|
66
|
+
webhooks:
|
|
67
|
+
create: "Webhook received from %{source}"
|
|
68
|
+
users:
|
|
69
|
+
create: "API user created via %{client_id}"
|
|
70
|
+
|
|
71
|
+
# Regular controllers
|
|
72
|
+
posts:
|
|
73
|
+
create: "Created post '%{title}'"
|
|
74
|
+
update: "Updated post %{id}"
|
|
75
|
+
publish: "Published post %{id}"
|
|
76
|
+
unpublish: "Unpublished post %{id}"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Logging Configuration
|
|
80
|
+
|
|
81
|
+
### Custom Log Formatter
|
|
82
|
+
|
|
83
|
+
Configure custom log formatting in `config/initializers/action_audit.rb`:
|
|
84
|
+
|
|
85
|
+
```ruby
|
|
86
|
+
# config/initializers/action_audit.rb
|
|
87
|
+
|
|
88
|
+
# Basic custom formatter
|
|
89
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
90
|
+
"[AUDIT] #{controller}/#{action} - #{message}"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Advanced formatter with timestamp and user info
|
|
94
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
95
|
+
timestamp = Time.current.iso8601
|
|
96
|
+
user_info = defined?(current_user) && current_user ? "User: #{current_user.email}" : "User: anonymous"
|
|
97
|
+
|
|
98
|
+
"[#{timestamp}] #{controller}/#{action} | #{message} | #{user_info}"
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Formatter with request ID
|
|
102
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
103
|
+
request_id = defined?(request) && request ? request.request_id : SecureRandom.hex(8)
|
|
104
|
+
"AUDIT [#{request_id}] #{controller}/#{action}: #{message}"
|
|
105
|
+
end
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Log Tagging
|
|
109
|
+
|
|
110
|
+
Add consistent tags to all audit log entries:
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
# Simple tag
|
|
114
|
+
ActionAudit.log_tag = "AUDIT"
|
|
115
|
+
|
|
116
|
+
# Multiple tags (if your logger supports it)
|
|
117
|
+
ActionAudit.log_tag = ["AUDIT", "SECURITY"]
|
|
118
|
+
|
|
119
|
+
# Dynamic tag
|
|
120
|
+
ActionAudit.log_tag = "AUDIT-#{Rails.env.upcase}"
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Default Behavior
|
|
124
|
+
|
|
125
|
+
If no custom configuration is provided:
|
|
126
|
+
|
|
127
|
+
- **Default formatter**: `"#{controller_path}/#{action_name} - #{interpolated_message}"`
|
|
128
|
+
- **Default tag**: `nil` (no tagging)
|
|
129
|
+
|
|
130
|
+
## Configuration Examples
|
|
131
|
+
|
|
132
|
+
### Minimal Configuration
|
|
133
|
+
|
|
134
|
+
```ruby
|
|
135
|
+
# config/initializers/action_audit.rb
|
|
136
|
+
ActionAudit.log_tag = "AUDIT"
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Production Configuration
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
# config/initializers/action_audit.rb
|
|
143
|
+
ActionAudit.log_tag = "AUDIT"
|
|
144
|
+
|
|
145
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
146
|
+
timestamp = Time.current.iso8601
|
|
147
|
+
request_id = defined?(request) && request ? request.request_id : "unknown"
|
|
148
|
+
user_id = defined?(current_user) && current_user ? current_user.id : "anonymous"
|
|
149
|
+
|
|
150
|
+
"[#{timestamp}] #{controller}/#{action} | #{message} | user_id=#{user_id} | request_id=#{request_id}"
|
|
151
|
+
end
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Development Configuration
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
# config/initializers/action_audit.rb
|
|
158
|
+
if Rails.env.development?
|
|
159
|
+
ActionAudit.log_tag = "DEV-AUDIT"
|
|
160
|
+
|
|
161
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
162
|
+
"🔍 [#{Time.current.strftime('%H:%M:%S')}] #{controller}/#{action} - #{message}"
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Environment-Specific Configuration
|
|
168
|
+
|
|
169
|
+
You can configure ActionAudit differently for each environment:
|
|
170
|
+
|
|
171
|
+
```ruby
|
|
172
|
+
# config/initializers/action_audit.rb
|
|
173
|
+
case Rails.env
|
|
174
|
+
when 'development'
|
|
175
|
+
ActionAudit.log_tag = "DEV-AUDIT"
|
|
176
|
+
ActionAudit.log_formatter = ->(c, a, m) { "🔍 #{c}/#{a} - #{m}" }
|
|
177
|
+
|
|
178
|
+
when 'staging'
|
|
179
|
+
ActionAudit.log_tag = "STAGING-AUDIT"
|
|
180
|
+
ActionAudit.log_formatter = ->(c, a, m) { "[STAGING] #{c}/#{a} | #{m}" }
|
|
181
|
+
|
|
182
|
+
when 'production'
|
|
183
|
+
ActionAudit.log_tag = "AUDIT"
|
|
184
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
185
|
+
timestamp = Time.current.iso8601
|
|
186
|
+
"[#{timestamp}] #{controller}/#{action} | #{message}"
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Integration with Structured Logging
|
|
192
|
+
|
|
193
|
+
ActionAudit works well with structured logging solutions:
|
|
194
|
+
|
|
195
|
+
```ruby
|
|
196
|
+
# For use with lograge or similar structured logging
|
|
197
|
+
ActionAudit.log_formatter = lambda do |controller, action, message|
|
|
198
|
+
{
|
|
199
|
+
type: 'audit',
|
|
200
|
+
controller: controller,
|
|
201
|
+
action: action,
|
|
202
|
+
message: message,
|
|
203
|
+
timestamp: Time.current.iso8601,
|
|
204
|
+
user_id: defined?(current_user) && current_user&.id,
|
|
205
|
+
request_id: defined?(request) && request&.request_id
|
|
206
|
+
}.to_json
|
|
207
|
+
end
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Testing Configuration
|
|
211
|
+
|
|
212
|
+
In your test environment, you might want to disable or modify auditing:
|
|
213
|
+
|
|
214
|
+
```ruby
|
|
215
|
+
# config/environments/test.rb or config/initializers/action_audit.rb
|
|
216
|
+
if Rails.env.test?
|
|
217
|
+
# Option 1: Disable formatting for cleaner test output
|
|
218
|
+
ActionAudit.log_formatter = nil
|
|
219
|
+
ActionAudit.log_tag = nil
|
|
220
|
+
|
|
221
|
+
# Option 2: Use simple test-friendly format
|
|
222
|
+
ActionAudit.log_formatter = ->(c, a, m) { "TEST_AUDIT: #{c}/#{a} - #{m}" }
|
|
223
|
+
end
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Next Steps
|
|
227
|
+
|
|
228
|
+
- [Learn about usage patterns](usage.md)
|
|
229
|
+
- [Set up multi-engine configuration](multi-engine.md)
|
|
230
|
+
- [Explore real-world examples](examples.md)
|