diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b8ed17..b62e4d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 3.5.1 + - feature: Added 'omitempty' feature to remove fields with default or null values + ## 3.4.0 - Added ability to directly convert from integer and float to boolean [#127](https://github.com/logstash-plugins/logstash-filter-mutate/pull/127) diff --git a/CONTRIBUTORS b/CONTRIBUTORS index f99fcce..2d72da2 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -25,6 +25,7 @@ Contributors: * Tal Levy (talevy) * piavlo * Abdul Haseeb Hussain (AbdulHaseebHussain) +* Gregory Ferreux (gferreux) Note: If you've sent us patches, bug reports, or otherwise contributed to Logstash, and you aren't on the list above and want to be, please let us know diff --git a/lib/logstash/filters/mutate.rb b/lib/logstash/filters/mutate.rb index 929add5..5cfbdd3 100644 --- a/lib/logstash/filters/mutate.rb +++ b/lib/logstash/filters/mutate.rb @@ -207,6 +207,17 @@ class LogStash::Filters::Mutate < LogStash::Filters::Base # } config :copy, :validate => :hash + # Omit a variable if it as a default value. + # + # Example: + # [source,ruby] + # filter { + # mutate { + # omitempty => [ "fieldname" ] + # } + # } + config :omitempty, :validate => :array + # Tag to apply if the operation errors config :tag_on_failure, :validate => :string, :default => '_mutate_error' @@ -263,6 +274,7 @@ def filter(event) join(event) if @join merge(event) if @merge copy(event) if @copy + omitempty(event) if @omitempty filter_matched(event) rescue => ex @@ -474,6 +486,26 @@ def capitalize(event) end end + def omitempty(event) + @omitempty.each do |field| + original = event.get(field) + if original.nil? + event.remove(field) + next + end + result = case original + when String, Array, Hash + original.empty? ? nil : original + when Integer + original == 0 ? nil : original + else + @logger.debug? && @logger.debug("Can't omitempty something that isn't a string,array,hash,integer", :field => field, :value => original) + original + end + event.remove(field) if result.nil? + end + end + def split(event) @split.each do |field, separator| value = event.get(field) diff --git a/logstash-filter-mutate.gemspec b/logstash-filter-mutate.gemspec index b459543..e51d05a 100644 --- a/logstash-filter-mutate.gemspec +++ b/logstash-filter-mutate.gemspec @@ -1,7 +1,7 @@ Gem::Specification.new do |s| s.name = 'logstash-filter-mutate' - s.version = '3.5.0' + s.version = '3.5.1' s.licenses = ['Apache License (2.0)'] s.summary = "Performs mutations on fields" 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/mutate_spec.rb b/spec/filters/mutate_spec.rb index 0258680..516909c 100644 --- a/spec/filters/mutate_spec.rb +++ b/spec/filters/mutate_spec.rb @@ -1088,4 +1088,45 @@ def pattern_path(path) end end + describe "omitempty" do + + config <<-CONFIG + filter { + mutate { + omitempty => ["field"] + } + } + CONFIG + + context 'when field is a string' do + sample({'field' => ''}) do + expect(subject).not_to include("field") + end + end + + context 'when field is an integer' do + sample({'field' => 0}) do + expect(subject).not_to include("field") + end + end + + context 'when field is an empty hash' do + sample({'field' => {}}) do + expect(subject).not_to include("field") + end + end + + context 'when field is an empty array' do + sample({'field' => []}) do + expect(subject).not_to include("field") + end + end + + context 'when field is null' do + sample({'field' => nil}) do + expect(subject).not_to include("field") + end + end + end + end