Skip to content

Commit

Permalink
Merge pull request #118 from flexoid/feature/deep-merge-fields
Browse files Browse the repository at this point in the history
Merge hash fields recursively for additional fields and child logger
  • Loading branch information
tilfin authored Feb 20, 2021
2 parents 7347135 + 58869fe commit cf091f6
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 14 deletions.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,18 @@ logger.info('Hello!', user: { name: 'Jiro' }, version: '2.3')
```

If any field of with_fields is specified in each log, the field is overridden.
But if the field's type is *Array*, both with_field value and logging value are merged with `concat` and `uniq`.
If the field's type is *Array*, both with_field value and logging value are merged with `concat` and `uniq`.

If the field's type is *Hash*, then values are merged recursively.

```ruby
logger.with_fields = { version: '1.1.0', user: { name: 'Taro' } }
logger.debug(user: { age: 19 })
```

```json
{"name":"test","hostname":"mint","pid":30182,"level":20,"time":"2017-07-22T20:52:12.332+09:00","v":0,"version":"1.1.0","msg":"No message","user":{"name":"Taro","age":19}}
```

### Create a child logger

Expand Down Expand Up @@ -242,6 +253,8 @@ child_logger.debug('This is not outputted')

If any field exists in both parent log and child log, the parent value is overridden or merged by child value.

If the field's type is *Hash*, then values are merged recursively.

### Hook before logging

Setting `before_log` of logger or child an *lambda* with `data` field, a process can be run before log each output.
Expand Down
2 changes: 2 additions & 0 deletions lib/ougai/logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ def weak_merge!(base_data, inferior_data)
base_data.merge!(inferior_data) do |_, base_v, inferior_v|
if base_v.is_a?(Array) and inferior_v.is_a?(Array)
(inferior_v + base_v).uniq
elsif base_v.is_a?(Hash) and inferior_v.is_a?(Hash)
weak_merge!(base_v, inferior_v)
else
base_v
end
Expand Down
36 changes: 23 additions & 13 deletions spec/child_logger_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@
parent_logger.with_fields = { foo: 11 }
logger.with_fields = { bar: '11' }
end

it 'outputs with child fields' do
logger.info(log_msg)
parent_logger.info(parent_log_msg)
Expand Down Expand Up @@ -426,7 +426,7 @@
before do
parent_logger.with_fields = { foo: 22 }
end

it 'output with new parent fields' do
logger.info(log_msg)
parent_logger.info(parent_log_msg)
Expand Down Expand Up @@ -462,7 +462,7 @@
before do
logger.with_fields = { bar: '33' }
end

it 'output valid' do
logger.info(log_msg)
parent_logger.info(parent_log_msg)
Expand All @@ -478,35 +478,45 @@

context 'grandchild logger' do
before do
parent_logger.with_fields = { tag: 'parent', tags: ['parent'] }
parent_logger.with_fields = { tag: 'parent', tags: ['parent'], event: { module: 'core' } }
end

let(:logger) { parent_logger.child(tag: 'child', tags: ['child']) }
let(:grand_logger) { logger.child(tag: 'grandchild', tags: ['grandchild']) }
let(:logger) { parent_logger.child(tag: 'child', tags: ['child'], event: { dataset: 'core.child' }) }
let(:grand_logger) { logger.child(tag: 'grandchild', tags: ['grandchild'], event: { action: 'log-action' }) }

it 'outputs with all merged fields' do
grand_logger.info('Hi', foo: 3)
logger.info(log_msg, foo: 2)
parent_logger.info(parent_log_msg, foo: 10)
parent_logger.info('Good evening!', foo: 11)
parent_logger.info(parent_log_msg, foo: 10, event: { module: 'service' })
parent_logger.info('Good evening!', foo: 11, event: { duration: 150 })

expect(items[0]).to be_log_message('Hi', log_level)
expect(items[0]).to include(tag: 'grandchild', tags: ['parent', 'child', 'grandchild'], foo: 3)
expect(items[0]).to include(
tag: 'grandchild',
tags: ['parent', 'child', 'grandchild'],
foo: 3,
event: { module: 'core', dataset: 'core.child', action: 'log-action' }
)

expect(items[1]).to be_log_message(log_msg, log_level)
expect(items[1]).to include(tag: 'child', tags: ['parent', 'child'], foo: 2)
expect(items[1]).to include(
tag: 'child',
tags: ['parent', 'child'],
foo: 2,
event: { module: 'core', dataset: 'core.child' }
)

expect(items[2]).to be_log_message(parent_log_msg, log_level)
expect(items[2]).to include(tag: 'parent', tags: ['parent'], foo: 10)
expect(items[2]).to include(tag: 'parent', tags: ['parent'], foo: 10, event: { module: 'service' })
expect(items[3]).to be_log_message('Good evening!', log_level)
expect(items[3]).to include(tag: 'parent', tags: ['parent'], foo: 11)
expect(items[3]).to include(tag: 'parent', tags: ['parent'], foo: 11, event: { module: 'core', duration: 150 })
end

context 'after updating child logger with_fields' do
before do
logger.with_fields = { bar: '33' }
end

it 'outputs with child fields' do
logger.info(log_msg)
expect(items[0]).to be_log_message(log_msg, log_level)
Expand Down
9 changes: 9 additions & 0 deletions spec/logging_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ def level
expect(result[:bar]).to eq('base')
expect(result[:baz]).to eq(['B', 'A'])
end

it 'merges hashes recursively' do
result = nil
subject.instance_eval do
result = weak_merge!({ foo: { bar: { baz: 15 } } },
{ foo: { bar: { extra: 10 }, nested: 'string' } })
end
expect(result).to eq({ foo: { bar: { baz: 15, extra: 10 }, nested: 'string' } })
end
end

describe '#chain' do
Expand Down

0 comments on commit cf091f6

Please sign in to comment.