event_logger_rails 0.2.1 → 0.3.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.
- checksums.yaml +4 -4
- data/README.md +280 -26
- data/app/controllers/concerns/event_logger_rails/loggable_controller.rb +19 -0
- data/app/models/concerns/event_logger_rails/loggable_model.rb +19 -0
- data/lib/event_logger_rails/current_request.rb +9 -0
- data/lib/event_logger_rails/emitter.rb +31 -0
- data/lib/event_logger_rails/engine.rb +23 -0
- data/lib/event_logger_rails/event.rb +81 -0
- data/lib/event_logger_rails/exceptions/invalid_logger_level.rb +13 -2
- data/lib/event_logger_rails/exceptions/unregistered_event.rb +12 -2
- data/lib/event_logger_rails/extensions/loggable.rb +23 -0
- data/lib/event_logger_rails/json_logger.rb +15 -0
- data/lib/event_logger_rails/message.rb +20 -0
- data/lib/event_logger_rails/middleware/capture_request_details.rb +36 -0
- data/lib/event_logger_rails/output.rb +61 -0
- data/lib/event_logger_rails/version.rb +1 -1
- data/lib/event_logger_rails.rb +26 -10
- data/lib/generators/event_logger_rails/install_generator.rb +6 -2
- data/lib/generators/event_logger_rails/templates/event_logger_rails.yml +17 -15
- metadata +23 -12
- data/app/controllers/concerns/event_logger_rails/loggable.rb +0 -29
- data/lib/event_logger_rails/event_logger.rb +0 -97
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 110cf01af709d86d2e848b9d11363ca58a0ab433eb444c05b9e9044d22ed35a3
|
4
|
+
data.tar.gz: 4b338f9e6f937e16195fc6f184bbad7e376409dcf44e545c50c3cec101b58123
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 46be7cf18342e29d39b60f7cc4858858b5b880f16f049d65d89f69dccc0f0add12053be5020d6856a8db059f75f7f7b86f05e7733a55cadda3b3ed83dfe1e9c5
|
7
|
+
data.tar.gz: e69a33c9979e4bea40ec4ed0c723821c574586ab6a6ac29cea0f8e181fc0c545acf763b985d69b98899c5b2336262add45055479c3411673fc87ce20f760bc6f
|
data/README.md
CHANGED
@@ -1,67 +1,294 @@
|
|
1
|
-
|
1
|
+
## 🔌 EventLoggerRails 💾
|
2
2
|
|
3
|
-
|
3
|
+

