Add multiple custom_options support
It would be useful to support multiple customizations throughout the app and the gems used. Currently some kind of hack is needed to preserve previous customizations. An example case: https://github.com/elastic/elasticsearch-rails/issues/749
I guess the simplest method would be using an array, like:
require 'active_support/core_ext/module/attribute_accessors'
class Test # :nodoc:
mattr_writer :custom_options do
[]
end
def custom_options(event)
# [...].flatten(1) is basically Active Support's Array.wrap
[@@custom_options].flatten(1).reduce({}) do |options, customizer|
options.merge(customizer.respond_to?(:call) ? customizer.call(event) : customizer)
end
end
end
event = { x: 1, y: 2 }
custom1 = ->(ev) { { from_1: ev[:x] } }
custom2 = ->(ev) { { from_2: ev[:y] } }
custom3 = { from_h: 3 }
Test.custom_options = custom1 # BC
Test.new.custom_options(event)
# => {:from_1=>1}
Test.custom_options = [custom2, custom1]
Test.new.custom_options(event)
# => {:from_2=>2, :from_1=>1}
Test.custom_options = [custom1, custom3, custom2]
Test.new.custom_options(event)
# => {:from_1=>1, :from_h=>3, :from_2=>2}
And in the calling site:
config.lograge.custom_options << lambda do |event|
# ...
end
# Or
config.lograge.custom_options = lambda do |event|
# ...
end
A BC concern: if a calling site saves the previous value of custom_options as a workaround for this issue, like in https://github.com/elastic/elasticsearch-rails/pull/750 (which is for the case above); then it has to consider the fact that it can be an array.
One can imagine overriding the writer (if it's possible at all), but that would duplicate the previous value. I'm not sure how can BC be maintained if one is to cover this.