logstash-filter-kv 4.4.1 → 4.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9f997d5d9787b39b3ffbb7f27130fbef6137ebf0f03ec65202795c47be856032
4
- data.tar.gz: 20864a2cb4f477591f010e1e7bdc682db38615dedd76fb8d1e6d961c784dec9a
3
+ metadata.gz: da90e7e03c6cb4960a1c224d216f03ee985b6f1b320832b265b4abd112ac5ade
4
+ data.tar.gz: a4f50d4707f2a3c74cd917e8f86b1acc53e974b56e967953009c6b1f6d241ec3
5
5
  SHA512:
6
- metadata.gz: e866ec418609a22c5365d737f0b3714a650b1d2a8538b9d59b709f4661ccf4af6e6a3a0a58eead83f6fa2dfa1596885c2ee642b6d1ac2a52005512d7a568c197
7
- data.tar.gz: d101397b3fa8a9f488e56c87532ccf71d8c683344a7cf27d5befa7dcfcc5c3ea6299816648ef47c22ee248b9fecc989136c24193e122b577a165cfa0fe3fa662
6
+ metadata.gz: 6b2f78f389c0ae6d43132aff4fce9ff868dd044a220cd9aeaf69c5015d05c0a200be2c6fdc0df9876c4395912e8ff32ee2649e464a2d2d7dc70274243994f08e
7
+ data.tar.gz: 855fb4feebcb15be71505bef3ca4920b60d2e06c1adfd3ae646dc2caf5c95ac69609a6a7cc52ab327bcfce29f92cace5e47612b6a8af542016f468657a007b17
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 4.7.0
2
+ - Allow attaching multiple tags on failure. The `tag_on_failure` option now also supports an array of strings [#92](https://github.com/logstash-plugins/logstash-filter-kv/issues/92)
3
+
4
+ ## 4.6.0
5
+ - Added `allow_empty_values` option [#72](https://github.com/logstash-plugins/logstash-filter-kv/pull/72)
6
+
7
+ ## 4.5.0
8
+ - Feat: check that target is set in ECS mode [#96](https://github.com/logstash-plugins/logstash-filter-kv/pull/96)
9
+
1
10
  ## 4.4.1
2
11
  - Fixed issue where a `field_split_pattern` containing a literal backslash failed to match correctly [#87](https://github.com/logstash-plugins/logstash-filter-kv/issues/87)
3
12
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Logstash Plugin
2
2
 
3
- [![Travis Build Status](https://travis-ci.org/logstash-plugins/logstash-filter-kv.svg)](https://travis-ci.org/logstash-plugins/logstash-filter-kv)
3
+ [![Travis Build Status](https://travis-ci.com/logstash-plugins/logstash-filter-kv.svg)](https://travis-ci.com/logstash-plugins/logstash-filter-kv)
4
4
 
5
5
  This is a plugin for [Logstash](https://github.com/elastic/logstash).
6
6
 
data/docs/index.asciidoc CHANGED
@@ -44,6 +44,13 @@ in case your data is not structured using `=` signs and whitespace.
44
44
  For example, this filter can also be used to parse query parameters like
45
45
  `foo=bar&baz=fizz` by setting the `field_split` parameter to `&`.
46
46
 
47
+ [id="plugins-{type}s-{plugin}-ecs_metadata"]
48
+ ==== Event Metadata and the Elastic Common Schema (ECS)
49
+
50
+ The plugin behaves the same regardless of ECS compatibility, except giving a warning when ECS is enabled and `target` isn't set.
51
+
52
+ TIP: Set the `target` option to avoid potential schema conflicts.
53
+
47
54
  [id="plugins-{type}s-{plugin}-options"]
48
55
  ==== Kv Filter Configuration Options
49
56
 
@@ -53,7 +60,9 @@ This plugin supports the following configuration options plus the <<plugins-{typ
53
60
  |=======================================================================
54
61
  |Setting |Input type|Required
55
62
  | <<plugins-{type}s-{plugin}-allow_duplicate_values>> |<<boolean,boolean>>|No
63
+ | <<plugins-{type}s-{plugin}-allow_empty_values>> |<<boolean,boolean>>|No
56
64
  | <<plugins-{type}s-{plugin}-default_keys>> |<<hash,hash>>|No
65
+ | <<plugins-{type}s-{plugin}-ecs_compatibility>> | <<string,string>>|No
57
66
  | <<plugins-{type}s-{plugin}-exclude_keys>> |<<array,array>>|No
58
67
  | <<plugins-{type}s-{plugin}-field_split>> |<<string,string>>|No
59
68
  | <<plugins-{type}s-{plugin}-field_split_pattern>> |<<string,string>>|No
@@ -65,7 +74,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
65
74
  | <<plugins-{type}s-{plugin}-remove_char_value>> |<<string,string>>|No
66
75
  | <<plugins-{type}s-{plugin}-source>> |<<string,string>>|No
67
76
  | <<plugins-{type}s-{plugin}-target>> |<<string,string>>|No
68
- | <<plugins-{type}s-{plugin}-tag_on_failure>> |<<string,string>>|No
77
+ | <<plugins-{type}s-{plugin}-tag_on_failure>> |<<array,array>>|No
69
78
  | <<plugins-{type}s-{plugin}-tag_on_timeout>> |<<string,string>>|No
70
79
  | <<plugins-{type}s-{plugin}-timeout_millis>> |<<number,number>>|No
71
80
  | <<plugins-{type}s-{plugin}-transform_key>> |<<string,string>>, one of `["lowercase", "uppercase", "capitalize"]`|No
@@ -101,6 +110,17 @@ you could use this configuration:
101
110
  }
102
111
  }
103
112
 
113
+ [id="plugins-{type}s-{plugin}-allow_empty_values"]
114
+ ===== `allow_empty_values`
115
+
116
+ * Value type is <<boolean,boolean>>
117
+ * Default value is `false`
118
+
119
+ A bool option for explicitly including empty values.
120
+ When set to true, empty values will be added to the event.
121
+
122
+ NOTE: Parsing empty values typically requires <<plugins-{type}s-{plugin}-whitespace,`whitespace => strict`>>.
123
+
104
124
  [id="plugins-{type}s-{plugin}-default_keys"]
105
125
  ===== `default_keys`
106
126
 
@@ -117,6 +137,17 @@ in case these keys do not exist in the source field being parsed.
117
137
  }
118
138
  }
119
139
 
140
+ [id="plugins-{type}s-{plugin}-ecs_compatibility"]
141
+ ===== `ecs_compatibility`
142
+
143
+ * Value type is <<string,string>>
144
+ * Supported values are:
145
+ ** `disabled`: does not use ECS-compatible field names
146
+ ** `v1`: Elastic Common Schema compliant behavior (warns when `target` isn't set)
147
+
148
+ Controls this plugin's compatibility with the {ecs-ref}[Elastic Common Schema (ECS)].
149
+ See <<plugins-{type}s-{plugin}-ecs_metadata>> for detailed information.
150
+
120
151
  [id="plugins-{type}s-{plugin}-exclude_keys"]
121
152
  ===== `exclude_keys`
122
153
 
@@ -341,12 +372,12 @@ For example, to place all keys into the event field kv:
341
372
  [id="plugins-{type}s-{plugin}-tag_on_failure"]
342
373
  ===== `tag_on_failure`
343
374
 
344
- * Value type is <<string,string>>
345
- * The default value for this setting is `_kv_filter_error`.
375
+ * Value type is <<array,array>>
376
+ * The default value for this setting is [`_kv_filter_error`].
346
377
 
347
378
  When a kv operation causes a runtime exception to be thrown within the plugin,
348
379
  the operation is safely aborted without crashing the plugin, and the event is
349
- tagged with the provided value.
380
+ tagged with the provided values.
350
381
 
351
382
  [id="plugins-{type}s-{plugin}-tag_on_timeout"]
352
383
  ===== `tag_on_timeout`
@@ -2,6 +2,9 @@
2
2
 
3
3
  require "logstash/filters/base"
4
4
  require "logstash/namespace"
5
+ require 'logstash/plugin_mixins/ecs_compatibility_support'
6
+ require 'logstash/plugin_mixins/ecs_compatibility_support/target_check'
7
+ require 'logstash/plugin_mixins/validator_support/field_reference_validation_adapter'
5
8
  require "timeout"
6
9
 
7
10
  # This filter helps automatically parse messages (or specific event fields)
@@ -30,6 +33,11 @@ require "timeout"
30
33
  class LogStash::Filters::KV < LogStash::Filters::Base
31
34
  config_name "kv"
32
35
 
36
+ include LogStash::PluginMixins::ECSCompatibilitySupport
37
+ include LogStash::PluginMixins::ECSCompatibilitySupport::TargetCheck
38
+
39
+ extend LogStash::PluginMixins::ValidatorSupport::FieldReferenceValidationAdapter
40
+
33
41
  # Constants used for transform check
34
42
  TRANSFORM_LOWERCASE_KEY = "lowercase"
35
43
  TRANSFORM_UPPERCASE_KEY = "uppercase"
@@ -59,7 +67,7 @@ class LogStash::Filters::KV < LogStash::Filters::Base
59
67
  # These characters form a regex character class and thus you must escape special regex
60
68
  # characters like `[` or `]` using `\`.
61
69
  #
62
- # Only leading and trailing characters are trimed from the key.
70
+ # Only leading and trailing characters are trimmed from the key.
63
71
  #
64
72
  # For example, to trim `<` `>` `[` `]` and `,` characters from keys:
65
73
  # [source,ruby]
@@ -201,7 +209,7 @@ class LogStash::Filters::KV < LogStash::Filters::Base
201
209
  # For example, to process the `not_the_message` field:
202
210
  # [source,ruby]
203
211
  # filter { kv { source => "not_the_message" } }
204
- config :source, :validate => :string, :default => "message"
212
+ config :source, :validate => :field_reference, :default => "message"
205
213
 
206
214
  # The name of the container to put all of the key-value pairs into.
207
215
  #
@@ -211,7 +219,7 @@ class LogStash::Filters::KV < LogStash::Filters::Base
211
219
  # For example, to place all keys into the event field kv:
212
220
  # [source,ruby]
213
221
  # filter { kv { target => "kv" } }
214
- config :target, :validate => :string
222
+ config :target, :validate => :field_reference
215
223
 
216
224
  # An array specifying the parsed keys which should be added to the event.
217
225
  # By default all keys will be added.
@@ -264,6 +272,9 @@ class LogStash::Filters::KV < LogStash::Filters::Base
264
272
  # }
265
273
  config :allow_duplicate_values, :validate => :boolean, :default => true
266
274
 
275
+ # A bool option for keeping empty or nil values.
276
+ config :allow_empty_values, :validate => :boolean, :default => false
277
+
267
278
  # A boolean specifying whether to treat square brackets, angle brackets,
268
279
  # and parentheses as value "wrappers" that should be removed from the value.
269
280
  # [source,ruby]
@@ -327,7 +338,10 @@ class LogStash::Filters::KV < LogStash::Filters::Base
327
338
  config :tag_on_timeout, :validate => :string, :default => '_kv_filter_timeout'
328
339
 
329
340
  # Tag to apply if kv errors
330
- config :tag_on_failure, :validate => :string, :default => '_kv_filter_error'
341
+ config :tag_on_failure, :validate => :array, :default => ['_kv_filter_error']
342
+
343
+
344
+ EMPTY_STRING = ''.freeze
331
345
 
332
346
  def register
333
347
  # Too late to set the regexp interruptible flag, at least warn if it is not set.
@@ -411,8 +425,8 @@ class LogStash::Filters::KV < LogStash::Filters::Base
411
425
 
412
426
  @logger.debug? && @logger.debug("KV scan regex", :regex => @scan_re.inspect)
413
427
 
414
- # divide by float to allow fractionnal seconds, the Timeout class timeout value is in seconds but the underlying
415
- # executor resolution is in microseconds so fractionnal second parameter down to microseconds is possible.
428
+ # divide by float to allow fractional seconds, the Timeout class timeout value is in seconds but the underlying
429
+ # executor resolution is in microseconds so fractional second parameter down to microseconds is possible.
416
430
  # see https://github.com/jruby/jruby/blob/9.2.7.0/core/src/main/java/org/jruby/ext/timeout/Timeout.java#L125
417
431
  @timeout_seconds = @timeout_millis / 1000.0
418
432
  end
@@ -429,7 +443,9 @@ class LogStash::Filters::KV < LogStash::Filters::Base
429
443
  return if kv.empty?
430
444
 
431
445
  if @target
432
- @logger.debug? && @logger.debug("Overwriting existing target field", :target => @target)
446
+ if event.include?(@target)
447
+ @logger.debug? && @logger.debug("Overwriting existing target field", field: @target, existing_value: event.get(@target))
448
+ end
433
449
  event.set(@target, kv)
434
450
  else
435
451
  kv.each{|k, v| event.set(k, v)}
@@ -444,7 +460,7 @@ class LogStash::Filters::KV < LogStash::Filters::Base
444
460
  meta = { :exception => ex.message }
445
461
  meta[:backtrace] = ex.backtrace if logger.debug?
446
462
  logger.warn('Exception while parsing KV', meta)
447
- event.tag(@tag_on_failure)
463
+ @tag_on_failure.each { |tag| event.tag(tag) }
448
464
  end
449
465
 
450
466
  def close
@@ -484,9 +500,9 @@ class LogStash::Filters::KV < LogStash::Filters::Base
484
500
 
485
501
  value = value.to_s
486
502
 
487
- value.bytesize < 255 ? "`#{value}`" : "entry too large; first 255 chars are `#{value[0..255].dump}`"
503
+ value.bytesize < 255 ? "`#{value.dump}`" : "(entry too large to show; showing first 255 characters) `#{value[0..255].dump}`[...]"
488
504
  end
489
-
505
+
490
506
  def has_value_splitter?(s)
491
507
  s =~ @value_split_re
492
508
  end
@@ -559,12 +575,12 @@ class LogStash::Filters::KV < LogStash::Filters::Base
559
575
  exclude_keys = @exclude_keys.map{|key| event.sprintf(key)}
560
576
 
561
577
  text.scan(@scan_re) do |key, *value_candidates|
562
- value = value_candidates.compact.first
563
- next if value.nil? || value.empty?
578
+ value = value_candidates.compact.first || EMPTY_STRING
579
+ next if value.empty? && !@allow_empty_values
564
580
 
565
- key = @trim_key ? key.gsub(@trim_key_re, "") : key
566
- key = @remove_char_key ? key.gsub(@remove_char_key_re, "") : key
567
- key = @transform_key ? transform(key, @transform_key) : key
581
+ key = key.gsub(@trim_key_re, EMPTY_STRING) if @trim_key
582
+ key = key.gsub(@remove_char_key_re, EMPTY_STRING) if @remove_char_key
583
+ key = transform(key, @transform_key) if @transform_key
568
584
 
569
585
  # Bail out as per the values of include_keys and exclude_keys
570
586
  next if not include_keys.empty? and not include_keys.include?(key)
@@ -573,9 +589,9 @@ class LogStash::Filters::KV < LogStash::Filters::Base
573
589
 
574
590
  key = event.sprintf(@prefix) + key
575
591
 
576
- value = @trim_value ? value.gsub(@trim_value_re, "") : value
577
- value = @remove_char_value ? value.gsub(@remove_char_value_re, "") : value
578
- value = @transform_value ? transform(value, @transform_value) : value
592
+ value = value.gsub(@trim_value_re, EMPTY_STRING) if @trim_value
593
+ value = value.gsub(@remove_char_value_re, EMPTY_STRING) if @remove_char_value
594
+ value = transform(value, @transform_value) if @transform_value
579
595
 
580
596
  # Bail out if inserting duplicate value in key mapping when unique_values
581
597
  # option is set to true.
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-filter-kv'
4
- s.version = '4.4.1'
4
+ s.version = '4.7.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Parses key-value pairs"
7
7
  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"
@@ -21,6 +21,8 @@ Gem::Specification.new do |s|
21
21
 
22
22
  # Gem dependencies
23
23
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
+ s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~> 1.3'
25
+ s.add_runtime_dependency 'logstash-mixin-validator_support', '~> 1.0'
24
26
 
25
27
  s.add_development_dependency 'logstash-devutils'
26
28
  s.add_development_dependency 'insist'
@@ -460,7 +460,6 @@ describe LogStash::Filters::KV do
460
460
  end
461
461
  end
462
462
 
463
-
464
463
  describe "test data from specific sub source" do
465
464
  config <<-CONFIG
466
465
  filter {
@@ -519,7 +518,6 @@ describe LogStash::Filters::KV do
519
518
  end
520
519
  end
521
520
 
522
-
523
521
  describe "test data from specific sub source and target" do
524
522
  config <<-CONFIG
525
523
  filter {
@@ -721,6 +719,27 @@ describe LogStash::Filters::KV do
721
719
  end
722
720
  end
723
721
 
722
+ describe "Allowing empty values" do
723
+ config <<-CONFIG
724
+ filter {
725
+ kv {
726
+ field_split => " "
727
+ source => "source"
728
+ allow_empty_values => true
729
+ whitespace => strict
730
+ }
731
+ }
732
+ CONFIG
733
+
734
+ sample("source" => "present=one empty= emptyquoted='' present=two emptybracketed=[] endofinput=") do
735
+ insist { subject.get('[present]') } == ['one','two']
736
+ insist { subject.get('[empty]') } == ''
737
+ insist { subject.get('[emptyquoted]') } == ''
738
+ insist { subject.get('[emptybracketed]') } == ''
739
+ insist { subject.get('[endofinput]') } == ''
740
+ end
741
+ end
742
+
724
743
  describe "Allow duplicate key/value pairs by default" do
725
744
  config <<-CONFIG
726
745
  filter {
@@ -1038,7 +1057,6 @@ describe "multi character splitting" do
1038
1057
  it_behaves_like "parsing all fields and values"
1039
1058
  end
1040
1059
 
1041
-
1042
1060
  context "example from @guyboertje in #15" do
1043
1061
  let(:message) { 'key1: val1; key2: val2; key3: https://site/?g={......"...; CLR rv:11.0)"..}; key4: val4;' }
1044
1062
  let(:options) {
@@ -1131,6 +1149,17 @@ context 'runtime errors' do
1131
1149
  plugin.filter(event)
1132
1150
  expect(event.get('tags')).to_not be_nil
1133
1151
  expect(event.get('tags')).to include('KV-ERROR')
1152
+ expect(event.get('tags')).to_not include('_kv_filter_error')
1153
+ end
1154
+ end
1155
+ context 'when multiple custom tags are defined' do
1156
+ let(:options) { super().merge("tag_on_failure" => ["kv_FAIL_one", "_kv_fail_TWO"])}
1157
+ it 'tags the event with the custom tag' do
1158
+ plugin.filter(event)
1159
+ expect(event.get('tags')).to_not be_nil
1160
+ expect(event.get('tags')).to include('kv_FAIL_one')
1161
+ expect(event.get('tags')).to include('_kv_fail_TWO')
1162
+ expect(event.get('tags')).to_not include('_kv_filter_error')
1134
1163
  end
1135
1164
  end
1136
1165
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-kv
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.1
4
+ version: 4.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-03 00:00:00.000000000 Z
11
+ date: 2022-03-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -30,6 +30,34 @@ dependencies:
30
30
  - - "<="
31
31
  - !ruby/object:Gem::Version
32
32
  version: '2.99'
33
+ - !ruby/object:Gem::Dependency
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - "~>"
37
+ - !ruby/object:Gem::Version
38
+ version: '1.3'
39
+ name: logstash-mixin-ecs_compatibility_support
40
+ prerelease: false
41
+ type: :runtime
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '1.3'
47
+ - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: '1.0'
53
+ name: logstash-mixin-validator_support
54
+ prerelease: false
55
+ type: :runtime
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.0'
33
61
  - !ruby/object:Gem::Dependency
34
62
  requirement: !ruby/object:Gem::Requirement
35
63
  requirements:
@@ -97,8 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
125
  - !ruby/object:Gem::Version
98
126
  version: '0'
99
127
  requirements: []
100
- rubyforge_project:
101
- rubygems_version: 2.6.13
128
+ rubygems_version: 3.1.6
102
129
  signing_key:
103
130
  specification_version: 4
104
131
  summary: Parses key-value pairs