twiglet 3.1.3 → 3.2.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9cace8decdc47857c5ce0bec8ae85b92fe93f866521bc6872371db38999b25c3
4
- data.tar.gz: dc9bf4d673968a4c718af21c117584f7770a3f2d50cc704ff5d39da1bec26626
3
+ metadata.gz: 98f1c6b47cc30e450a1318ea8040d210cb1af5103124fbeee26bb4b5c5ccbb36
4
+ data.tar.gz: 4a1affb0ad177358ac4b66e33326b39e089fdf8bb63cee4e78593db3a2fd4109
5
5
  SHA512:
6
- metadata.gz: 12c4455ae13471d0ebf0899966c9dbd32bf17841c468beaddb0a912a234033921a1694c2007d6a9d1732bdb69dbabc21f88cf98a195b9eea9a9be52d51cc07db
7
- data.tar.gz: 91fab7466ae13a05de15fe66c2b8e4b78b28e2ee31220cd0f427d3928bfd59b15dbec2facc444f5c3a10a29bade3ee568e369fb921360fd6ddbb4c76f80bafd0
6
+ metadata.gz: bf39d61c9cdf97257a040ee3246facd81c3376a656e024817c7abc96153fce7404138b022923aafc4ba84b54c85a74553cdc59ca19dc88af0d5ea5b71e3ef171
7
+ data.tar.gz: 6d17f9991a7535f4083138cf1c65861e4890c0d4ef3a19cf0c14931d5766afb09136a7d56fbb7a782b166270eeb8fbeb74a6671b1301fc10cfe83f7ddb23085e
@@ -9,7 +9,7 @@ jobs:
9
9
 
10
10
  steps:
11
11
  - name: bump version
12
- uses: simplybusiness/dobby@v2.0.0
12
+ uses: simplybusiness/dobby@v2.1.0
13
13
  env:
14
14
  DOBBY_APP_ID: ${{ secrets.DOBBY_APP_ID }}
15
15
  DOBBY_PRIVATE_KEY: ${{ secrets.DOBBY_PRIVATE_KEY }}
@@ -10,7 +10,7 @@ jobs:
10
10
  runs-on: ubuntu-18.04
11
11
 
12
12
  steps:
13
- - uses: simplybusiness/version-forget-me-not@v2
13
+ - uses: simplybusiness/version-forget-me-not@v2.1.0
14
14
  env:
15
15
  ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16
16
  VERSION_FILE_PATH: "lib/twiglet/version.rb"
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
- ## Use of dotted keys (DEPRECATED)
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
- -> { bad_request.get("/some/path") }.must_raise StandardError
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'
@@ -24,6 +24,6 @@ module HashExtensions
24
24
  key.to_s
25
25
  .split('.')
26
26
  .reverse
27
- .reduce(val) { |nested, key_part| Hash[key_part.to_sym, nested] }
27
+ .reduce(val) { |nested, key_part| { key_part.to_sym => nested } }
28
28
  end
29
29
  end
@@ -13,28 +13,29 @@ module Twiglet
13
13
 
14
14
  def initialize(
15
15
  service_name,
16
- default_properties: {},
17
- now: -> { Time.now.utc },
18
- output: $stdout,
19
- level: Logger::DEBUG
16
+ **args
20
17
  )
21
18
  @service_name = service_name
22
- @now = now
23
- @output = output
24
- @level = level
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.from_file("#{__dir__}/validation_schema.json")
30
+ @validator = Validator.new(validation_schema)
30
31
 
31
- @formatter = Twiglet::Formatter.new(
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: @formatter, level: level)
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
 
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Twiglet
4
- VERSION = '3.1.3'
4
+ VERSION = '3.2.5'
5
5
  end
@@ -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)
@@ -17,7 +17,7 @@ describe Twiglet::Validator do
17
17
  }
18
18
  }
19
19
 
20
- @validator = Twiglet::Validator.new(schema)
20
+ @validator = Twiglet::Validator.new(schema.to_json)
21
21
  end
22
22
 
23
23
  it 'does not raise when validation passes' do
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.1.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-02-16 00:00:00.000000000 Z
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.3
144
+ rubygems_version: 3.2.15
145
145
  signing_key:
146
146
  specification_version: 4
147
147
  summary: Twiglet