twiglet 3.1.3 → 3.2.5
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/.github/workflows/dobby-actions.yml +1 -1
- data/.github/workflows/version-forget-me-not.yml +1 -1
- data/README.md +66 -1
- data/examples/rack/request_logger_test.rb +1 -1
- data/lib/hash_extensions.rb +1 -1
- data/lib/twiglet/logger.rb +12 -14
- data/lib/twiglet/validator.rb +1 -5
- data/lib/twiglet/version.rb +1 -1
- data/test/formatter_test.rb +1 -1
- data/test/logger_test.rb +66 -0
- data/test/validator_test.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98f1c6b47cc30e450a1318ea8040d210cb1af5103124fbeee26bb4b5c5ccbb36
|
4
|
+
data.tar.gz: 4a1affb0ad177358ac4b66e33326b39e089fdf8bb63cee4e78593db3a2fd4109
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf39d61c9cdf97257a040ee3246facd81c3376a656e024817c7abc96153fce7404138b022923aafc4ba84b54c85a74553cdc59ca19dc88af0d5ea5b71e3ef171
|
7
|
+
data.tar.gz: 6d17f9991a7535f4083138cf1c65861e4890c0d4ef3a19cf0c14931d5766afb09136a7d56fbb7a782b166270eeb8fbeb74a6671b1301fc10cfe83f7ddb23085e
|
data/README.md
CHANGED
@@ -144,7 +144,72 @@ logger.formatter
|
|
144
144
|
Take a look at this sample [Rack application](examples/rack/example_rack_app.rb#L15) with an ECS compliant
|
145
145
|
[request logger](/examples/rack/request_logger.rb) as a template when configuring your own request logging middleware with Twiglet.
|
146
146
|
|
147
|
-
|
147
|
+
### Log format validation
|
148
|
+
Twiglet allows for the configuration of a custom validation schema. The validation schema must be [JSON Schema](https://json-schema.org/) compliant. Any fields not explicitly included in the provided schema are permitted by default.
|
149
|
+
|
150
|
+
For example, given the following JSON Schema:
|
151
|
+
```ruby
|
152
|
+
validation_schema = <<-JSON
|
153
|
+
{
|
154
|
+
"type": "object",
|
155
|
+
"required": ["pet"],
|
156
|
+
"properties": {
|
157
|
+
"pet": {
|
158
|
+
"type": "object",
|
159
|
+
"required": ["name", "best_boy_or_girl?"],
|
160
|
+
"properties": {
|
161
|
+
"name": {
|
162
|
+
"type": "string",
|
163
|
+
"minLength": 1
|
164
|
+
},
|
165
|
+
"good_boy?": {
|
166
|
+
"type": "boolean"
|
167
|
+
}
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
JSON
|
173
|
+
```
|
174
|
+
|
175
|
+
The logger can be instantiated with the custom schema
|
176
|
+
```ruby
|
177
|
+
custom_logger = Twiglet::Logger.new('service name', validation_schema: validation_schema)
|
178
|
+
```
|
179
|
+
|
180
|
+
Compliant log messages will log as normal.
|
181
|
+
```ruby
|
182
|
+
# this is compliant
|
183
|
+
custom_logger.debug(pet: { name: 'Davis', good_boy?: true })
|
184
|
+
|
185
|
+
# the result
|
186
|
+
{:ecs=>{:version=>"1.5.0"}, :@timestamp=>"2020-05-11T15:01:01.000Z", :service=>{:name=>"petshop"}, :log=>{:level=>"debug"}, :pet=>{:name=>"Davis", :good_boy?=>true}}
|
187
|
+
```
|
188
|
+
|
189
|
+
Non compliant messages will raise an error.
|
190
|
+
```ruby
|
191
|
+
begin
|
192
|
+
custom_logger.debug(pet: { name: 'Davis' })
|
193
|
+
rescue JSON::Schema::ValidationError
|
194
|
+
# we forgot to specify that he's a good boy!
|
195
|
+
puts 'uh-oh'
|
196
|
+
end
|
197
|
+
```
|
198
|
+
|
199
|
+
#### Customizing error responses
|
200
|
+
Depending on the application, it may not be desirable for the logger to raise Runtime errors. Twiglet allows you to configure a custom response for handling validation errors.
|
201
|
+
|
202
|
+
Configure error handling by writing a block
|
203
|
+
```ruby
|
204
|
+
logger.configure_validation_error_response do |error|
|
205
|
+
# validation error handling goes here
|
206
|
+
# for example:
|
207
|
+
{YOUR APPLICATION BUG TRACKING SERVICE}.notify_error(error)
|
208
|
+
end
|
209
|
+
|
210
|
+
```
|
211
|
+
|
212
|
+
### Use of dotted keys (DEPRECATED)
|
148
213
|
|
149
214
|
Writing nested json objects could be confusing. This library has a built-in feature to convert dotted keys into nested objects, so if you log like this:
|
150
215
|
|
@@ -65,7 +65,7 @@ describe RequestLogger do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
it 'logs an error message when a request is bad' do
|
68
|
-
|
68
|
+
expect { bad_request.get("/some/path") }.must_raise StandardError
|
69
69
|
log = JSON.parse(output.string)
|
70
70
|
assert_equal log['log']['level'], 'error'
|
71
71
|
assert_equal log['error']['message'], 'some exception'
|
data/lib/hash_extensions.rb
CHANGED
data/lib/twiglet/logger.rb
CHANGED
@@ -13,28 +13,29 @@ module Twiglet
|
|
13
13
|
|
14
14
|
def initialize(
|
15
15
|
service_name,
|
16
|
-
|
17
|
-
now: -> { Time.now.utc },
|
18
|
-
output: $stdout,
|
19
|
-
level: Logger::DEBUG
|
16
|
+
**args
|
20
17
|
)
|
21
18
|
@service_name = service_name
|
22
|
-
|
23
|
-
@
|
24
|
-
|
19
|
+
default_properties = args.delete(:default_properties) || {}
|
20
|
+
@args = args
|
21
|
+
|
22
|
+
now = args.fetch(:now, -> { Time.now.utc })
|
23
|
+
output = args.fetch(:output, $stdout)
|
24
|
+
level = args.fetch(:level, DEBUG)
|
25
|
+
validation_schema = args.fetch(:validation_schema, File.read("#{__dir__}/validation_schema.json"))
|
25
26
|
|
26
27
|
raise 'Service name is mandatory' \
|
27
28
|
unless service_name.is_a?(String) && !service_name.strip.empty?
|
28
29
|
|
29
|
-
@validator = Validator.
|
30
|
+
@validator = Validator.new(validation_schema)
|
30
31
|
|
31
|
-
|
32
|
+
formatter = Twiglet::Formatter.new(
|
32
33
|
service_name,
|
33
34
|
default_properties: default_properties,
|
34
35
|
now: now,
|
35
36
|
validator: @validator
|
36
37
|
)
|
37
|
-
super(output, formatter:
|
38
|
+
super(output, formatter: formatter, level: level)
|
38
39
|
end
|
39
40
|
|
40
41
|
def configure_validation_error_response(&block)
|
@@ -59,10 +60,7 @@ module Twiglet
|
|
59
60
|
def with(default_properties)
|
60
61
|
Logger.new(
|
61
62
|
@service_name,
|
62
|
-
default_properties: default_properties
|
63
|
-
now: @now,
|
64
|
-
output: @output,
|
65
|
-
level: @level
|
63
|
+
**@args.merge(default_properties: default_properties)
|
66
64
|
)
|
67
65
|
end
|
68
66
|
|
data/lib/twiglet/validator.rb
CHANGED
@@ -8,14 +8,10 @@ module Twiglet
|
|
8
8
|
attr_accessor :custom_error_handler
|
9
9
|
|
10
10
|
def initialize(schema)
|
11
|
-
@schema = schema
|
11
|
+
@schema = JSON.parse(schema)
|
12
12
|
@custom_error_handler = ->(e) { raise e }
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.from_file(file_path)
|
16
|
-
new(JSON.parse(File.read(file_path)))
|
17
|
-
end
|
18
|
-
|
19
15
|
def validate(message)
|
20
16
|
JSON::Validator.validate!(@schema, message)
|
21
17
|
rescue JSON::Schema::ValidationError => e
|
data/lib/twiglet/version.rb
CHANGED
data/test/formatter_test.rb
CHANGED
@@ -8,7 +8,7 @@ require_relative '../lib/twiglet/validator'
|
|
8
8
|
describe Twiglet::Formatter do
|
9
9
|
before do
|
10
10
|
@now = -> { Time.utc(2020, 5, 11, 15, 1, 1) }
|
11
|
-
@formatter = Twiglet::Formatter.new('petshop', now: @now, validator: Twiglet::Validator.new({}))
|
11
|
+
@formatter = Twiglet::Formatter.new('petshop', now: @now, validator: Twiglet::Validator.new({}.to_json))
|
12
12
|
end
|
13
13
|
|
14
14
|
it 'initializes an instance of a Ruby Logger Formatter' do
|
data/test/logger_test.rb
CHANGED
@@ -357,6 +357,17 @@ describe Twiglet::Logger do
|
|
357
357
|
it 'initializes the logger with the provided level' do
|
358
358
|
assert_equal Logger::WARN, Twiglet::Logger.new('petshop', level: :warn).level
|
359
359
|
end
|
360
|
+
|
361
|
+
it 'does not log lower level' do
|
362
|
+
logger = Twiglet::Logger.new(
|
363
|
+
'petshop',
|
364
|
+
now: @now,
|
365
|
+
output: @buffer,
|
366
|
+
level: Logger::INFO
|
367
|
+
)
|
368
|
+
logger.debug({ name: 'Davis', best_boy_or_girl?: true, species: 'dog' })
|
369
|
+
assert_empty @buffer.read
|
370
|
+
end
|
360
371
|
end
|
361
372
|
|
362
373
|
describe 'configuring error response' do
|
@@ -380,6 +391,61 @@ describe Twiglet::Logger do
|
|
380
391
|
end
|
381
392
|
end
|
382
393
|
|
394
|
+
describe 'validation schema' do
|
395
|
+
before do
|
396
|
+
validation_schema = <<-JSON
|
397
|
+
{
|
398
|
+
"type": "object",
|
399
|
+
"required": ["pet"],
|
400
|
+
"properties": {
|
401
|
+
"pet": {
|
402
|
+
"type": "object",
|
403
|
+
"required": ["name", "best_boy_or_girl?"],
|
404
|
+
"properties": {
|
405
|
+
"name": {
|
406
|
+
"type": "string",
|
407
|
+
"minLength": 1
|
408
|
+
},
|
409
|
+
"best_boy_or_girl?": {
|
410
|
+
"type": "boolean"
|
411
|
+
}
|
412
|
+
}
|
413
|
+
}
|
414
|
+
}
|
415
|
+
}
|
416
|
+
JSON
|
417
|
+
|
418
|
+
@logger = Twiglet::Logger.new(
|
419
|
+
'petshop',
|
420
|
+
now: @now,
|
421
|
+
output: @buffer,
|
422
|
+
validation_schema: validation_schema
|
423
|
+
)
|
424
|
+
end
|
425
|
+
|
426
|
+
it 'allows for the configuration of custom validation rules' do
|
427
|
+
@logger.debug(
|
428
|
+
{
|
429
|
+
pet: { name: 'Davis', best_boy_or_girl?: true, species: 'dog' }
|
430
|
+
}
|
431
|
+
)
|
432
|
+
log = read_json(@buffer)
|
433
|
+
|
434
|
+
assert_equal true, log[:pet][:best_boy_or_girl?]
|
435
|
+
end
|
436
|
+
|
437
|
+
it 'raises when custom validation rules are broken' do
|
438
|
+
nonconformant = {
|
439
|
+
pet: { name: 'Davis' }
|
440
|
+
}
|
441
|
+
|
442
|
+
assert_raises JSON::Schema::ValidationError,
|
443
|
+
"The property '#/pet' did not contain a required property of 'best_boy_or_girl?'" do
|
444
|
+
@logger.debug(nonconformant)
|
445
|
+
end
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
383
449
|
private
|
384
450
|
|
385
451
|
def read_json(buffer)
|
data/test/validator_test.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twiglet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simply Business
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json-schema
|
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
141
|
- !ruby/object:Gem::Version
|
142
142
|
version: '0'
|
143
143
|
requirements: []
|
144
|
-
rubygems_version: 3.2.
|
144
|
+
rubygems_version: 3.2.15
|
145
145
|
signing_key:
|
146
146
|
specification_version: 4
|
147
147
|
summary: Twiglet
|