twiglet 3.1.0 → 3.2.1

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: 120d52bf23086d2db6f65f068aa087835914bcfe52c3ef1f8b6b886f946e9dcd
4
- data.tar.gz: 8355c113e09882c4b1346111bba954b82f81d69c0290d1055dca4bb61174fc09
3
+ metadata.gz: 64fa676db51b4a53f17a7f1ff578ba00b670c2df9100b6972f2cf4b6fb51c1fc
4
+ data.tar.gz: 014044c6cccb28d13d019a26715ad83a5532e38b5f4df7ecf9a9a211eaec6751
5
5
  SHA512:
6
- metadata.gz: 65ca30c0dcf26b8190b7840b70bd5a183b481333bc98af0abfed2835a5a25ec664e2b3c24f10d90f40a6a1d5a18fb90d9f97c2c2aae0ab49b123558049cc11da
7
- data.tar.gz: 5936e07ac730cd18b39b5777a3fd1a7b8d805852726ad2732d46d6acdb1c7ef820f7dacf87ba68a85352dd3653c0e49b132a90ad71a40dd7ebdc3744ff9e68b8
6
+ metadata.gz: 3d771c2182011b62d5d5af36a55fb04069a2f19805733df475b2f8d0e93e9ccdffdbac81c24eda8ba2081950812b94f87673c931776b65a125fb973106ce1210
7
+ data.tar.gz: 01c66f316cabc1b1169d35ca224d2c35f5e79efab580df3c530deaddcf30f8b23a46549ffc46140540408fc8c60c916ea72cb1c67122d32233b633786c8289c8
@@ -1,4 +1,4 @@
1
- name: "version update action"
1
+ name: "dobby action"
2
2
  on:
3
3
  issue_comment:
4
4
  types: [created]
@@ -8,8 +8,9 @@ jobs:
8
8
  if: startsWith(github.event.comment.body, '/dobby')
9
9
 
10
10
  steps:
11
- - name: 'bump version'
12
- uses: simplybusiness/dobby@v1.0.0
11
+ - name: bump version
12
+ uses: simplybusiness/dobby@v2.0.0
13
13
  env:
14
- ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
14
+ DOBBY_APP_ID: ${{ secrets.DOBBY_APP_ID }}
15
+ DOBBY_PRIVATE_KEY: ${{ secrets.DOBBY_PRIVATE_KEY }}
15
16
  VERSION_FILE_PATH: lib/twiglet/version.rb
data/Gemfile CHANGED
@@ -2,11 +2,4 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
- gem 'json-schema'
6
-
7
- group :development, :test do
8
- gem 'minitest'
9
- gem 'rake'
10
- gem 'simplecov', '0.17.1'
11
- gem 'simplycop'
12
- end
5
+ gemspec
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
 
@@ -1,7 +1,6 @@
1
1
  require 'logger'
2
2
  require_relative '../hash_extensions'
3
3
  require_relative 'message'
4
- require_relative 'validator'
5
4
 
6
5
  module Twiglet
7
6
  class Formatter < ::Logger::Formatter
@@ -2,10 +2,10 @@
2
2
 
3
3
  require 'logger'
4
4
  require 'time'
5
- require 'json'
6
5
  require_relative 'formatter'
7
6
  require_relative '../hash_extensions'
8
7
  require_relative 'message'
8
+ require_relative 'validator'
9
9
 
10
10
  module Twiglet
11
11
  class Logger < ::Logger
@@ -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, Logger::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('lib/twiglet/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.0'
4
+ VERSION = '3.2.1'
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
@@ -380,6 +380,61 @@ describe Twiglet::Logger do
380
380
  end
381
381
  end
382
382
 
383
+ describe 'validation schema' do
384
+ before do
385
+ validation_schema = <<-JSON
386
+ {
387
+ "type": "object",
388
+ "required": ["pet"],
389
+ "properties": {
390
+ "pet": {
391
+ "type": "object",
392
+ "required": ["name", "best_boy_or_girl?"],
393
+ "properties": {
394
+ "name": {
395
+ "type": "string",
396
+ "minLength": 1
397
+ },
398
+ "best_boy_or_girl?": {
399
+ "type": "boolean"
400
+ }
401
+ }
402
+ }
403
+ }
404
+ }
405
+ JSON
406
+
407
+ @logger = Twiglet::Logger.new(
408
+ 'petshop',
409
+ now: @now,
410
+ output: @buffer,
411
+ validation_schema: validation_schema
412
+ )
413
+ end
414
+
415
+ it 'allows for the configuration of custom validation rules' do
416
+ @logger.debug(
417
+ {
418
+ pet: { name: 'Davis', best_boy_or_girl?: true, species: 'dog' }
419
+ }
420
+ )
421
+ log = read_json(@buffer)
422
+
423
+ assert_equal true, log[:pet][:best_boy_or_girl?]
424
+ end
425
+
426
+ it 'raises when custom validation rules are broken' do
427
+ nonconformant = {
428
+ pet: { name: 'Davis' }
429
+ }
430
+
431
+ assert_raises JSON::Schema::ValidationError,
432
+ "The property '#/pet' did not contain a required property of 'best_boy_or_girl?'" do
433
+ @logger.debug(nonconformant)
434
+ end
435
+ end
436
+ end
437
+
383
438
  private
384
439
 
385
440
  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
data/twiglet.gemspec CHANGED
@@ -21,4 +21,10 @@ Gem::Specification.new do |gem|
21
21
  gem.required_ruby_version = '>= 2.6'
22
22
 
23
23
  gem.license = 'Copyright SimplyBusiness'
24
+
25
+ gem.add_runtime_dependency 'json-schema'
26
+ gem.add_development_dependency 'minitest'
27
+ gem.add_development_dependency 'rake'
28
+ gem.add_development_dependency 'simplecov', '0.17.1'
29
+ gem.add_development_dependency 'simplycop'
24
30
  end
metadata CHANGED
@@ -1,15 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: twiglet
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.1
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-15 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-02-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json-schema
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 0.17.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 0.17.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplycop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
13
83
  description: Like a log, only smaller.
14
84
  email:
15
85
  - tech@simplybusiness.co.uk
@@ -19,10 +89,10 @@ extra_rdoc_files: []
19
89
  files:
20
90
  - ".github/CODEOWNERS"
21
91
  - ".github/dependabot.yml"
92
+ - ".github/workflows/dobby-actions.yml"
22
93
  - ".github/workflows/gem-publish.yml"
23
94
  - ".github/workflows/ruby.yml"
24
95
  - ".github/workflows/version-forget-me-not.yml"
25
- - ".github/workflows/version-update.yml"
26
96
  - ".gitignore"
27
97
  - ".rubocop.yml"
28
98
  - ".ruby-version"