From d5102805320629a30e3f4830199542d798a00a5d Mon Sep 17 00:00:00 2001 From: Holger Just Date: Tue, 17 Jul 2018 21:39:37 +0200 Subject: [PATCH] Preserve existing field mappings for encoder fields --- lib/rackstash/encoder/helper/fields_map.rb | 18 +++++++-- .../encoder/helper/fields_map_spec.rb | 38 +++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/lib/rackstash/encoder/helper/fields_map.rb b/lib/rackstash/encoder/helper/fields_map.rb index cd22404..3c10806 100644 --- a/lib/rackstash/encoder/helper/fields_map.rb +++ b/lib/rackstash/encoder/helper/fields_map.rb @@ -18,19 +18,29 @@ module Rackstash private def set_fields_mapping(fields, default = {}) - @fields_map = default.dup - Hash(fields).each_pair do |key, value| - @fields_map[key.to_sym] = utf8_encode(value) + @fields_map ||= {} + default.each do |key, value| + if fields.key?(key) + @fields_map[key] = utf8_encode(fields[key]) + else + # Preserve existing mappings which might have been set by a + # previous call to {#set_fields_mapping} + @fields_map[key] ||= utf8_encode(value) + end end end def extract_field(name, event) - field_name = @fields_map[name] + field_name = field(name) field = event.delete(field_name) if field_name field = yield(field_name) if field.nil? && block_given? field end + + def field(name) + @fields_map[name] + end end end end diff --git a/spec/rackstash/encoder/helper/fields_map_spec.rb b/spec/rackstash/encoder/helper/fields_map_spec.rb index 1d3573b..6b7032c 100644 --- a/spec/rackstash/encoder/helper/fields_map_spec.rb +++ b/spec/rackstash/encoder/helper/fields_map_spec.rb @@ -26,6 +26,44 @@ RSpec.describe Rackstash::Encoder::Helper::FieldsMap do } } + describe '#set_fields_mapping' do + it 'sets a default mapping' do + helper.set_fields_mapping({}, { field: 'default' }) + expect(helper.field(:field)).to eql 'default' + end + + it 'sets default fields as strings' do + helper.set_fields_mapping({}, { number: 123 }) + expect(helper.field(:number)).to eql '123' + end + + it 'sets fields as strings' do + helper.set_fields_mapping({ number: 42 }, { number: 'something' }) + expect(helper.field(:number)).to eql '42' + end + + it 'overwrites fields on subsequent calls' do + helper.set_fields_mapping({ field: 'overwritten' }, { field: 'default' }) + expect(helper.field(:field)).to eql 'overwritten' + + helper.set_fields_mapping({ field: 'again' }, { field: 'other_default' }) + expect(helper.field(:field)).to eql 'again' + end + + it 'keeps existing default fields on subsequent calls' do + helper.set_fields_mapping({}, { field: 'foo' }) + expect(helper.field(:field)).to eql 'foo' + + helper.set_fields_mapping({}, { field: 'bar' }) + expect(helper.field(:field)).to eql 'foo' + end + + it 'ignores fields not defined as a default field' do + helper.set_fields_mapping({invalid: 'invalid' }, { known: 'known' }) + expect(helper.field(:invalid)).to be_nil + end + end + describe '#extract_field' do context 'with defaults' do let(:defaults) { { default: 'foo' } }