|
4
|
+
*Elara, the mascot for `EventLoggerRails`*
|
5
|
+
|
6
|
+
Are you tired of navigating through logs as if you're lost in the labyrinth of the Wired, searching for that elusive piece of data? Say "Hello, World!" to `EventLoggerRails`, the Rails engine transmuting your logs into enlightened gems of understanding. 💎
|
7
|
+
|
8
|
+
### Visualize This
|
9
|
+
|
10
|
+
In a single, centralized config file, decipher the events that pulse through the veins of your business. Once set, let `EventLoggerRails` weave them into intricate patterns of JSON logs that shimmer like a digital mirage. 🎇
|
11
|
+
|
12
|
+
### Yet, The Nexus Expands
|
13
|
+
|
14
|
+
Channel these JSON enigmas directly into analytic realms like OpenSearch. There, witness the alchemy of data taking form through real-time visualizations and analysis. 📊✨
|
15
|
+
|
16
|
+
### Why Choose `EventLoggerRails`?
|
17
|
+
|
18
|
+
- 🚀 **Fast Setup**: Get your logging up and running in minutes, not hours!
|
19
|
+
- 🌐 **Team-Friendly Event Registry**: Simplify how your team defines and logs business-critical events.
|
20
|
+
- 📚 **Readable**: Logs in a clean, JSON-formatted structure for easy parsing and analysis.
|
21
|
+
- 🔍 **In-Depth Insight**: Elevate your business process analysis with granular, structured logging.
|
22
|
+
|
23
|
+
Don't let crucial events get lost in the digital void. Make your app's logging as unforgettable as your first journey into the Wired with `EventLoggerRails`!
|
24
|
+
|
25
|
+
### Huh?
|
26
|
+
|
27
|
+
Ok, so Elara might be a little zealous about our project, and she seems to be stuck in a 90's anime. Don't let that dissuade you from using this engine, though.
|
28
|
+
|
29
|
+
Our no-nonsense project description: **`EventLoggerRails` is a Rails engine for emitting structured events in logs during the execution of business processes for analysis and visualization.
|
30
|
+
It allows teams to define events in a simple, centralized configuration file, and then log those events in JSON format for further processing.**
|
4
31
|
|
5
32
|
## Usage
|
6
33
|
|
7
|
-
You can define a registry of events
|
8
|
-
The events
|
34
|
+
You can define a registry of events your application emits via the config file (`config/event_logger_rails.yml`).
|
35
|
+
The events you define are placed in the config file under the corresponding environment. Most events belong in `shared`, though you may want to define different
|
36
|
+
events or event characteristics per environment.
|
9
37
|
|
10
|
-
For example, to register a user signup event, first define the event as a registered event
|
38
|
+
For example, to register a user signup event, first define the event as a registered event. You must include a `description` for the event, and you may
|
39
|
+
optionally include a `level` to use for that specific event.
|
11
40
|
|
12
41
|
```yaml
|
13
|
-
|
42
|
+
shared:
|
14
43
|
user:
|
15
44
|
signup:
|
16
|
-
success:
|
17
|
-
|
45
|
+
success:
|
46
|
+
description: 'Indicates a successful user signup.'
|
47
|
+
failure:
|
48
|
+
description: 'Indicates a user signup was not successful.'
|
49
|
+
level: 'error'
|
18
50
|
```
|
19
51
|
|
20
|
-
|
52
|
+
### Logging in Controllers
|
53
|
+
|
54
|
+
Continuing this example, we'll want to log the events we registered. To do so, include the `EventLoggerRails::LoggableController` concern in the controller that
|
55
|
+
processes user signup's and call the `log_event` method to log details about the event:
|
21
56
|
|
22
57
|
```ruby
|
23
58
|
class UsersController < ApplicationController
|
24
|
-
include EventLoggerRails::
|
59
|
+
include EventLoggerRails::LoggableController
|
25
60
|
|
26
61
|
def create
|
27
62
|
user = User.new(user_params)
|
28
63
|
if user.save
|
29
|
-
log_event
|
64
|
+
log_event 'user.signup.success'
|
30
65
|
redirect_to dashboard_path
|
31
66
|
else
|
32
|
-
log_event
|
67
|
+
log_event 'user.signup.failure', data: { errors: user.errors.full_messages }
|
33
68
|
render :new
|
34
|
-
|
69
|
+
end
|
35
70
|
end
|
36
71
|
end
|
37
72
|
```
|
38
73
|
|
39
74
|
In this example, a possible successful signup could be structured like this:
|
40
75
|
|
41
|
-
```
|
42
|
-
|
76
|
+
```json
|
77
|
+
{
|
78
|
+
"environment": "development",
|
79
|
+
"format": "application/x-www-form-urlencoded;charset=UTF-8",
|
80
|
+
"host": "d6aeb6b0516c",
|
81
|
+
"id": "2b8f44c1-0e42-4a5f-84b8-52659990d138",
|
82
|
+
"service_name": "DummyApp",
|
83
|
+
"level": "WARN",
|
84
|
+
"method": "POST",
|
85
|
+
"parameters": {
|
86
|
+
"authenticity_token": "[FILTERED]",
|
87
|
+
"user": {
|
88
|
+
"email": "princess@leia.com",
|
89
|
+
"password": "[FILTERED]"
|
90
|
+
}
|
91
|
+
},
|
92
|
+
"path": "/users",
|
93
|
+
"remote_ip": "172.20.0.1",
|
94
|
+
"timestamp": "2023-09-30T06:47:16.938+00:00",
|
95
|
+
"event_identifier": "user.signup.success",
|
96
|
+
"event_description": "Indicates a user signup was successful.",
|
97
|
+
"email": "princess@leia.com",
|
98
|
+
"action": "create",
|
99
|
+
"controller": "Registrations"
|
100
|
+
}
|
43
101
|
```
|
44
102
|
|
45
103
|
...while a failed signup might look like this:
|
46
104
|
|
105
|
+
```json
|
106
|
+
{
|
107
|
+
"environment": "development",
|
108
|
+
"format": "application/x-www-form-urlencoded;charset=UTF-8",
|
109
|
+
"host": "d6aeb6b0516c",
|
110
|
+
"id": "2b8f44c1-0e42-4a5f-84b8-52656690d138",
|
111
|
+
"service_name": "DummyApp",
|
112
|
+
"level": "ERROR",
|
113
|
+
"method": "POST",
|
114
|
+
"parameters": {
|
115
|
+
"authenticity_token": "[FILTERED]",
|
116
|
+
"user": {
|
117
|
+
"email": "",
|
118
|
+
"password": "[FILTERED]"
|
119
|
+
},
|
120
|
+
},
|
121
|
+
"path": "/users",
|
122
|
+
"remote_ip": "172.20.0.1",
|
123
|
+
"timestamp": "2023-09-30T06:47:16.928+00:00",
|
124
|
+
"event_identifier": "user.signup.failure",
|
125
|
+
"event_description": "Indicates a user signup was not successful.",
|
126
|
+
"errors": [
|
127
|
+
"Email can't be blank",
|
128
|
+
"Password can't be blank"
|
129
|
+
],
|
130
|
+
"email": "princess@leia.com",
|
131
|
+
"action": "create",
|
132
|
+
"controller": "Registrations"
|
133
|
+
}
|
47
134
|
```
|
48
|
-
|
135
|
+
|
136
|
+
Note how the log entry from the previous example contains the data passed in via the optional `data` argument.
|
137
|
+
|
138
|
+
You can also provide a logger level as an optional argument if you need to specify a logger level other than the default. If you provide a logger level, it
|
139
|
+
will override the configured event level and the default logger level.
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
log_event 'user.signup.failure', level: :info, data: { errors: user.errors }
|
49
143
|
```
|
50
144
|
|
51
|
-
|
145
|
+
This will output an event with the corresponding severity level. You must provide a valid logger level (`:debug, :info, :warn, :error, or :unknown`).
|
52
146
|
|
147
|
+
```json
|
148
|
+
{
|
149
|
+
"environment": "development",
|
150
|
+
"format": "application/x-www-form-urlencoded;charset=UTF-8",
|
151
|
+
"host": "d6aeb6b0516c",
|
152
|
+
"id": "2b8f44c1-0e42-4a5f-84b8-52656690d138",
|
153
|
+
"service_name": "DummyApp",
|
154
|
+
"level": "INFO",
|
155
|
+
"method": "POST",
|
156
|
+
"parameters": {
|
157
|
+
"authenticity_token": "[FILTERED]",
|
158
|
+
"user": {
|
159
|
+
"email": "",
|
160
|
+
"password": "[FILTERED]"
|
161
|
+
},
|
162
|
+
},
|
163
|
+
"path": "/users",
|
164
|
+
"remote_ip": "172.20.0.1",
|
165
|
+
"timestamp": "2023-09-30T06:47:16.928+00:00",
|
166
|
+
"event_identifier": "user.signup.failure",
|
167
|
+
"event_description": "Indicates a user signup was not successful.",
|
168
|
+
"errors": [
|
169
|
+
"Email can't be blank",
|
170
|
+
"Password can't be blank"
|
171
|
+
],
|
172
|
+
"email": "princess@leia.com",
|
173
|
+
"action": "create",
|
174
|
+
"controller": "Registrations"
|
175
|
+
}
|
53
176
|
```
|
54
|
-
|
177
|
+
|
178
|
+
### Logging in Models
|
179
|
+
|
180
|
+
You can also log events from within models by including the `EventLoggerRails::LoggableModel` concern and calling `log_event`.
|
181
|
+
|
182
|
+
```ruby
|
183
|
+
class User < ApplicationRecord
|
184
|
+
include EventLoggerRails::LoggableModel
|
185
|
+
|
186
|
+
after_create :log_signup
|
187
|
+
|
188
|
+
private
|
189
|
+
|
190
|
+
def log_signup
|
191
|
+
log_event 'user.signup.success', data: { email: }
|
192
|
+
end
|
193
|
+
end
|
55
194
|
```
|
56
195
|
|
57
|
-
|
196
|
+
By default, `EventLoggerRails` will include the model name, instance ID, and whatever data is passed.
|
58
197
|
|
198
|
+
```json
|
199
|
+
{
|
200
|
+
"environment": "development",
|
201
|
+
"format": "application/x-www-form-urlencoded;charset=UTF-8",
|
202
|
+
"host": "d6aeb6b0516c",
|
203
|
+
"id": "2b8f44c1-0e42-4a5f-84b8-52652332d138",
|
204
|
+
"service_name": "DummyApp",
|
205
|
+
"level": "WARN",
|
206
|
+
"method": "POST",
|
207
|
+
"parameters": {
|
208
|
+
"authenticity_token": "[FILTERED]",
|
209
|
+
"user": {
|
210
|
+
"email": "princess@leia.com",
|
211
|
+
"password": "[FILTERED]"
|
212
|
+
}
|
213
|
+
},
|
214
|
+
"path": "/users",
|
215
|
+
"remote_ip": "172.20.0.1",
|
216
|
+
"timestamp": "2023-09-30T06:47:16.817+00:00",
|
217
|
+
"event_identifier": "user.signup.success",
|
218
|
+
"event_description": "Indicates a user signup was successful.",
|
219
|
+
"email": "princess@leia.com",
|
220
|
+
"model": "User",
|
221
|
+
"instance_id": 41
|
222
|
+
}
|
59
223
|
```
|
60
|
-
|
224
|
+
|
225
|
+
### Logging Everywhere Else
|
226
|
+
|
227
|
+
You can log events from anywhere inside of your application by calling `EventLoggerRails.log` directly, though you won't get the additional context
|
228
|
+
from the controller or model.
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
EventLoggerRails.log 'user.signup.success', level: :info, data: { user_id: @user.id }
|
232
|
+
```
|
233
|
+
|
234
|
+
### Errors
|
235
|
+
|
236
|
+
There are two expected errors which are handled by `EventLoggerRails`: an unregistered event and an invalid logger level. Both will result
|
237
|
+
in a log entry with an event corresponding to the error, and the severity level will be set to `ERROR`.
|
238
|
+
|
239
|
+
If you fail to register an event, the logger will emit an `event_logger_rails.event.unregistered` event:
|
240
|
+
|
241
|
+
```json
|
242
|
+
{
|
243
|
+
"environment": "development",
|
244
|
+
"format": "application/x-www-form-urlencoded;charset=UTF-8",
|
245
|
+
"host": "d6aeb6b0516c",
|
246
|
+
"id": "94c5ffe9-1bd8-4e04-88a3-478958e242b0",
|
247
|
+
"service_name": "DummyApp",
|
248
|
+
"level": "ERROR",
|
249
|
+
"method": "POST",
|
250
|
+
"parameters": {
|
251
|
+
"authenticity_token": "[FILTERED]",
|
252
|
+
"user": {
|
253
|
+
"email": "",
|
254
|
+
"password": "[FILTERED]"
|
255
|
+
}
|
256
|
+
},
|
257
|
+
"path": "/users",
|
258
|
+
"remote_ip": "172.20.0.1",
|
259
|
+
"timestamp": "2023-09-30T07:03:34.993+00:00",
|
260
|
+
"event_identifier": "event_logger_rails.event.unregistered",
|
261
|
+
"event_description": "Indicates provided event was unregistered.",
|
262
|
+
"message": "Event provided not registered: foo.bar"
|
263
|
+
}
|
61
264
|
```
|
62
265
|
|
63
|
-
|
64
|
-
|
266
|
+
If you provide an invalid log level, the logger will emit an `event_logger_rails.logger_level.invalid` event:
|
267
|
+
|
268
|
+
```json
|
269
|
+
{
|
270
|
+
"environment": "development",
|
271
|
+
"format": "application/x-www-form-urlencoded;charset=UTF-8",
|
272
|
+
"host": "d6aeb6b0516c",
|
273
|
+
"id": "11541423-0008-4cc7-aef7-1e4af9a801d7",
|
274
|
+
"service_name": "DummyApp",
|
275
|
+
"level": "ERROR",
|
276
|
+
"method": "POST",
|
277
|
+
"parameters": {
|
278
|
+
"authenticity_token": "[FILTERED]",
|
279
|
+
"user": {
|
280
|
+
"email": "",
|
281
|
+
"password": "[FILTERED]"
|
282
|
+
}
|
283
|
+
},
|
284
|
+
"path": "/users",
|
285
|
+
"remote_ip": "172.20.0.1",
|
286
|
+
"timestamp": "2023-09-30T07:04:52.623+00:00",
|
287
|
+
"event_identifier": "event_logger_rails.logger_level.invalid",
|
288
|
+
"event_description": "Indicates provided level was invalid.",
|
289
|
+
"message": "Invalid logger level provided: 'foobar'. Valid levels: :debug, :info, :warn, :error, :unknown."
|
290
|
+
}
|
291
|
+
```
|
65
292
|
|
66
293
|
## Installation
|
67
294
|
|
@@ -74,27 +301,54 @@ gem 'event_logger_rails'
|
|
74
301
|
And then execute:
|
75
302
|
|
76
303
|
```bash
|
77
|
-
|
304
|
+
bundle
|
78
305
|
```
|
79
306
|
|
80
307
|
Or install it yourself as:
|
81
308
|
|
82
309
|
```bash
|
83
|
-
|
310
|
+
gem install event_logger_rails
|
84
311
|
```
|
85
312
|
|
86
313
|
Run the install generator to create a config file (`config/event_logger_rails.yml`):
|
87
314
|
|
88
315
|
```bash
|
89
|
-
|
316
|
+
bin/rails generate event_logger_rails:install
|
90
317
|
```
|
91
318
|
|
92
319
|
Add your events to the generated config file following the structure of the examples.
|
93
320
|
|
321
|
+
You can specify a default level `EventLoggerRails` will use if a level is not included in the call to the logger or configured as a default for the provided event.
|
322
|
+
This default level is set to `:warn` unless otherwise specified.
|
323
|
+
|
324
|
+
```ruby
|
325
|
+
Rails.application.configure do |config|
|
326
|
+
config.event_logger_rails.default_level = :info
|
327
|
+
end
|
328
|
+
```
|
329
|
+
|
330
|
+
By default, `EventLoggerRails` outputs to a separate log file (`log/event_logger_rails.#{Rails.env}.log`) from normal Rails log output, allowing
|
331
|
+
you to ingest these logs independently. If you wish to set an alternative log device to capture output, you can configure it in `config/application.rb`:
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
Rails.application.configure do |config|
|
335
|
+
config.event_logger_rails.logdev = 'path/to/log.file'
|
336
|
+
end
|
337
|
+
```
|
338
|
+
|
339
|
+
Some platforms require logging output to be sent to $STDOUT. You can configure this as an output device easily enough.
|
340
|
+
|
341
|
+
```ruby
|
342
|
+
Rails.application.configure do |config|
|
343
|
+
config.event_logger_rails.logdev = $stdout
|
344
|
+
end
|
345
|
+
```
|
346
|
+
|
94
347
|
## Contributing
|
95
348
|
|
96
|
-
|
349
|
+
Your inputs echo in this realm. Venture forth and materialize your thoughts through a PR.
|
97
350
|
|
98
351
|
## License
|
99
352
|
|
100
353
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
354
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EventLoggerRails
|
4
|
+
##
|
5
|
+
# Provides event logging with relevant controller/request data.
|
6
|
+
module LoggableController
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
include EventLoggerRails::Extensions::Loggable
|
9
|
+
|
10
|
+
def optional_data
|
11
|
+
{
|
12
|
+
action: action_name,
|
13
|
+
controller: controller_name.camelcase
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
private :optional_data
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EventLoggerRails
|
4
|
+
##
|
5
|
+
# Provides event logging with relevant model data.
|
6
|
+
module LoggableModel
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
include EventLoggerRails::Extensions::Loggable
|
9
|
+
|
10
|
+
def optional_data
|
11
|
+
{
|
12
|
+
model: self.class.name,
|
13
|
+
instance_id: id
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
private :optional_data
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EventLoggerRails
|
4
|
+
##
|
5
|
+
# Processes events, sending data to logger.
|
6
|
+
class Emitter
|
7
|
+
def initialize(logdev:)
|
8
|
+
@logger = JsonLogger.new(logdev)
|
9
|
+
end
|
10
|
+
|
11
|
+
def log(event, level:, data: {})
|
12
|
+
Event.new(event).validate! do |validated_event|
|
13
|
+
message = Message.new(event: validated_event, data:)
|
14
|
+
level = level || validated_event.level || EventLoggerRails.default_level
|
15
|
+
log_message(message, level.to_sym)
|
16
|
+
end
|
17
|
+
rescue Exceptions::UnregisteredEvent, Exceptions::InvalidLoggerLevel => error
|
18
|
+
log(error.event, level: :error, data: { message: error.message })
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :logger
|
24
|
+
|
25
|
+
def log_message(message, level)
|
26
|
+
logger.send(level) { message }
|
27
|
+
rescue NoMethodError
|
28
|
+
raise Exceptions::InvalidLoggerLevel.new(logger_level: level)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -1,7 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module EventLoggerRails
|
4
|
+
##
|
5
|
+
# Engine for plugging into Rails
|
4
6
|
class Engine < ::Rails::Engine
|
5
7
|
isolate_namespace EventLoggerRails
|
8
|
+
|
9
|
+
config.generators do |generator|
|
10
|
+
generator.test_framework :rspec
|
11
|
+
end
|
12
|
+
|
13
|
+
config.event_logger_rails = ActiveSupport::OrderedOptions.new
|
14
|
+
config.event_logger_rails.logdev = "log/event_logger_rails.#{Rails.env}.log"
|
15
|
+
config.event_logger_rails.default_level = :warn
|
16
|
+
|
17
|
+
initializer 'event_logger_rails.add_middleware' do |app|
|
18
|
+
app.middleware.use Middleware::CaptureRequestDetails
|
19
|
+
end
|
20
|
+
|
21
|
+
config.after_initialize do |app|
|
22
|
+
EventLoggerRails.setup do |engine|
|
23
|
+
engine.default_level = app.config.event_logger_rails.default_level
|
24
|
+
engine.logdev = app.config.event_logger_rails.logdev
|
25
|
+
engine.registered_events = Rails.application.config_for(:event_logger_rails)
|
26
|
+
engine.sensitive_fields = app.config.filter_parameters
|
27
|
+
end
|
28
|
+
end
|
6
29
|
end
|
7
30
|
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EventLoggerRails
|
4
|
+
##
|
5
|
+
# Models an event for logging.
|
6
|
+
class Event
|
7
|
+
DEFAULT_EVENTS = {
|
8
|
+
'event_logger_rails.logger_level.invalid' => {
|
9
|
+
description: 'Indicates provided level was invalid.',
|
10
|
+
level: :error
|
11
|
+
},
|
12
|
+
'event_logger_rails.event.unregistered' => {
|
13
|
+
description: 'Indicates provided event was unregistered.',
|
14
|
+
level: :error
|
15
|
+
},
|
16
|
+
'event_logger_rails.event.testing' => {
|
17
|
+
description: 'Event reserved for testing.',
|
18
|
+
level: :warn
|
19
|
+
}
|
20
|
+
}.freeze
|
21
|
+
private_constant :DEFAULT_EVENTS
|
22
|
+
|
23
|
+
attr_reader :identifier, :description, :level
|
24
|
+
|
25
|
+
def initialize(provided_identifier)
|
26
|
+
@provided_identifier = provided_identifier.to_s
|
27
|
+
|
28
|
+
if (default_event = DEFAULT_EVENTS[@provided_identifier])
|
29
|
+
default_registration = [@provided_identifier, *default_event&.values]
|
30
|
+
end
|
31
|
+
|
32
|
+
@identifier, @description, @level = default_registration || config_registration
|
33
|
+
end
|
34
|
+
|
35
|
+
def merge(...)
|
36
|
+
to_hash.merge(...)
|
37
|
+
end
|
38
|
+
|
39
|
+
def valid?
|
40
|
+
identifier.present?
|
41
|
+
end
|
42
|
+
|
43
|
+
def validate!
|
44
|
+
raise Exceptions::UnregisteredEvent.new(unregistered_event: self) unless valid?
|
45
|
+
|
46
|
+
yield(self)
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_hash
|
50
|
+
{
|
51
|
+
event_identifier: identifier,
|
52
|
+
event_description: description
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_s
|
57
|
+
identifier&.to_s || provided_identifier.to_s
|
58
|
+
end
|
59
|
+
|
60
|
+
def ==(other)
|
61
|
+
to_s == other.to_s
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
attr_reader :provided_identifier
|
67
|
+
|
68
|
+
def config_registration
|
69
|
+
parsed_event = provided_identifier.split('.').map(&:to_sym)
|
70
|
+
config = EventLoggerRails.registered_events.dig(*parsed_event)
|
71
|
+
case config
|
72
|
+
in { description:, level: }
|
73
|
+
[provided_identifier, description, level]
|
74
|
+
in { description: }
|
75
|
+
[provided_identifier, description, nil]
|
76
|
+
else
|
77
|
+
[nil, nil, nil]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -5,11 +5,22 @@ module EventLoggerRails
|
|
5
5
|
##
|
6
6
|
# Indicates invalid log level provided.
|
7
7
|
class InvalidLoggerLevel < StandardError
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :event
|
9
9
|
|
10
10
|
def initialize(logger_level:)
|
11
|
-
super
|
11
|
+
super
|
12
|
+
@event = Event.new('event_logger_rails.logger_level.invalid')
|
13
|
+
@logger_level = logger_level
|
14
|
+
end
|
15
|
+
|
16
|
+
def message
|
17
|
+
"Invalid logger level provided: '#{logger_level.to_sym}'. " \
|
18
|
+
'Valid levels: :debug, :info, :warn, :error, :unknown.'
|
12
19
|
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
attr_reader :logger_level
|
13
24
|
end
|
14
25
|
end
|
15
26
|
end
|
@@ -5,11 +5,21 @@ module EventLoggerRails
|
|
5
5
|
##
|
6
6
|
# Indicates event provided not registered.
|
7
7
|
class UnregisteredEvent < StandardError
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :event
|
9
9
|
|
10
10
|
def initialize(unregistered_event:)
|
11
|
-
super(
|
11
|
+
super()
|
12
|
+
@event = Event.new('event_logger_rails.event.unregistered')
|
13
|
+
@unregistered_event = unregistered_event
|
14
|
+
end
|
15
|
+
|
16
|
+
def message
|
17
|
+
"Event provided not registered: #{unregistered_event}"
|
12
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :unregistered_event
|
13
23
|
end
|
14
24
|
end
|
15
25
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EventLoggerRails
|
4
|
+
module Extensions
|
5
|
+
##
|
6
|
+
# Provides event logging with relevant model data.
|
7
|
+
module Loggable
|
8
|
+
def log_event(event, **kwargs)
|
9
|
+
EventLoggerRails.log(
|
10
|
+
event,
|
11
|
+
level: kwargs[:level] || nil,
|
12
|
+
data: (kwargs[:data] || {}).merge(optional_data)
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def optional_data
|
19
|
+
{}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EventLoggerRails
|
4
|
+
##
|
5
|
+
# Writes log entries in JSON format
|
6
|
+
class JsonLogger < ::Logger
|
7
|
+
def initialize(...)
|
8
|
+
super(...)
|
9
|
+
@formatter = proc do |level, timestamp, _progname, message|
|
10
|
+
output = Output.new(level:, timestamp:, message:)
|
11
|
+
"#{output.to_json}\n"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EventLoggerRails
|
4
|
+
##
|
5
|
+
# Models a message sent to the logger containing event and optional data
|
6
|
+
class Message
|
7
|
+
def initialize(event:, data: {})
|
8
|
+
@event = event
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_hash
|
13
|
+
event.merge(data)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
attr_reader :event, :data
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../current_request'
|
4
|
+
|
5
|
+
module EventLoggerRails
|
6
|
+
module Middleware
|
7
|
+
##
|
8
|
+
# Middleware to capture request details and store in global state
|
9
|
+
class CaptureRequestDetails
|
10
|
+
def initialize(app)
|
11
|
+
@app = app
|
12
|
+
end
|
13
|
+
|
14
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
15
|
+
def call(env)
|
16
|
+
begin
|
17
|
+
request = ActionDispatch::Request.new(env)
|
18
|
+
|
19
|
+
CurrentRequest.id = env['action_dispatch.request_id']
|
20
|
+
CurrentRequest.format = request.headers['Content-Type']
|
21
|
+
CurrentRequest.method = request.method
|
22
|
+
CurrentRequest.parameters = request.parameters.except(:controller, :action, :format)
|
23
|
+
CurrentRequest.path = request.path
|
24
|
+
CurrentRequest.remote_ip = request.remote_ip
|
25
|
+
|
26
|
+
status, headers, body = @app.call(env)
|
27
|
+
ensure
|
28
|
+
CurrentRequest.reset
|
29
|
+
end
|
30
|
+
|
31
|
+
[status, headers, body]
|
32
|
+
end
|
33
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EventLoggerRails
|
4
|
+
##
|
5
|
+
# Merges data from application, request, and logger message for structured output
|
6
|
+
class Output
|
7
|
+
def initialize(level:, timestamp:, message:)
|
8
|
+
@current_request = EventLoggerRails::CurrentRequest
|
9
|
+
@level = level
|
10
|
+
@timestamp = timestamp.iso8601(3)
|
11
|
+
@message = message.respond_to?(:to_hash) ? sanitizer.filter(**message) : { message: }
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_json(*args)
|
15
|
+
JSON.generate(to_hash, *args)
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_hash
|
19
|
+
application_data.merge(**current_request_data, **logger_data)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
attr_reader :level, :timestamp, :message, :current_request
|
25
|
+
|
26
|
+
def sanitizer
|
27
|
+
@sanitizer ||= ActiveSupport::ParameterFilter.new(EventLoggerRails.sensitive_fields)
|
28
|
+
end
|
29
|
+
|
30
|
+
def application_data
|
31
|
+
{
|
32
|
+
environment: Rails.env,
|
33
|
+
host: Socket.gethostname,
|
34
|
+
service_name: Rails.application.class.module_parent_name
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
# rubocop:disable Metrics/AbcSize
|
39
|
+
def current_request_data
|
40
|
+
return {} if CurrentRequest.instance.attributes.blank?
|
41
|
+
|
42
|
+
{
|
43
|
+
format: current_request.format,
|
44
|
+
id: current_request.id,
|
45
|
+
method: current_request.method,
|
46
|
+
parameters: sanitizer.filter(current_request.parameters),
|
47
|
+
path: current_request.path,
|
48
|
+
remote_ip: current_request.remote_ip
|
49
|
+
}
|
50
|
+
end
|
51
|
+
# rubocop:enable Metrics/AbcSize
|
52
|
+
|
53
|
+
def logger_data
|
54
|
+
{
|
55
|
+
level:,
|
56
|
+
timestamp:,
|
57
|
+
**message
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/event_logger_rails.rb
CHANGED
@@ -2,24 +2,40 @@
|
|
2
2
|
|
3
3
|
require 'rails'
|
4
4
|
require 'active_support/dependencies'
|
5
|
-
require 'event_logger_rails/version'
|
6
5
|
require 'event_logger_rails/engine'
|
7
|
-
require 'event_logger_rails/
|
6
|
+
require 'event_logger_rails/current_request'
|
7
|
+
require 'event_logger_rails/event'
|
8
|
+
require 'event_logger_rails/emitter'
|
8
9
|
require 'event_logger_rails/exceptions/invalid_logger_level'
|
9
10
|
require 'event_logger_rails/exceptions/unregistered_event'
|
11
|
+
require 'event_logger_rails/extensions/loggable'
|
12
|
+
require 'event_logger_rails/json_logger'
|
13
|
+
require 'event_logger_rails/message'
|
14
|
+
require 'event_logger_rails/middleware/capture_request_details'
|
15
|
+
require 'event_logger_rails/output'
|
16
|
+
require 'event_logger_rails/version'
|
10
17
|
|
11
18
|
##
|
12
|
-
# Namespace for
|
19
|
+
# Namespace for EventLoggerRails gem
|
13
20
|
module EventLoggerRails
|
14
|
-
|
15
|
-
|
16
|
-
|
21
|
+
mattr_accessor :default_level
|
22
|
+
mattr_accessor :logdev
|
23
|
+
mattr_accessor :registered_events
|
24
|
+
mattr_accessor :sensitive_fields
|
25
|
+
|
26
|
+
def self.setup
|
27
|
+
yield self
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.emitter
|
31
|
+
@emitter ||= Emitter.new(logdev:)
|
32
|
+
end
|
17
33
|
|
18
|
-
def self.
|
19
|
-
|
34
|
+
def self.log(...)
|
35
|
+
emitter.log(...)
|
20
36
|
end
|
21
37
|
|
22
|
-
def self.
|
23
|
-
|
38
|
+
def self.reset
|
39
|
+
@emitter = nil
|
24
40
|
end
|
25
41
|
end
|
@@ -1,14 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'rails/generators'
|
4
|
+
|
3
5
|
module EventLoggerRails
|
4
6
|
module Generators
|
5
7
|
##
|
6
|
-
# Creates basic config file for EventLoggerRails
|
8
|
+
# Creates basic config file and initializer for EventLoggerRails
|
7
9
|
class InstallGenerator < Rails::Generators::Base
|
8
|
-
desc 'Create
|
10
|
+
desc 'Create event registry file'
|
9
11
|
source_root File.expand_path('templates', __dir__)
|
10
12
|
|
11
13
|
def copy_config_file
|
14
|
+
return if File.exist?(File.join(destination_root, 'config/event_logger_rails.yml'))
|
15
|
+
|
12
16
|
copy_file 'event_logger_rails.yml', 'config/event_logger_rails.yml'
|
13
17
|
end
|
14
18
|
end
|
@@ -1,15 +1,3 @@
|
|
1
|
-
##
|
2
|
-
# Allowed logger levels for use with EventLoggerRails
|
3
|
-
# You can add/remove levels, if desired; however, an exception will occur
|
4
|
-
# when using a logger level that is not enumerated here.
|
5
|
-
#
|
6
|
-
logger_levels:
|
7
|
-
- 'debug'
|
8
|
-
- 'info'
|
9
|
-
- 'warn'
|
10
|
-
- 'error'
|
11
|
-
- 'fatal'
|
12
|
-
|
13
1
|
##
|
14
2
|
# Registered events for use with EventLoggerRails
|
15
3
|
# Add your custom event definitions to this section; attempting to log events
|
@@ -17,9 +5,23 @@ logger_levels:
|
|
17
5
|
#
|
18
6
|
# Example event:
|
19
7
|
#
|
20
|
-
#
|
8
|
+
# shared:
|
21
9
|
# user:
|
22
10
|
# signup:
|
23
|
-
# success:
|
11
|
+
# success:
|
12
|
+
# description: 'Indicates a successful user signup.'
|
13
|
+
# failure:
|
14
|
+
# description: 'Indicates a user signup was not successful.'
|
15
|
+
# level: 'error'
|
16
|
+
#
|
17
|
+
shared:
|
18
|
+
|
19
|
+
##
|
20
|
+
# Add events that are unique to specific environments by uncommenting the appropriate
|
21
|
+
# environment and adding the event.
|
22
|
+
#
|
23
|
+
# development:
|
24
|
+
#
|
25
|
+
# test:
|
24
26
|
#
|
25
|
-
|
27
|
+
# production:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: event_logger_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dick Davis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -24,7 +24,9 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 7.0.0
|
27
|
-
description:
|
27
|
+
description: |
|
28
|
+
EventLoggerRails is a Rails engine for emitting structured events in logs during the execution of business processes for analysis and visualization.
|
29
|
+
It allows teams to define events in a simple, centralized configuration file, and then log those events in JSON format for further processing.
|
28
30
|
email:
|
29
31
|
- dick@hey.com
|
30
32
|
executables: []
|
@@ -33,25 +35,33 @@ extra_rdoc_files: []
|
|
33
35
|
files:
|
34
36
|
- README.md
|
35
37
|
- Rakefile
|
36
|
-
- app/controllers/concerns/event_logger_rails/
|
38
|
+
- app/controllers/concerns/event_logger_rails/loggable_controller.rb
|
39
|
+
- app/models/concerns/event_logger_rails/loggable_model.rb
|
37
40
|
- config/routes.rb
|
38
41
|
- lib/event_logger_rails.rb
|
42
|
+
- lib/event_logger_rails/current_request.rb
|
43
|
+
- lib/event_logger_rails/emitter.rb
|
39
44
|
- lib/event_logger_rails/engine.rb
|
40
|
-
- lib/event_logger_rails/
|
45
|
+
- lib/event_logger_rails/event.rb
|
41
46
|
- lib/event_logger_rails/exceptions/invalid_logger_level.rb
|
42
47
|
- lib/event_logger_rails/exceptions/unregistered_event.rb
|
48
|
+
- lib/event_logger_rails/extensions/loggable.rb
|
49
|
+
- lib/event_logger_rails/json_logger.rb
|
50
|
+
- lib/event_logger_rails/message.rb
|
51
|
+
- lib/event_logger_rails/middleware/capture_request_details.rb
|
52
|
+
- lib/event_logger_rails/output.rb
|
43
53
|
- lib/event_logger_rails/version.rb
|
44
54
|
- lib/generators/event_logger_rails/install_generator.rb
|
45
55
|
- lib/generators/event_logger_rails/templates/event_logger_rails.yml
|
46
56
|
- lib/tasks/event_logger_rails_tasks.rake
|
47
|
-
homepage: https://github.com/
|
57
|
+
homepage: https://github.com/dickdavis/event_logger_rails
|
48
58
|
licenses:
|
49
59
|
- MIT
|
50
60
|
metadata:
|
51
61
|
rubygems_mfa_required: 'true'
|
52
|
-
homepage_uri: https://github.com/
|
53
|
-
source_code_uri: https://github.com/
|
54
|
-
changelog_uri: https://github.com/
|
62
|
+
homepage_uri: https://github.com/dickdavis/event_logger_rails
|
63
|
+
source_code_uri: https://github.com/dickdavis/event_logger_rails/tree/0.3.0
|
64
|
+
changelog_uri: https://github.com/dickdavis/event_logger_rails/blob/0.3.0/CHANGELOG.md
|
55
65
|
post_install_message:
|
56
66
|
rdoc_options: []
|
57
67
|
require_paths:
|
@@ -60,15 +70,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
60
70
|
requirements:
|
61
71
|
- - ">="
|
62
72
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
73
|
+
version: 3.1.4
|
64
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
75
|
requirements:
|
66
76
|
- - ">="
|
67
77
|
- !ruby/object:Gem::Version
|
68
78
|
version: '0'
|
69
79
|
requirements: []
|
70
|
-
rubygems_version: 3.
|
80
|
+
rubygems_version: 3.3.26
|
71
81
|
signing_key:
|
72
82
|
specification_version: 4
|
73
|
-
summary: Rails gem
|
83
|
+
summary: Rails gem weaving the fabric of logged events into tapestries for analytic
|
84
|
+
reverie.
|
74
85
|
test_files: []
|
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module EventLoggerRails
|
4
|
-
##
|
5
|
-
# Provides event logging with relevant controller/request data.
|
6
|
-
module Loggable
|
7
|
-
extend ActiveSupport::Concern
|
8
|
-
|
9
|
-
def log_event(level, event, **data)
|
10
|
-
data_to_log = data_from_request.merge(data)
|
11
|
-
EventLoggerRails.log(level, event, **data_to_log)
|
12
|
-
rescue EventLoggerRails::Exceptions::UnregisteredEvent => e
|
13
|
-
log_event :error, 'event_logger_rails.event.unregistered', message: e.message
|
14
|
-
rescue EventLoggerRails::Exceptions::InvalidLoggerLevel => e
|
15
|
-
log_event :error, 'event_logger_rails.logger_level.invalid', message: e.message
|
16
|
-
end
|
17
|
-
|
18
|
-
def data_from_request
|
19
|
-
{
|
20
|
-
controller: controller_name.camelcase,
|
21
|
-
action: action_name,
|
22
|
-
method: request.method,
|
23
|
-
path: request.path,
|
24
|
-
remote_ip: request.remote_ip,
|
25
|
-
parameters: request.query_parameters.to_json
|
26
|
-
}
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
@@ -1,97 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'yaml'
|
4
|
-
|
5
|
-
require_relative 'exceptions/invalid_logger_level'
|
6
|
-
require_relative 'exceptions/unregistered_event'
|
7
|
-
|
8
|
-
module EventLoggerRails
|
9
|
-
##
|
10
|
-
# Outputs event and related data logs.
|
11
|
-
class EventLogger
|
12
|
-
DEFAULT_EVENTS = [
|
13
|
-
'event_logger_rails.logger_level.invalid',
|
14
|
-
'event_logger_rails.event.unregistered',
|
15
|
-
'event_logger_rails.event.testing'
|
16
|
-
].freeze
|
17
|
-
private_constant :DEFAULT_EVENTS
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
@logger_levels = logger_levels_from_config
|
21
|
-
@registered_events = registered_events_from_config
|
22
|
-
@last_updated = File.ctime(config_file)
|
23
|
-
end
|
24
|
-
|
25
|
-
def log(*tags, **params)
|
26
|
-
reload_config if config_changed?
|
27
|
-
|
28
|
-
level, event = *tags
|
29
|
-
validate_tags(level, event)
|
30
|
-
logger = ActiveSupport::TaggedLogging.new(Logger.new(output_device))
|
31
|
-
logger.tagged("#{level.to_s.upcase} | #{DateTime.current} | #{event}") { logger.send(level, **params.as_json) }
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
attr_reader :logger_levels, :registered_events, :last_updated
|
37
|
-
|
38
|
-
def logger_levels_from_config
|
39
|
-
data_from_config[:logger_levels].map(&:to_sym)
|
40
|
-
end
|
41
|
-
|
42
|
-
def registered_events_from_config
|
43
|
-
data_from_config[:registered_events]
|
44
|
-
end
|
45
|
-
|
46
|
-
def data_from_config
|
47
|
-
YAML.safe_load(File.read(config_file)).deep_symbolize_keys
|
48
|
-
end
|
49
|
-
|
50
|
-
def config_file
|
51
|
-
Rails.root.join('config/event_logger_rails.yml')
|
52
|
-
end
|
53
|
-
|
54
|
-
def reload_config
|
55
|
-
@logger_levels = logger_levels_from_config
|
56
|
-
@registered_events = registered_events_from_config
|
57
|
-
@last_updated = File.ctime(config_file)
|
58
|
-
end
|
59
|
-
|
60
|
-
def config_changed?
|
61
|
-
return false unless Rails.env.development?
|
62
|
-
|
63
|
-
last_updated != File.ctime(config_file)
|
64
|
-
end
|
65
|
-
|
66
|
-
def validate_tags(level, event)
|
67
|
-
validate_logger_level(level) && validate_event(event)
|
68
|
-
end
|
69
|
-
|
70
|
-
def validate_logger_level(level)
|
71
|
-
return true if logger_levels.include?(level)
|
72
|
-
|
73
|
-
raise EventLoggerRails::Exceptions::InvalidLoggerLevel.new(logger_level: level)
|
74
|
-
end
|
75
|
-
|
76
|
-
def validate_event(event)
|
77
|
-
return true if event_registered?(event) || default_event?(event)
|
78
|
-
|
79
|
-
raise EventLoggerRails::Exceptions::UnregisteredEvent.new(unregistered_event: event)
|
80
|
-
end
|
81
|
-
|
82
|
-
def event_registered?(event)
|
83
|
-
parsed_event = event.split('.').map(&:to_sym)
|
84
|
-
registered_events.dig(*parsed_event)
|
85
|
-
end
|
86
|
-
|
87
|
-
def default_event?(event)
|
88
|
-
DEFAULT_EVENTS.include?(event)
|
89
|
-
end
|
90
|
-
|
91
|
-
def output_device
|
92
|
-
return $stdout unless Rails.env.test?
|
93
|
-
|
94
|
-
File.open(File::NULL, 'w')
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|