diff --git a/CHANGELOG.md b/CHANGELOG.md index 3221fed..bfab845 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 3.1.2 + - String interpolation is now available for "field" and "target" fields + ## 3.1.1 - Relax constraint on logstash-core-plugin-api to >= 1.60 <= 2.99 diff --git a/lib/logstash/filters/split.rb b/lib/logstash/filters/split.rb index fe4361a..252c088 100644 --- a/lib/logstash/filters/split.rb +++ b/lib/logstash/filters/split.rb @@ -52,10 +52,16 @@ class LogStash::Filters::Split < LogStash::Filters::Base # The field which value is split by the terminator. # Can be a multiline message or the ID of an array. # Nested arrays are referenced like: "[object_id][array_id]" + # String interpolation is also available for this field, + # it means that "field => %{other_field}" will use the + # field value of "other_field". config :field, :validate => :string, :default => "message" # The field within the new event which the value is split into. # If not set, the target field defaults to split field name. + # String interpolation is also available for this field, + # it means that "target => %{other_field}" will use the + # field value of "other_field". config :target, :validate => :string public @@ -66,8 +72,12 @@ def register public def filter(event) + # Convert field to a string based on any format values + field = event.sprintf(@field) + # Same for target + target = event.sprintf(@target) - original_value = event.get(@field) + original_value = event.get(field) if original_value.is_a?(Array) splits = original_value @@ -76,7 +86,7 @@ def filter(event) # splits. splits = original_value.split(@terminator, -1) else - logger.warn("Only String and Array types are splittable. field:#{@field} is of type = #{original_value.class}") + logger.warn("Only String and Array types are splittable. field:#{field} is of type = #{original_value.class}") event.tag(PARSE_FAILURE_TAG) return end @@ -89,11 +99,11 @@ def filter(event) next if value.empty? event_split = event.clone - @logger.debug("Split event", :value => value, :field => @field) + @logger.debug("Split event", :value => value, :field => field) if @target.nil? - event_split.set(@field, value) + event_split.set(field, value) else - event_split.set(@target, value) + event_split.set(target, value) end filter_matched(event_split) diff --git a/logstash-filter-split.gemspec b/logstash-filter-split.gemspec index fe0f017..78a89e2 100644 --- a/logstash-filter-split.gemspec +++ b/logstash-filter-split.gemspec @@ -1,7 +1,7 @@ Gem::Specification.new do |s| s.name = 'logstash-filter-split' - s.version = '3.1.1' + s.version = '3.1.2' s.licenses = ['Apache License (2.0)'] s.summary = "The split filter is for splitting multiline messages into separate events." s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program" diff --git a/spec/filters/split_spec.rb b/spec/filters/split_spec.rb index 7f2c22a..ad83e79 100644 --- a/spec/filters/split_spec.rb +++ b/spec/filters/split_spec.rb @@ -76,14 +76,34 @@ insist { subject[2].get("array") } == "sesame street" end - sample("array" => ["big"], "untouched" => "1\n2\n3") do - insist { subject.is_a?(Logstash::Event) } - insist { subject.get("array") } == "big" + sample("array" => ["single-element"], "untouched" => "1\n2\n3") do + insist { subject.get("array") } == "single-element" + insist { subject.get("untouched") } == "1\n2\n3" end + end - sample("array" => ["single-element"], "untouched" => "1\n2\n3") do - insist { subject["array"] } == "single-element" - insist { subject["untouched"] } == "1\n2\n3" + describe "split array with string interpolation" do + config <<-CONFIG + filter { + split { + field => "%{array_field}" + } + } + CONFIG + + sample("array" => ["big", "bird", "sesame street"], "array_field" => "array", "untouched" => "1\n2\n3") do + insist { subject.length } == 3 + subject.each do |s| + insist { s.get("untouched") } == "1\n2\n3" + end + insist { subject[0].get("array") } == "big" + insist { subject[1].get("array") } == "bird" + insist { subject[2].get("array") } == "sesame street" + end + + sample("array" => ["single-element"], "array_field" => "array", "untouched" => "1\n2\n3") do + insist { subject.get("array") } == "single-element" + insist { subject.get("untouched") } == "1\n2\n3" end end @@ -105,6 +125,25 @@ end end + describe "split array into new field with string interpolation" do + config <<-CONFIG + filter { + split { + field => "array" + target => "%{target_field}" + } + } + CONFIG + + sample("array" => ["big", "bird", "sesame street"], "target_field" => "final") do + insist { subject.length } == 3 + insist { subject[0].get("final") } == "big" + insist { subject[1].get("final") } == "bird" + insist { subject[2].get("final") } == "sesame street" + end + end + + context "when invalid type is passed" do let(:filter) { LogStash::Filters::Split.new({"field" => "field"}) } let(:logger) { filter.logger }