logstash-filter-fingerprint 3.2.3 → 3.3.2

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: 5985afeb097946794b24fa48da9e78f4a4146e39b7a39b4be98f11c2b74cd7f8
4
- data.tar.gz: 1e6ba943dbae9448dacf4bcf8f4d268aa48381d816be73630f6594358090c8d4
3
+ metadata.gz: f6c1e99ae34e1681eba14af022fa9fc79909bfaf306542326f0ae88881810370
4
+ data.tar.gz: ffe46fdd11dc94d0fdcdb35d889ec41f3560f205c78e872985ea426fdd776cef
5
5
  SHA512:
6
- metadata.gz: 63d38e83879e80b301af57fd82fbf60630ace866b6f102425e8d3ae97467b5384b17268215e52854c35bf1c24e7dfe8f6bd448fa9821f7289610c794232d7a48
7
- data.tar.gz: 566ef91a8e6d67abf113bdd07621f65d47a290d0b12f7278d881d3eb13cdaf8c6346147eee3d4534a4184ec70544440177b9821b54e61f58ace71a84ae821669
6
+ metadata.gz: c343f48b3f479e5a38c4de0510fc9a51b6785c4437441206baf491c1373df9abae24d30b5efc4f761295857e7d376c7c276e69378ed305e53432fe55e6e5477a
7
+ data.tar.gz: 964ad01b6482e60069421ec1c26c1ad422c44e88372ff63305d752210fd31755752409af9dd2bee96adf8fafa9b9065ca1ce40b53f18da05b5a76b86a54fffb0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 3.3.2
2
+ - [DOC] Clarify behavior when key is set [#65](https://github.com/logstash-plugins/logstash-filter-fingerprint/pull/65).
3
+
4
+ ## 3.3.1
5
+ - Force encoding to UTF-8 when concatenating sources to generate fingerprint [#64](https://github.com/logstash-plugins/logstash-filter-fingerprint/pull/64)
6
+
7
+ ## 3.3.0
8
+ - Add ECS compatibility [#62](https://github.com/logstash-plugins/logstash-filter-fingerprint/pull/62)
9
+
10
+ ## 3.2.4
11
+ - Fixed the error in Murmur3 with Integer [#61](https://github.com/logstash-plugins/logstash-filter-fingerprint/pull/61)
12
+
1
13
  ## 3.2.3
2
14
  - [DOC] Expanded description for concatenate_sources behavior and provided examples [#60](https://github.com/logstash-plugins/logstash-filter-fingerprint/pull/60)
3
15
 
data/docs/index.asciidoc CHANGED
@@ -23,15 +23,30 @@ include::{include_path}/plugin_header.asciidoc[]
23
23
  Create consistent hashes (fingerprints) of one or more fields and store
24
24
  the result in a new field.
25
25
 
26
- You can use this plugin to create consistent document ids when events are
26
+ You can use this plugin to create consistent document ids when events are
27
27
  inserted into Elasticsearch. This approach means that existing documents can be
28
28
  updated instead of creating new documents.
29
29
 
30
- NOTE: When the `target` option is set to `UUID` the result won't be
30
+ NOTE: When the `method` option is set to `UUID` the result won't be
31
31
  a consistent hash but a random
32
32
  https://en.wikipedia.org/wiki/Universally_unique_identifier[UUID].
33
33
  To generate UUIDs, prefer the {logstash-ref}/plugins-filters-uuid.html[uuid filter].
34
34
 
35
+ [id="plugins-{type}s-{plugin}-ecs_metadata"]
36
+ ==== Event Metadata and the Elastic Common Schema (ECS)
37
+ This plugin adds a hash value to event as an identifier. You can configure the `target` option to change the output field.
38
+
39
+ When ECS compatibility is disabled, the hash value is stored in the `fingerprint` field.
40
+ When ECS is enabled, the value is stored in the `[event][hash]` field.
41
+
42
+ Here’s how ECS compatibility mode affects output.
43
+ [cols="<l,<l,e,<e"]
44
+ |=======================================================================
45
+ | ECS disabled | ECS v1 | Availability | Description
46
+
47
+ | fingerprint | [event][hash] | Always | a hash value of event
48
+ |=======================================================================
49
+
35
50
  [id="plugins-{type}s-{plugin}-options"]
36
51
  ==== Fingerprint Filter Configuration Options
37
52
 
@@ -43,6 +58,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
43
58
  | <<plugins-{type}s-{plugin}-base64encode>> |<<boolean,boolean>>|No
44
59
  | <<plugins-{type}s-{plugin}-concatenate_sources>> |<<boolean,boolean>>|No
45
60
  | <<plugins-{type}s-{plugin}-concatenate_all_fields>> |<<boolean,boolean>>|No
61
+ | <<plugins-{type}s-{plugin}-ecs_compatibility>> | <<string,string>>|No
46
62
  | <<plugins-{type}s-{plugin}-key>> |<<string,string>>|No
47
63
  | <<plugins-{type}s-{plugin}-method>> |<<string,string>>, one of `["SHA1", "SHA256", "SHA384", "SHA512", "MD5", "MURMUR3", "IPV4_NETWORK", "UUID", "PUNCTUATION"]`|Yes
48
64
  | <<plugins-{type}s-{plugin}-source>> |<<array,array>>|No
@@ -133,6 +149,18 @@ fingerprint computation. If `false` and at least one source field is
133
149
  given, the target field will be an array with fingerprints of the
134
150
  source fields given.
135
151
 
152
+ [id="plugins-{type}s-{plugin}-ecs_compatibility"]
153
+ ===== `ecs_compatibility`
154
+
155
+ * Value type is <<string,string>>
156
+ * Supported values are:
157
+ ** `disabled`: unstructured data added at root level
158
+ ** `v1`: uses `[event][hash]` fields that are compatible with Elastic Common Schema
159
+
160
+ Controls this plugin's compatibility with the
161
+ {ecs-ref}[Elastic Common Schema (ECS)].
162
+ See <<plugins-{type}s-{plugin}-ecs_metadata>> for detailed information.
163
+
136
164
  [id="plugins-{type}s-{plugin}-key"]
137
165
  ===== `key`
138
166
 
@@ -151,12 +179,11 @@ With other methods, optionally fill in the HMAC key.
151
179
 
152
180
  The fingerprint method to use.
153
181
 
154
- If set to `SHA1`, `SHA256`, `SHA384`, `SHA512`, or `MD5` and a key is set,
155
- the cryptographic hash function with the same name will be used to generate
156
- the fingerprint. When a key set, the keyed-hash (HMAC) digest function will
157
- be used.
182
+ If set to `SHA1`, `SHA256`, `SHA384`, `SHA512`, or `MD5` and a key is set, the
183
+ corresponding cryptographic hash function and the keyed-hash (HMAC) digest function
184
+ are used to generate the fingerprint.
158
185
 
159
- If set to `MURMUR3` the non-cryptographic MurmurHash function will be used.
186
+ If set to `MURMUR3` the non-cryptographic 64 bit MurmurHash function will be used.
160
187
 
161
188
  If set to `IPV4_NETWORK` the input data needs to be a IPv4 address and
162
189
  the hash value will be the masked-out address using the number of bits
@@ -184,7 +211,8 @@ to create the fingerprint. If an array is given, see the
184
211
  ===== `target`
185
212
 
186
213
  * Value type is <<string,string>>
187
- * Default value is `"fingerprint"`
214
+ * Default value is `"fingerprint"` when ECS is disabled
215
+ * Default value is `"[event][hash]"` when ECS is enabled
188
216
 
189
217
  The name of the field where the generated fingerprint will be stored.
190
218
  Any current contents of that field will be overwritten.
@@ -6,6 +6,7 @@ require "openssl"
6
6
  require "ipaddr"
7
7
  require "murmurhash3"
8
8
  require "securerandom"
9
+ require "logstash/plugin_mixins/ecs_compatibility_support"
9
10
 
10
11
  # Create consistent hashes (fingerprints) of one or more fields and store
11
12
  # the result in a new field.
@@ -22,6 +23,8 @@ require "securerandom"
22
23
  # https://en.wikipedia.org/wiki/Universally_unique_identifier[UUID].
23
24
  # To generate UUIDs, prefer the <<plugins-filters-uuid,uuid filter>>.
24
25
  class LogStash::Filters::Fingerprint < LogStash::Filters::Base
26
+ include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled, :v1, :v8 => :v1)
27
+
25
28
  config_name "fingerprint"
26
29
 
27
30
  # The name(s) of the source field(s) whose contents will be used
@@ -31,7 +34,7 @@ class LogStash::Filters::Fingerprint < LogStash::Filters::Base
31
34
 
32
35
  # The name of the field where the generated fingerprint will be stored.
33
36
  # Any current contents of that field will be overwritten.
34
- config :target, :validate => :string, :default => 'fingerprint'
37
+ config :target, :validate => :string
35
38
 
36
39
  # When used with the `IPV4_NETWORK` method fill in the subnet prefix length.
37
40
  # With other methods, optionally fill in the HMAC key.
@@ -76,6 +79,11 @@ class LogStash::Filters::Fingerprint < LogStash::Filters::Base
76
79
  # without having to proide the field names in the `source` attribute
77
80
  config :concatenate_all_fields, :validate => :boolean, :default => false
78
81
 
82
+ def initialize(*params)
83
+ super
84
+ @target ||= ecs_select[disabled: 'fingerprint', v1: '[event][hash]']
85
+ end
86
+
79
87
  def register
80
88
  # convert to symbol for faster comparisons
81
89
  @method = @method.to_sym
@@ -120,11 +128,13 @@ class LogStash::Filters::Fingerprint < LogStash::Filters::Base
120
128
  to_string = ""
121
129
  if @concatenate_all_fields
122
130
  deep_sort_hashes(event.to_hash).each do |k,v|
123
- to_string << "|#{k}|#{v}"
131
+ # Force encoding to UTF-8 to get around https://github.com/jruby/jruby/issues/6748
132
+ to_string << "|#{k}|#{v}".force_encoding("UTF-8")
124
133
  end
125
134
  else
126
135
  @source.sort.each do |k|
127
- to_string << "|#{k}|#{deep_sort_hashes(event.get(k))}"
136
+ # Force encoding to UTF-8 to get around https://github.com/jruby/jruby/issues/6748
137
+ to_string << "|#{k}|#{deep_sort_hashes(event.get(k))}".force_encoding("UTF-8")
128
138
  end
129
139
  end
130
140
  to_string << "|"
@@ -193,8 +203,8 @@ class LogStash::Filters::Fingerprint < LogStash::Filters::Base
193
203
 
194
204
  def fingerprint_murmur3(value)
195
205
  case value
196
- when Fixnum
197
- MurmurHash3::V32.int_hash(value)
206
+ when Integer
207
+ MurmurHash3::V32.int64_hash(value)
198
208
  else
199
209
  MurmurHash3::V32.str_hash(value.to_s)
200
210
  end
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-filter-fingerprint'
4
- s.version = '3.2.3'
4
+ s.version = '3.3.2'
5
5
  s.licenses = ['Apache-2.0']
6
6
  s.summary = "Fingerprints fields by replacing values with a consistent hash"
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"
@@ -23,5 +23,6 @@ Gem::Specification.new do |s|
23
23
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
24
24
  s.add_runtime_dependency "murmurhash3" #(MIT license)
25
25
  s.add_development_dependency 'logstash-devutils'
26
+ s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~>1.2'
26
27
  end
27
28
 
@@ -1,287 +1,319 @@
1
1
  # encoding: utf-8
2
2
  require "logstash/devutils/rspec/spec_helper"
3
3
  require "logstash/filters/fingerprint"
4
+ require 'logstash/plugin_mixins/ecs_compatibility_support/spec_helper'
4
5
 
5
- describe LogStash::Filters::Fingerprint do
6
+ describe LogStash::Filters::Fingerprint, :ecs_compatibility_support, :aggregate_failures do
7
+ ecs_compatibility_matrix(:disabled, :v1, :v8 => :v1) do |ecs_select|
6
8
 
7
- let(:plugin) { described_class.new(config) }
8
- let(:config) { { "method" => fingerprint_method } }
9
- let(:fingerprint_method) { "SHA1" } # default
10
- let(:data) { {} }
11
- let(:event) { LogStash::Event.new(data) }
12
- let(:fingerprint) { event.get("fingerprint") }
9
+ let(:plugin) { described_class.new(config) }
10
+ let(:config) { { "method" => fingerprint_method } }
11
+ let(:fingerprint_method) { "SHA1" } # default
12
+ let(:data) { {} }
13
+ let(:event) { LogStash::Event.new(data) }
14
+ let(:fingerprint) { event.get(ecs_select[disabled: "fingerprint", v1: "[event][hash]"]) }
13
15
 
14
- before(:each) do
15
- plugin.register
16
- plugin.filter(event)
17
- end
16
+ before(:each) do
17
+ allow_any_instance_of(described_class).to receive(:ecs_compatibility).and_return(ecs_compatibility)
18
+ plugin.register
19
+ plugin.filter(event)
20
+ end
18
21
 
19
- context "with a string field" do
20
- let(:data) { {"clientip" => "123.123.123.123" } }
21
- let(:config) { super().merge("source" => ["clientip" ]) }
22
+ context "with a string field" do
23
+ let(:data) { {"clientip" => "123.123.123.123" } }
24
+ let(:config) { super().merge("source" => ["clientip" ]) }
22
25
 
23
- describe "the IPV4_NETWORK method" do
24
- let(:fingerprint_method) { "IPV4_NETWORK" }
25
- let(:config) { super().merge("key" => 24) }
26
+ describe "the IPV4_NETWORK method" do
27
+ let(:fingerprint_method) { "IPV4_NETWORK" }
28
+ let(:config) { super().merge("key" => 24) }
26
29
 
27
- it "fingerprints the ip as the network" do
28
- expect(fingerprint).to eq("123.123.123.0")
30
+ it "fingerprints the ip as the network" do
31
+ expect(fingerprint).to eq("123.123.123.0")
32
+ end
29
33
  end
30
- end
31
34
 
32
- describe "the MURMUR3 method" do
33
- let(:fingerprint_method) { "MURMUR3" }
35
+ describe "the MURMUR3 method" do
36
+ let(:fingerprint_method) { "MURMUR3" }
34
37
 
35
- it "fingerprints the value" do
36
- expect(fingerprint).to eq(4013733395)
37
- end
38
- end
38
+ context "string" do
39
+ it "fingerprints the value" do
40
+ expect(fingerprint).to eq(4013733395)
41
+ end
42
+ end
39
43
 
40
- describe "the SHA1 method" do
41
- let(:fingerprint_method) { "SHA1" }
44
+ context "number" do
45
+ let(:data) { {"clientip" => 123 } }
42
46
 
43
- it "fingerprints the value" do
44
- expect(fingerprint).to eq("3a5076c520b4b463f43806896ea0b3978d09dcae")
47
+ it "fingerprints the value" do
48
+ expect(fingerprint).to eq(823512154)
49
+ end
50
+ end
45
51
  end
46
52
 
47
- context "with HMAC" do
48
- let(:config) { super().merge("key" => "longencryptionkey") }
53
+ describe "the SHA1 method" do
54
+ let(:fingerprint_method) { "SHA1" }
49
55
 
50
56
  it "fingerprints the value" do
51
- expect(fingerprint).to eq("fdc60acc4773dc5ac569ffb78fcb93c9630797f4")
57
+ expect(fingerprint).to eq("3a5076c520b4b463f43806896ea0b3978d09dcae")
52
58
  end
53
- context "with HMAC and base64 encoding" do
54
- let(:config) { super().merge("base64encode" => true) }
59
+
60
+ context "with HMAC" do
61
+ let(:config) { super().merge("key" => "longencryptionkey") }
62
+
55
63
  it "fingerprints the value" do
56
- expect(fingerprint).to eq("/cYKzEdz3FrFaf+3j8uTyWMHl/Q=")
64
+ expect(fingerprint).to eq("fdc60acc4773dc5ac569ffb78fcb93c9630797f4")
65
+ end
66
+ context "with HMAC and base64 encoding" do
67
+ let(:config) { super().merge("base64encode" => true) }
68
+ it "fingerprints the value" do
69
+ expect(fingerprint).to eq("/cYKzEdz3FrFaf+3j8uTyWMHl/Q=")
70
+ end
57
71
  end
58
72
  end
59
- end
60
- context "and base64 encoding" do
61
- let(:config) { super().merge("base64encode" => true) }
62
- it "fingerprints the value" do
63
- expect(fingerprint).to eq("OlB2xSC0tGP0OAaJbqCzl40J3K4=")
73
+ context "and base64 encoding" do
74
+ let(:config) { super().merge("base64encode" => true) }
75
+ it "fingerprints the value" do
76
+ expect(fingerprint).to eq("OlB2xSC0tGP0OAaJbqCzl40J3K4=")
77
+ end
64
78
  end
65
79
  end
66
- end
67
80
 
68
- context "the SHA256 algorithm" do
69
- let(:fingerprint_method) { "SHA256" }
70
- it "fingerprints the value" do
71
- expect(fingerprint).to eq("4dabcab210766e35f03e77120e6986d6e6d4752b2a9ff22980b9253d026080d8")
72
- end
73
- context "with HMAC" do
74
- let(:config) { super().merge("key" => "longencryptionkey") }
81
+ context "the SHA256 algorithm" do
82
+ let(:fingerprint_method) { "SHA256" }
75
83
  it "fingerprints the value" do
76
- expect(fingerprint).to eq("345bec3eff242d53b568916c2610b3e393d885d6b96d643f38494fd74bf4a9ca")
84
+ expect(fingerprint).to eq("4dabcab210766e35f03e77120e6986d6e6d4752b2a9ff22980b9253d026080d8")
77
85
  end
78
- context "and base64 encoding" do
79
- let(:config) { super().merge("base64encode" => true) }
86
+ context "with HMAC" do
87
+ let(:config) { super().merge("key" => "longencryptionkey") }
80
88
  it "fingerprints the value" do
81
- expect(fingerprint).to eq("NFvsPv8kLVO1aJFsJhCz45PYhda5bWQ/OElP10v0qco=")
89
+ expect(fingerprint).to eq("345bec3eff242d53b568916c2610b3e393d885d6b96d643f38494fd74bf4a9ca")
90
+ end
91
+ context "and base64 encoding" do
92
+ let(:config) { super().merge("base64encode" => true) }
93
+ it "fingerprints the value" do
94
+ expect(fingerprint).to eq("NFvsPv8kLVO1aJFsJhCz45PYhda5bWQ/OElP10v0qco=")
95
+ end
82
96
  end
83
97
  end
84
98
  end
85
- end
86
99
 
87
- context "the SHA384 algorithm" do
88
- let(:fingerprint_method) { "SHA384" }
89
- it "fingerprints the value" do
90
- expect(fingerprint).to eq("fd605b0a3af3e04ce0d7a0b0d9c48d67a12dab811f60072e6eae84e35d567793ffb68a1807536f11c90874065c2a4392")
91
- end
92
- context "with HMAC" do
93
- let(:config) { super().merge("key" => "longencryptionkey") }
100
+ context "the SHA384 algorithm" do
101
+ let(:fingerprint_method) { "SHA384" }
94
102
  it "fingerprints the value" do
95
- expect(fingerprint).to eq("22d4c0e8c4fbcdc4887d2038fca7650f0e2e0e2457ff41c06eb2a980dded6749561c814fe182aff93e2538d18593947a")
103
+ expect(fingerprint).to eq("fd605b0a3af3e04ce0d7a0b0d9c48d67a12dab811f60072e6eae84e35d567793ffb68a1807536f11c90874065c2a4392")
96
104
  end
97
- context "and base64 encoding" do
98
- let(:config) { super().merge("base64encode" => true) }
105
+ context "with HMAC" do
106
+ let(:config) { super().merge("key" => "longencryptionkey") }
99
107
  it "fingerprints the value" do
100
- expect(fingerprint).to eq("ItTA6MT7zcSIfSA4/KdlDw4uDiRX/0HAbrKpgN3tZ0lWHIFP4YKv+T4lONGFk5R6")
108
+ expect(fingerprint).to eq("22d4c0e8c4fbcdc4887d2038fca7650f0e2e0e2457ff41c06eb2a980dded6749561c814fe182aff93e2538d18593947a")
109
+ end
110
+ context "and base64 encoding" do
111
+ let(:config) { super().merge("base64encode" => true) }
112
+ it "fingerprints the value" do
113
+ expect(fingerprint).to eq("ItTA6MT7zcSIfSA4/KdlDw4uDiRX/0HAbrKpgN3tZ0lWHIFP4YKv+T4lONGFk5R6")
114
+ end
101
115
  end
102
116
  end
103
117
  end
104
- end
105
- context "the SHA512 algorithm" do
106
- let(:fingerprint_method) { "SHA512" }
107
- it "fingerprints the value" do
108
- expect(fingerprint).to eq("5468e2dc64ea92b617782aae884b35af60041ac9e168a283615b6a462c54c13d42fa9542cce9b7d76a8124ac6616818905e3e5dd35d6e519f77c3b517558639a")
109
- end
110
- context "with HMAC" do
111
- let(:config) { super().merge("key" => "longencryptionkey") }
118
+ context "the SHA512 algorithm" do
119
+ let(:fingerprint_method) { "SHA512" }
112
120
  it "fingerprints the value" do
113
- expect(fingerprint).to eq("11c19b326936c08d6c50a3c847d883e5a1362e6a64dd55201a25f2c1ac1b673f7d8bf15b8f112a4978276d573275e3b14166e17246f670c2a539401c5bfdace8")
121
+ expect(fingerprint).to eq("5468e2dc64ea92b617782aae884b35af60041ac9e168a283615b6a462c54c13d42fa9542cce9b7d76a8124ac6616818905e3e5dd35d6e519f77c3b517558639a")
114
122
  end
115
- context "and base64 encoding" do
116
- let(:config) { super().merge("base64encode" => true) }
123
+ context "with HMAC" do
124
+ let(:config) { super().merge("key" => "longencryptionkey") }
117
125
  it "fingerprints the value" do
118
- expect(fingerprint).to eq("EcGbMmk2wI1sUKPIR9iD5aE2Lmpk3VUgGiXywawbZz99i/FbjxEqSXgnbVcydeOxQWbhckb2cMKlOUAcW/2s6A==")
126
+ expect(fingerprint).to eq("11c19b326936c08d6c50a3c847d883e5a1362e6a64dd55201a25f2c1ac1b673f7d8bf15b8f112a4978276d573275e3b14166e17246f670c2a539401c5bfdace8")
127
+ end
128
+ context "and base64 encoding" do
129
+ let(:config) { super().merge("base64encode" => true) }
130
+ it "fingerprints the value" do
131
+ expect(fingerprint).to eq("EcGbMmk2wI1sUKPIR9iD5aE2Lmpk3VUgGiXywawbZz99i/FbjxEqSXgnbVcydeOxQWbhckb2cMKlOUAcW/2s6A==")
132
+ end
119
133
  end
120
134
  end
121
135
  end
122
- end
123
- context "the MD5 algorithm" do
124
- let(:fingerprint_method) { "MD5" }
125
- it "fingerprints the value" do
126
- expect(fingerprint).to eq("ccdd8d3d940a01b2fb3258c059924c0d")
127
- end
128
- context "with HMAC" do
129
- let(:config) { super().merge("key" => "longencryptionkey") }
136
+ context "the MD5 algorithm" do
137
+ let(:fingerprint_method) { "MD5" }
130
138
  it "fingerprints the value" do
131
- expect(fingerprint).to eq("9336c879e305c9604a3843fc3e75948f")
139
+ expect(fingerprint).to eq("ccdd8d3d940a01b2fb3258c059924c0d")
132
140
  end
133
- context "and base64 encoding" do
134
- let(:config) { super().merge("base64encode" => true) }
141
+ context "with HMAC" do
142
+ let(:config) { super().merge("key" => "longencryptionkey") }
135
143
  it "fingerprints the value" do
136
- expect(fingerprint).to eq("kzbIeeMFyWBKOEP8PnWUjw==")
144
+ expect(fingerprint).to eq("9336c879e305c9604a3843fc3e75948f")
145
+ end
146
+ context "and base64 encoding" do
147
+ let(:config) { super().merge("base64encode" => true) }
148
+ it "fingerprints the value" do
149
+ expect(fingerprint).to eq("kzbIeeMFyWBKOEP8PnWUjw==")
150
+ end
137
151
  end
138
152
  end
139
153
  end
140
154
  end
141
- end
142
155
 
143
- context "multiple values in the source field" do
144
- let(:config) { super().merge("source" => ["clientip" ]) }
145
- let(:data) { { "clientip" => [ "123.123.123.123", "223.223.223.223" ] } }
156
+ context "multiple values in the source field" do
157
+ let(:config) { super().merge("source" => ["clientip" ]) }
158
+ let(:data) { { "clientip" => [ "123.123.123.123", "223.223.223.223" ] } }
146
159
 
147
- it "produces a fingerprint array" do
148
- expect(fingerprint).to eq(["3a5076c520b4b463f43806896ea0b3978d09dcae", "47bbc4e06edebbace047fed35abeceec64968b81"])
160
+ it "produces a fingerprint array" do
161
+ expect(fingerprint).to eq(["3a5076c520b4b463f43806896ea0b3978d09dcae", "47bbc4e06edebbace047fed35abeceec64968b81"])
162
+ end
149
163
  end
150
- end
151
164
 
152
- describe "concatenate_all_fields" do
153
- let(:config) { { "concatenate_all_fields" => true } }
154
- # The @timestamp field is specified in this sample event as we need the event contents to be constant for the tests
155
- let(:data) do
156
- { "@timestamp" => "2017-07-26T14:44:27.064Z", "clientip" => "123.123.123.123", "message" => "This is a test message", "log_level" => "INFO", "offset" => 123456789, "type" => "test" }
157
- end
165
+ describe "concatenate_all_fields" do
166
+ let(:config) { { "concatenate_all_fields" => true } }
167
+ # The @timestamp field is specified in this sample event as we need the event contents to be constant for the tests
168
+ let(:data) do
169
+ { "@timestamp" => "2017-07-26T14:44:27.064Z", "clientip" => "123.123.123.123", "message" => "This is a test message", "log_level" => "INFO", "offset" => 123456789, "type" => "test" }
170
+ end
158
171
 
159
- it "fingerprints the concatenated values" do
160
- expect(fingerprint).to eq("cbf022518e97860403160ed8a41847c0db104e63")
172
+ it "fingerprints the concatenated values" do
173
+ expect(fingerprint).to eq("cbf022518e97860403160ed8a41847c0db104e63")
174
+ end
161
175
  end
162
- end
163
176
 
164
- context "when multiple fields are used" do
165
- let(:config) { super().merge("source" => ['field1', 'field2']) }
166
- let(:data) { { "field1" => "test1", "field2" => "test2" } }
177
+ context "when multiple fields are used" do
178
+ let(:config) { super().merge("source" => ['field1', 'field2']) }
179
+ let(:data) { { "field1" => "test1", "field2" => "test2" } }
167
180
 
168
- it "fingerprints the value of the last value" do
169
- # SHA1 of "test2"
170
- expect(fingerprint).to eq("109f4b3c50d7b0df729d299bc6f8e9ef9066971f")
171
- end
181
+ it "fingerprints the value of the last value" do
182
+ # SHA1 of "test2"
183
+ expect(fingerprint).to eq("109f4b3c50d7b0df729d299bc6f8e9ef9066971f")
184
+ end
172
185
 
173
- describe "with concatenate_sources" do
174
- let(:config) { super().merge("concatenate_sources" => true) }
175
- it "fingerprints the value of concatenated key/pairs" do
176
- # SHA1 of "|field1|test1|field2|test2|"
177
- expect(fingerprint).to eq("e3b6b71eedc656f1d29408264e8a75535db985cb")
186
+ describe "with concatenate_sources" do
187
+ let(:config) { super().merge("concatenate_sources" => true) }
188
+ it "fingerprints the value of concatenated key/pairs" do
189
+ # SHA1 of "|field1|test1|field2|test2|"
190
+ expect(fingerprint).to eq("e3b6b71eedc656f1d29408264e8a75535db985cb")
191
+ end
178
192
  end
179
193
  end
180
- end
181
194
 
182
- describe "PUNCTUATION method" do
183
- let(:fingerprint_method) { 'PUNCTUATION' }
184
- let(:config) { super().merge("source" => 'field1') }
185
- let(:data) { { "field1" => "PHP Warning: json_encode() [<a href='function.json-encode'>function.json-encode</a>]: Invalid UTF-8 sequence in argument in /var/www/htdocs/test.php on line 233" } }
195
+ context "when utf-8 chars used" do
196
+ let(:config) { super().merge("source" => ['field1', 'field2']) }
197
+ let(:data) { {"field1"=>[{"inner_key"=>"🂡"}, {"1"=>"2"}], "field2"=>"🂡"} }
198
+ it "fingerprints the value of the last value" do
199
+ # SHA1 of "|field1|inner_key|🂡|1|2|field2|🂡|"
200
+ expect(fingerprint).to eq("58fa9e0e60c9f0d24b51d84cddb26732a39eeb3d")
201
+ end
186
202
 
187
- it "extracts punctiation as the fingerprint" do
188
- expect(fingerprint).to eq(":_()[<='.-'>.-</>]:-////.")
203
+ describe "with concatenate_sources" do
204
+ let(:config) { super().merge("concatenate_sources" => true) }
205
+ it "fingerprints the value of concatenated key/pairs" do
206
+ # SHA1 of "|field1|inner_key|🂡|1|2|field2|🂡|"
207
+ expect(fingerprint).to eq("d74f41841c7cdc793a97c218d2ff18064a5f1950")
208
+ end
209
+ end
189
210
  end
190
- end
191
211
 
192
- context 'Timestamps' do
193
- epoch_time = Time.at(0).gmtime
194
- let(:config) { super().merge("source" => ['@timestamp']) }
212
+ describe "PUNCTUATION method" do
213
+ let(:fingerprint_method) { 'PUNCTUATION' }
214
+ let(:config) { super().merge("source" => 'field1') }
215
+ let(:data) { { "field1" => "PHP Warning: json_encode() [<a href='function.json-encode'>function.json-encode</a>]: Invalid UTF-8 sequence in argument in /var/www/htdocs/test.php on line 233" } }
195
216
 
196
- describe 'OpenSSL Fingerprinting' do
197
- let(:config) { super().merge("key" => '0123') }
198
- let(:fingerprint_method) { "SHA1" }
199
- let(:data) { { "@timestamp" => epoch_time } }
200
- it "fingerprints the timestamp correctly" do
201
- expect(fingerprint).to eq('1d5379ec92d86a67cfc642d55aa050ca312d3b9a')
217
+ it "extracts punctiation as the fingerprint" do
218
+ expect(fingerprint).to eq(":_()[<='.-'>.-</>]:-////.")
202
219
  end
203
220
  end
204
221
 
205
- describe 'MURMUR3 Fingerprinting' do
206
- let(:fingerprint_method) { "MURMUR3" }
207
- let(:data) { { "@timestamp" => epoch_time } }
208
- it "fingerprints the timestamp correctly" do
209
- expect(fingerprint).to eq(743372282)
222
+ context 'Timestamps' do
223
+ epoch_time = Time.at(0).gmtime
224
+ let(:config) { super().merge("source" => ['@timestamp']) }
225
+
226
+ describe 'OpenSSL Fingerprinting' do
227
+ let(:config) { super().merge("key" => '0123') }
228
+ let(:fingerprint_method) { "SHA1" }
229
+ let(:data) { { "@timestamp" => epoch_time } }
230
+ it "fingerprints the timestamp correctly" do
231
+ expect(fingerprint).to eq('1d5379ec92d86a67cfc642d55aa050ca312d3b9a')
232
+ end
210
233
  end
211
- end
212
- end
213
234
 
214
- describe "post fingerprint execution triggers" do
215
- let(:fingerprint_method) { "PUNCTUATION" }
216
- let(:config) do
217
- {
218
- "source" => 'field1',
219
- "add_field" => { 'myfield' => 'myvalue' },
220
- "add_tag" => ['mytag']
221
- }
235
+ describe 'MURMUR3 Fingerprinting' do
236
+ let(:fingerprint_method) { "MURMUR3" }
237
+ let(:data) { { "@timestamp" => epoch_time } }
238
+ it "fingerprints the timestamp correctly" do
239
+ expect(fingerprint).to eq(743372282)
240
+ end
241
+ end
222
242
  end
223
- let(:data) { { "field1" => "Hello, World!" } }
224
243
 
225
- it "adds the new field" do
226
- expect(event.get("myfield")).to eq("myvalue")
227
- end
228
- it "adds the new tag" do
229
- expect(event.get("tags")).to include("mytag")
244
+ describe "post fingerprint execution triggers" do
245
+ let(:fingerprint_method) { "PUNCTUATION" }
246
+ let(:config) do
247
+ {
248
+ "source" => 'field1',
249
+ "add_field" => { 'myfield' => 'myvalue' },
250
+ "add_tag" => ['mytag']
251
+ }
252
+ end
253
+ let(:data) { { "field1" => "Hello, World!" } }
254
+
255
+ it "adds the new field" do
256
+ expect(event.get("myfield")).to eq("myvalue")
257
+ end
258
+ it "adds the new tag" do
259
+ expect(event.get("tags")).to include("mytag")
260
+ end
230
261
  end
231
- end
232
262
 
233
- describe "tolerance to hash order" do
234
- # insertion order can influence the result of to_hash's keys
235
- let(:data1) { {
263
+ describe "tolerance to hash order" do
264
+ # insertion order can influence the result of to_hash's keys
265
+ let(:data1) { {
236
266
  "a" => {"a0" => 0, "a1" => 1},
237
267
  "b" => {"b0" => 0, "b1" => 1},
238
- } }
239
- let(:event1) { LogStash::Event.new(data1) }
240
- let(:data2) { {
268
+ } }
269
+ let(:event1) { LogStash::Event.new(data1) }
270
+ let(:data2) { {
241
271
  "b" => {"b1" => 1, "b0" => 0},
242
272
  "a" => {"a1" => 1, "a0" => 0},
243
- } }
244
- let(:event2) { LogStash::Event.new(data2) }
245
- let(:config) { { "source" => [ "a" ] } }
273
+ } }
274
+ let(:event2) { LogStash::Event.new(data2) }
275
+ let(:config) { { "source" => [ "a" ] } }
246
276
 
247
- before(:each) do
248
- # for testing purposes we want to ensure the hash order is different.
249
- # since we can't easily control the order on the underlying Map,
250
- # we're mocking the order here:
251
- allow(event1).to receive(:to_hash).and_return(data1)
252
- allow(event2).to receive(:to_hash).and_return(data2)
253
- # by default event.get(key) fetches data from the event.
254
- # mocking the default value has to be done first, and only
255
- # then we can mock the getting "a" and "b"
256
- allow(event1).to receive(:get).and_call_original
257
- allow(event2).to receive(:get).and_call_original
258
- # mock event.get("a") and event.get("b") for both events
259
- # so we can inject an inconsistent order for the tests
260
- allow(event1).to receive(:get).with("a") {|arg| data1["a"] }
261
- allow(event1).to receive(:get).with("b") {|arg| data1["b"] }
262
- allow(event2).to receive(:get).with("a") {|arg| data2["a"] }
263
- allow(event2).to receive(:get).with("b") {|arg| data2["b"] }
264
- plugin.filter(event1)
265
- plugin.filter(event2)
266
- end
267
- it "computes the same hash" do
268
- # confirm the order of the keys in the nested hash is different
269
- # (of course it is, we just mocked the to_hash return)
270
- expect(event1.to_hash["a"].keys).to_not eq(event2.to_hash["a"].keys)
271
- # let's check that the fingerprint doesn't care about the insertion order
272
- expect(event1.get("fingerprint")).to eq(event2.get("fingerprint"))
273
- end
274
- context "concatenate_sources" do
275
- let("config") { { "source" => [ "a", "b"], "concatenate_sources" => true } }
276
- it "computes the same hash" do
277
- expect(event1.get("fingerprint")).to eq(event2.get("fingerprint"))
277
+ before(:each) do
278
+ # for testing purposes we want to ensure the hash order is different.
279
+ # since we can't easily control the order on the underlying Map,
280
+ # we're mocking the order here:
281
+ allow(event1).to receive(:to_hash).and_return(data1)
282
+ allow(event2).to receive(:to_hash).and_return(data2)
283
+ # by default event.get(key) fetches data from the event.
284
+ # mocking the default value has to be done first, and only
285
+ # then we can mock the getting "a" and "b"
286
+ allow(event1).to receive(:get).and_call_original
287
+ allow(event2).to receive(:get).and_call_original
288
+ # mock event.get("a") and event.get("b") for both events
289
+ # so we can inject an inconsistent order for the tests
290
+ allow(event1).to receive(:get).with("a") {|arg| data1["a"] }
291
+ allow(event1).to receive(:get).with("b") {|arg| data1["b"] }
292
+ allow(event2).to receive(:get).with("a") {|arg| data2["a"] }
293
+ allow(event2).to receive(:get).with("b") {|arg| data2["b"] }
294
+ plugin.filter(event1)
295
+ plugin.filter(event2)
278
296
  end
279
- end
280
- context "concatenate_all_fields => true" do
281
- let(:config) { { "concatenate_all_fields" => true } }
282
297
  it "computes the same hash" do
298
+ # confirm the order of the keys in the nested hash is different
299
+ # (of course it is, we just mocked the to_hash return)
300
+ expect(event1.to_hash["a"].keys).to_not eq(event2.to_hash["a"].keys)
301
+ # let's check that the fingerprint doesn't care about the insertion order
283
302
  expect(event1.get("fingerprint")).to eq(event2.get("fingerprint"))
284
303
  end
304
+ context "concatenate_sources" do
305
+ let("config") { { "source" => [ "a", "b"], "concatenate_sources" => true } }
306
+ it "computes the same hash" do
307
+ expect(event1.get("fingerprint")).to eq(event2.get("fingerprint"))
308
+ end
309
+ end
310
+ context "concatenate_all_fields => true" do
311
+ let(:config) { { "concatenate_all_fields" => true } }
312
+ it "computes the same hash" do
313
+ expect(event1.get("fingerprint")).to eq(event2.get("fingerprint"))
314
+ end
315
+ end
285
316
  end
317
+
286
318
  end
287
319
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-fingerprint
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.3
4
+ version: 3.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-11 00:00:00.000000000 Z
11
+ date: 2021-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -58,6 +58,20 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '1.2'
67
+ name: logstash-mixin-ecs_compatibility_support
68
+ prerelease: false
69
+ type: :runtime
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.2'
61
75
  description: This gem is a Logstash plugin required to be installed on top of the
62
76
  Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
63
77
  gem is not a stand-alone program