twiglet 3.4.8 → 3.5.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 +4 -4
- data/.github/workflows/ruby.yml +1 -1
- data/.ruby-version +1 -1
- data/README.md +1 -1
- data/lib/twiglet/formatter.rb +7 -1
- data/lib/twiglet/logger.rb +10 -3
- data/lib/twiglet/version.rb +1 -1
- data/test/formatter_test.rb +26 -0
- data/test/logger_test.rb +109 -0
- 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: 00772aa96a6be0df63c418fc7cc077cf599e9909af51e00be9992bf78d298660
|
4
|
+
data.tar.gz: 479f94b2de093c797e863b66f02287e37d1b1c5aa58931553bdff269844ed792
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17317a0d26e6b66b573e5eeeafc7d4957c6bdb87e70f320279098cb405464e68fe29a56cbe4421663d809cf39b6e7f72d5d5b5c0261fecd59766bf420e928250
|
7
|
+
data.tar.gz: 222e608e335c4a6406e08376356f1cd7e42c89ea09f7d4eba6432fc33aa26d614421f60ef123d45b2eed73ab334741b50fbf096ee17631f38dbf8930cb4c4397
|
data/.github/workflows/ruby.yml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.6
|
1
|
+
2.7.6
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Twiglet: Ruby version
|
2
2
|
Like a log, only smaller.
|
3
3
|
|
4
|
-
This library provides a minimal JSON logging interface suitable for use in (micro)services. See the [RATIONALE](RATIONALE.md) for design rationale and an explantion of the Elastic Common Schema that we are using for log attribute naming.
|
4
|
+
This library provides a minimal JSON logging interface suitable for use in (micro)services. See the [RATIONALE](docs/RATIONALE.md) for design rationale and an explantion of the Elastic Common Schema that we are using for log attribute naming.
|
5
5
|
|
6
6
|
See [Full docs](docs/index.md)
|
data/lib/twiglet/formatter.rb
CHANGED
@@ -7,11 +7,14 @@ module Twiglet
|
|
7
7
|
Hash.include HashExtensions
|
8
8
|
|
9
9
|
def initialize(service_name,
|
10
|
-
validator:,
|
10
|
+
validator:,
|
11
|
+
default_properties: {},
|
12
|
+
context_provider: nil,
|
11
13
|
now: -> { Time.now.utc })
|
12
14
|
@service_name = service_name
|
13
15
|
@now = now
|
14
16
|
@default_properties = default_properties
|
17
|
+
@context_provider = context_provider
|
15
18
|
@validator = validator
|
16
19
|
|
17
20
|
super()
|
@@ -40,8 +43,11 @@ module Twiglet
|
|
40
43
|
}
|
41
44
|
}
|
42
45
|
|
46
|
+
context = @context_provider&.call || {}
|
47
|
+
|
43
48
|
base_message
|
44
49
|
.deep_merge(@default_properties.to_nested)
|
50
|
+
.deep_merge(context.to_nested)
|
45
51
|
.deep_merge(message.to_nested)
|
46
52
|
.to_json
|
47
53
|
.concat("\n")
|
data/lib/twiglet/logger.rb
CHANGED
@@ -16,7 +16,6 @@ module Twiglet
|
|
16
16
|
**args
|
17
17
|
)
|
18
18
|
@service_name = service_name
|
19
|
-
default_properties = args.delete(:default_properties) || {}
|
20
19
|
@args = args
|
21
20
|
|
22
21
|
now = args.fetch(:now, -> { Time.now.utc })
|
@@ -31,7 +30,8 @@ module Twiglet
|
|
31
30
|
|
32
31
|
formatter = Twiglet::Formatter.new(
|
33
32
|
service_name,
|
34
|
-
default_properties: default_properties,
|
33
|
+
default_properties: args.fetch(:default_properties, {}),
|
34
|
+
context_provider: args[:context_provider],
|
35
35
|
now: now,
|
36
36
|
validator: @validator
|
37
37
|
)
|
@@ -58,12 +58,19 @@ module Twiglet
|
|
58
58
|
end
|
59
59
|
|
60
60
|
def with(default_properties)
|
61
|
-
|
61
|
+
self.class.new(
|
62
62
|
@service_name,
|
63
63
|
**@args.merge(default_properties: default_properties)
|
64
64
|
)
|
65
65
|
end
|
66
66
|
|
67
|
+
def context_provider(&blk)
|
68
|
+
self.class.new(
|
69
|
+
@service_name,
|
70
|
+
**@args.merge(context_provider: blk)
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
67
74
|
alias_method :warning, :warn
|
68
75
|
alias_method :critical, :fatal
|
69
76
|
|
data/lib/twiglet/version.rb
CHANGED
data/test/formatter_test.rb
CHANGED
@@ -32,4 +32,30 @@ describe Twiglet::Formatter do
|
|
32
32
|
}
|
33
33
|
assert_equal JSON.parse(msg), expected_log
|
34
34
|
end
|
35
|
+
|
36
|
+
it 'merges the outputs of the context provider into messages logs' do
|
37
|
+
provider = -> { { 'request' => { 'id' => '1234567890' } } }
|
38
|
+
formatter = Twiglet::Formatter.new(
|
39
|
+
'petshop', now: @now, validator: Twiglet::Validator.new({}.to_json),
|
40
|
+
context_provider: provider
|
41
|
+
)
|
42
|
+
msg = formatter.call('warn', nil, nil, 'shop is running low on dog food')
|
43
|
+
expected_log = {
|
44
|
+
"ecs" => {
|
45
|
+
"version" => '1.5.0'
|
46
|
+
},
|
47
|
+
"@timestamp" => '2020-05-11T15:01:01.000Z',
|
48
|
+
"service" => {
|
49
|
+
"name" => 'petshop'
|
50
|
+
},
|
51
|
+
"log" => {
|
52
|
+
"level" => 'warn'
|
53
|
+
},
|
54
|
+
"message" => 'shop is running low on dog food',
|
55
|
+
"request" => {
|
56
|
+
'id' => '1234567890'
|
57
|
+
}
|
58
|
+
}
|
59
|
+
assert_equal JSON.parse(msg), expected_log
|
60
|
+
end
|
35
61
|
end
|
data/test/logger_test.rb
CHANGED
@@ -146,6 +146,115 @@ describe Twiglet::Logger do
|
|
146
146
|
assert_equal 'Barker', log[:pet][:name]
|
147
147
|
end
|
148
148
|
|
149
|
+
it "isn't possible to chain .with methods to gradually add messages" do
|
150
|
+
# Let's add some context to this customer journey
|
151
|
+
purchase_logger = @logger.with(
|
152
|
+
{
|
153
|
+
trace: { id: '1c8a5fb2-fecd-44d8-92a4-449eb2ce4dcb' }
|
154
|
+
}
|
155
|
+
).with(
|
156
|
+
{
|
157
|
+
customer: { full_name: 'Freda Bloggs' },
|
158
|
+
event: { action: 'pet purchase' }
|
159
|
+
}
|
160
|
+
)
|
161
|
+
|
162
|
+
# do stuff
|
163
|
+
purchase_logger.info(
|
164
|
+
{
|
165
|
+
message: 'customer bought a dog',
|
166
|
+
pet: { name: 'Barker', species: 'dog', breed: 'Bitsa' }
|
167
|
+
}
|
168
|
+
)
|
169
|
+
|
170
|
+
log = read_json @buffer
|
171
|
+
|
172
|
+
assert_nil log[:trace]
|
173
|
+
assert_equal 'Freda Bloggs', log[:customer][:full_name]
|
174
|
+
assert_equal 'pet purchase', log[:event][:action]
|
175
|
+
assert_equal 'customer bought a dog', log[:message]
|
176
|
+
assert_equal 'Barker', log[:pet][:name]
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should be able to add contextual information to events with the context_provider" do
|
180
|
+
purchase_logger = @logger.context_provider do
|
181
|
+
{ 'context' => { 'id' => 'my-context-id' } }
|
182
|
+
end
|
183
|
+
|
184
|
+
# do stuff
|
185
|
+
purchase_logger.info(
|
186
|
+
{
|
187
|
+
message: 'customer bought a dog',
|
188
|
+
pet: { name: 'Barker', species: 'dog', breed: 'Bitsa' }
|
189
|
+
}
|
190
|
+
)
|
191
|
+
|
192
|
+
log = read_json @buffer
|
193
|
+
|
194
|
+
assert_equal 'customer bought a dog', log[:message]
|
195
|
+
assert_equal 'my-context-id', log[:context][:id]
|
196
|
+
end
|
197
|
+
|
198
|
+
it "chaining .with and .context_provider is possible" do
|
199
|
+
# Let's add some context to this customer journey
|
200
|
+
purchase_logger = @logger.with(
|
201
|
+
{
|
202
|
+
trace: { id: '1c8a5fb2-fecd-44d8-92a4-449eb2ce4dcb' },
|
203
|
+
customer: { full_name: 'Freda Bloggs' },
|
204
|
+
event: { action: 'pet purchase' }
|
205
|
+
}
|
206
|
+
).context_provider do
|
207
|
+
{ 'context' => { 'id' => 'my-context-id' } }
|
208
|
+
end
|
209
|
+
|
210
|
+
# do stuff
|
211
|
+
purchase_logger.info(
|
212
|
+
{
|
213
|
+
message: 'customer bought a dog',
|
214
|
+
pet: { name: 'Barker', species: 'dog', breed: 'Bitsa' }
|
215
|
+
}
|
216
|
+
)
|
217
|
+
|
218
|
+
log = read_json @buffer
|
219
|
+
|
220
|
+
assert_equal '1c8a5fb2-fecd-44d8-92a4-449eb2ce4dcb', log[:trace][:id]
|
221
|
+
assert_equal 'Freda Bloggs', log[:customer][:full_name]
|
222
|
+
assert_equal 'pet purchase', log[:event][:action]
|
223
|
+
assert_equal 'customer bought a dog', log[:message]
|
224
|
+
assert_equal 'Barker', log[:pet][:name]
|
225
|
+
assert_equal 'my-context-id', log[:context][:id]
|
226
|
+
end
|
227
|
+
|
228
|
+
it "chaining .context_provider and .with is possible" do
|
229
|
+
# Let's add some context to this customer journey
|
230
|
+
purchase_logger = @logger
|
231
|
+
.context_provider do
|
232
|
+
{ 'context' => { 'id' => 'my-context-id' } }
|
233
|
+
end.with(
|
234
|
+
{
|
235
|
+
trace: { id: '1c8a5fb2-fecd-44d8-92a4-449eb2ce4dcb' },
|
236
|
+
customer: { full_name: 'Freda Bloggs' },
|
237
|
+
event: { action: 'pet purchase' }
|
238
|
+
}
|
239
|
+
)
|
240
|
+
# do stuff
|
241
|
+
purchase_logger.info(
|
242
|
+
{
|
243
|
+
message: 'customer bought a dog',
|
244
|
+
pet: { name: 'Barker', species: 'dog', breed: 'Bitsa' }
|
245
|
+
}
|
246
|
+
)
|
247
|
+
|
248
|
+
log = read_json @buffer
|
249
|
+
|
250
|
+
assert_equal '1c8a5fb2-fecd-44d8-92a4-449eb2ce4dcb', log[:trace][:id]
|
251
|
+
assert_equal 'Freda Bloggs', log[:customer][:full_name]
|
252
|
+
assert_equal 'pet purchase', log[:event][:action]
|
253
|
+
assert_equal 'customer bought a dog', log[:message]
|
254
|
+
assert_equal 'Barker', log[:pet][:name]
|
255
|
+
assert_equal 'my-context-id', log[:context][:id]
|
256
|
+
end
|
257
|
+
|
149
258
|
it "should log 'message' string property" do
|
150
259
|
message = {}
|
151
260
|
message['message'] = 'Guinea pigs arrived'
|
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.5.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: 2022-
|
11
|
+
date: 2022-05-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json-schema
|
@@ -145,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
145
145
|
- !ruby/object:Gem::Version
|
146
146
|
version: '0'
|
147
147
|
requirements: []
|
148
|
-
rubygems_version: 3.
|
148
|
+
rubygems_version: 3.1.6
|
149
149
|
signing_key:
|
150
150
|
specification_version: 4
|
151
151
|
summary: Twiglet
|