logstash-input-beats 6.0.14-java → 6.1.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/VERSION +1 -1
- data/docs/index.asciidoc +36 -0
- data/lib/logstash-input-beats_jars.rb +1 -1
- data/lib/logstash/inputs/beats.rb +13 -0
- data/lib/logstash/inputs/beats/decoded_event_transform.rb +10 -1
- data/lib/logstash/inputs/beats/event_transform_common.rb +2 -2
- data/lib/logstash/inputs/beats/message_listener.rb +30 -5
- data/logstash-input-beats.gemspec +1 -0
- data/spec/inputs/beats/decoded_event_transform_spec.rb +2 -1
- data/spec/inputs/beats/event_transform_common_spec.rb +2 -1
- data/spec/inputs/beats/message_listener_spec.rb +82 -54
- data/spec/inputs/beats/raw_event_transform_spec.rb +2 -1
- data/spec/support/shared_examples.rb +33 -27
- data/vendor/jar-dependencies/org/logstash/beats/logstash-input-beats/{6.0.14/logstash-input-beats-6.0.14.jar → 6.1.0/logstash-input-beats-6.1.0.jar} +0 -0
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5924244575544fab0560730b5e773b170a04e6c25d1a72c683ea27c2cc47a597
|
4
|
+
data.tar.gz: 7e316315f18e4f33f821dc4c5655d78452e66d605b6db7edc1bc23b55ae3e1d4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c17ac9a8663f465fd38282753f4cda55e6bf5d6ac7659ecafc4524193742dfc7f22ab325b6cdff36cb20daaf18448ff0a1f0345471d0467e023c68b924b70dc3
|
7
|
+
data.tar.gz: 422714a92f313e7f2d504c3b4927955759188a4246bb6417bbc4d77f24f1a5b4ce8ad403c7e059bc9c025ba97c9f3175bb5e186ff526dd34c850e7c97eb4befe
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
|
+
## 6.1.0
|
2
|
+
- ECS compatibility enablement, now an `ecs_compatibility` setting is used to declare the level of ECS compatibility
|
3
|
+
(`disabled` or `v1`) at plugin level. `disabled` let the plugin behave like before while `v1` does a rename of
|
4
|
+
`host` and `@metadata.ip_address` event fields. [404](https://github.com/logstash-plugins/logstash-input-beats/pull/404)
|
5
|
+
|
1
6
|
## 6.0.14
|
2
|
-
|
7
|
+
- Feat: log + unwrap generic SSL context exceptions [#405](https://github.com/logstash-plugins/logstash-input-beats/pull/405)
|
3
8
|
|
4
9
|
## 6.0.13
|
5
10
|
- [DOC] Update links to use shared attributes
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
6.0
|
1
|
+
6.1.0
|
data/docs/index.asciidoc
CHANGED
@@ -86,6 +86,14 @@ Logstash `@timestamp` field.
|
|
86
86
|
This configuration results in daily index names like
|
87
87
|
+filebeat-{logstash_version}-{localdate}+.
|
88
88
|
|
89
|
+
|
90
|
+
[id="plugins-{type}s-{plugin}-ecs_metadata"]
|
91
|
+
==== Event Metadata and the Elastic Common Schema (ECS)
|
92
|
+
When decoding `beats` events, this plugin adds two fields related to the event: the deprecated `host`
|
93
|
+
which contains the `hostname` provided by beats and the `ip_address` containing the remote address
|
94
|
+
of the client's connection. When <<plugins-{type}s-{plugin}-ecs_compatibility,ECS compatibility mode>> is
|
95
|
+
enabled these are now moved in ECS compatible namespace.
|
96
|
+
|
89
97
|
[id="plugins-{type}s-{plugin}-options"]
|
90
98
|
==== Beats Input Configuration Options
|
91
99
|
|
@@ -97,6 +105,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
97
105
|
| <<plugins-{type}s-{plugin}-add_hostname>> |<<boolean,boolean>>|No
|
98
106
|
| <<plugins-{type}s-{plugin}-cipher_suites>> |<<array,array>>|No
|
99
107
|
| <<plugins-{type}s-{plugin}-client_inactivity_timeout>> |<<number,number>>|No
|
108
|
+
| <<plugins-{type}s-{plugin}-ecs_compatibility>> | <<string,string>>|No
|
100
109
|
| <<plugins-{type}s-{plugin}-host>> |<<string,string>>|No
|
101
110
|
| <<plugins-{type}s-{plugin}-include_codec_tag>> |<<boolean,boolean>>|No
|
102
111
|
| <<plugins-{type}s-{plugin}-port>> |<<number,number>>|Yes
|
@@ -144,6 +153,33 @@ The list of ciphers suite to use, listed by priorities.
|
|
144
153
|
|
145
154
|
Close Idle clients after X seconds of inactivity.
|
146
155
|
|
156
|
+
[id="plugins-{type}s-{plugin}-ecs_compatibility"]
|
157
|
+
===== `ecs_compatibility`
|
158
|
+
|
159
|
+
* Value type is <<string,string>>
|
160
|
+
* Supported values are:
|
161
|
+
** `disabled`: unstructured connection metadata added at root level
|
162
|
+
** `v1`: structured connection metadata added under ECS compliant namespaces
|
163
|
+
* Default value depends on which version of Logstash is running:
|
164
|
+
** When Logstash provides a `pipeline.ecs_compatibility` setting, its value is used as the default
|
165
|
+
** Otherwise, the default value is `disabled`.
|
166
|
+
|
167
|
+
Controls this plugin's compatibility with the {ecs-ref}[Elastic Common Schema (ECS)].
|
168
|
+
The value of this setting affects the keys for the Beats connection's metadata on the event:
|
169
|
+
|
170
|
+
.Metadata Location by `ecs_compatibility` value
|
171
|
+
[cols="<l,<l,e,<e"]
|
172
|
+
|=======================================================================
|
173
|
+
|`disabled` |`v1` |Availability |Description
|
174
|
+
|
175
|
+
|[host] |[@metadata][input][beats][host][name] |Always |Name or address of the beat host
|
176
|
+
|[@metadata][ip_address] |[@metadata][input][beats][host][ip] |Always |IP address of the Beats client
|
177
|
+
|[@metadata][tls_peer][status] | [@metadata][tls_peer][status] | When SSL related fields are populated | Contains "verified"/"unverified" labels in `disabled`, `true`/`false` in `v1`
|
178
|
+
|[@metadata][tls_peer][protocol] | [@metadata][input][beats][tls][version_protocol] | When SSL status is "verified" | Contains the TLS version used (e.g. `TLSv1.2`)
|
179
|
+
|[@metadata][tls_peer][subject] | [@metadata][input][beats][tls][client][subject] | When SSL status is "verified" | Contains the identity name of the remote end (e.g. `CN=artifacts-no-kpi.elastic.co`)
|
180
|
+
|[@metadata][tls_peer][cipher_suite] | [@metadata][input][beats][tls][cipher] | When SSL status is "verified" | Contains the name of cipher suite used (e.g. `TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`)
|
181
|
+
|=======================================================================
|
182
|
+
|
147
183
|
[id="plugins-{type}s-{plugin}-host"]
|
148
184
|
===== `host`
|
149
185
|
|
@@ -8,4 +8,4 @@ require_jar('com.fasterxml.jackson.core', 'jackson-annotations', '2.9.10')
|
|
8
8
|
require_jar('com.fasterxml.jackson.core', 'jackson-databind', '2.9.10.4')
|
9
9
|
require_jar('com.fasterxml.jackson.module', 'jackson-module-afterburner', '2.9.10')
|
10
10
|
require_jar('org.apache.logging.log4j', 'log4j-api', '2.11.1')
|
11
|
-
require_jar('org.logstash.beats', 'logstash-input-beats', '6.0
|
11
|
+
require_jar('org.logstash.beats', 'logstash-input-beats', '6.1.0')
|
@@ -5,6 +5,7 @@ require "logstash/timestamp"
|
|
5
5
|
require "logstash/codecs/multiline"
|
6
6
|
require "logstash/util"
|
7
7
|
require "logstash-input-beats_jars"
|
8
|
+
require "logstash/plugin_mixins/ecs_compatibility_support"
|
8
9
|
require_relative "beats/patch"
|
9
10
|
|
10
11
|
# This input plugin enables Logstash to receive events from the
|
@@ -49,6 +50,9 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
|
|
49
50
|
require "logstash/inputs/beats/message_listener"
|
50
51
|
require "logstash/inputs/beats/tls"
|
51
52
|
|
53
|
+
# adds ecs_compatibility config which could be :disabled or :v1
|
54
|
+
include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled,:v1)
|
55
|
+
|
52
56
|
config_name "beats"
|
53
57
|
|
54
58
|
default :codec, "plain"
|
@@ -121,6 +125,8 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
|
|
121
125
|
# Beats handler executor thread
|
122
126
|
config :executor_threads, :validate => :number, :default => LogStash::Config::CpuCoreStrategy.maximum
|
123
127
|
|
128
|
+
attr_reader :field_hostname, :field_hostip
|
129
|
+
|
124
130
|
def register
|
125
131
|
# For Logstash 2.4 we need to make sure that the logger is correctly set for the
|
126
132
|
# java classes before actually loading them.
|
@@ -156,6 +162,13 @@ class LogStash::Inputs::Beats < LogStash::Inputs::Base
|
|
156
162
|
configuration_error "Multiline codec with beats input is not supported. Please refer to the beats documentation for how to best manage multiline data. See https://www.elastic.co/guide/en/beats/filebeat/current/multiline-examples.html"
|
157
163
|
end
|
158
164
|
|
165
|
+
# define ecs name mapping
|
166
|
+
@field_hostname = ecs_select[disabled: "host", v1: "[@metadata][input][beats][host][name]"]
|
167
|
+
@field_hostip = ecs_select[disabled: "[@metadata][ip_address]", v1: "[@metadata][input][beats][host][ip]"]
|
168
|
+
@field_tls_protocol_version = ecs_select[disabled: "[@metadata][tls_peer][protocol]", v1: "[@metadata][input][beats][tls][version_protocol]"]
|
169
|
+
@field_tls_peer_subject = ecs_select[disabled: "[@metadata][tls_peer][subject]", v1: "[@metadata][input][beats][tls][client][subject]"]
|
170
|
+
@field_tls_cipher = ecs_select[disabled: "[@metadata][tls_peer][cipher_suite]", v1: "[@metadata][input][beats][tls][cipher]"]
|
171
|
+
|
159
172
|
@logger.info("Starting input listener", :address => "#{@host}:#{@port}")
|
160
173
|
|
161
174
|
@server = create_server
|
@@ -9,7 +9,16 @@ module LogStash module Inputs class Beats
|
|
9
9
|
ts = coerce_ts(hash.delete("@timestamp"))
|
10
10
|
|
11
11
|
event.set("@timestamp", ts) unless ts.nil?
|
12
|
-
hash.each
|
12
|
+
hash.each do |k, v|
|
13
|
+
#could be a nested map, so we need to merge and not overwrite
|
14
|
+
existing_value = event.get(k)
|
15
|
+
if existing_value.is_a?(Hash)
|
16
|
+
existing_value = existing_value.merge(v)
|
17
|
+
else
|
18
|
+
existing_value = v
|
19
|
+
end
|
20
|
+
event.set(k, existing_value)
|
21
|
+
end
|
13
22
|
super(event)
|
14
23
|
event.tag("beats_input_codec_#{codec_name}_applied") if include_codec_tag?
|
15
24
|
event
|
@@ -15,8 +15,8 @@ module LogStash module Inputs class Beats
|
|
15
15
|
return unless @input.add_hostname
|
16
16
|
host = event.get("[beat][hostname]")
|
17
17
|
|
18
|
-
if host && event.get(
|
19
|
-
event.set(
|
18
|
+
if host && event.get(@input.field_hostname).nil?
|
19
|
+
event.set(@input.field_hostname, host)
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
@@ -31,7 +31,9 @@ module LogStash module Inputs class Beats
|
|
31
31
|
hash = message.getData
|
32
32
|
ip_address = ip_address(ctx)
|
33
33
|
|
34
|
-
|
34
|
+
unless ip_address.nil? || hash['@metadata'].nil?
|
35
|
+
set_nested(hash, @input.field_hostip, ip_address)
|
36
|
+
end
|
35
37
|
target_field = extract_target_field(hash)
|
36
38
|
|
37
39
|
extract_tls_peer(hash, ctx)
|
@@ -140,11 +142,12 @@ module LogStash module Inputs class Beats
|
|
140
142
|
end
|
141
143
|
|
142
144
|
if tls_verified
|
145
|
+
set_nested(hash, @field_tls_protocol_version, tls_session.getProtocol())
|
146
|
+
set_nested(hash, @field_tls_peer_subject, tls_session.getPeerPrincipal().getName())
|
147
|
+
set_nested(hash, @field_tls_cipher, tls_session.getCipherSuite())
|
148
|
+
|
143
149
|
hash['@metadata']['tls_peer'] = {
|
144
|
-
:status => "verified"
|
145
|
-
:protocol => tls_session.getProtocol(),
|
146
|
-
:subject => tls_session.getPeerPrincipal().getName(),
|
147
|
-
:cipher_suite => tls_session.getCipherSuite()
|
150
|
+
:status => "verified"
|
148
151
|
}
|
149
152
|
else
|
150
153
|
hash['@metadata']['tls_peer'] = {
|
@@ -154,6 +157,28 @@ module LogStash module Inputs class Beats
|
|
154
157
|
end
|
155
158
|
end
|
156
159
|
|
160
|
+
# set the value for field_name into the hash, nesting into sub-hashes and creating hashes where necessary
|
161
|
+
public #only to make it testable
|
162
|
+
def set_nested(hash, field_name, value)
|
163
|
+
field_ref = Java::OrgLogstash::FieldReference.from(field_name)
|
164
|
+
# create @metadata sub-hash if needed
|
165
|
+
if field_ref.type == Java::OrgLogstash::FieldReference::META_CHILD
|
166
|
+
unless hash.key?("@metadata")
|
167
|
+
hash["@metadata"] = {}
|
168
|
+
end
|
169
|
+
nesting_hash = hash["@metadata"]
|
170
|
+
else
|
171
|
+
nesting_hash = hash
|
172
|
+
end
|
173
|
+
|
174
|
+
field_ref.path.each do |token|
|
175
|
+
nesting_hash[token] = {} unless nesting_hash.key?(token)
|
176
|
+
nesting_hash = nesting_hash[token]
|
177
|
+
end
|
178
|
+
nesting_hash[field_ref.key] = value
|
179
|
+
end
|
180
|
+
|
181
|
+
private
|
157
182
|
def extract_target_field(hash)
|
158
183
|
if from_filebeat?(hash)
|
159
184
|
hash.delete(FILEBEAT_LOG_LINE_FIELD).to_s
|
@@ -27,6 +27,7 @@ Gem::Specification.new do |s|
|
|
27
27
|
s.add_runtime_dependency "thread_safe", "~> 0.3.5"
|
28
28
|
s.add_runtime_dependency "logstash-codec-multiline", ">= 2.0.5"
|
29
29
|
s.add_runtime_dependency 'jar-dependencies', '~> 0.3', '>= 0.3.4'
|
30
|
+
s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~>1.1'
|
30
31
|
|
31
32
|
s.add_development_dependency "flores", "~>0.0.6"
|
32
33
|
s.add_development_dependency "rspec"
|
@@ -29,7 +29,8 @@ describe LogStash::Inputs::Beats::DecodedEventTransform do
|
|
29
29
|
|
30
30
|
subject { described_class.new(input).transform(event, map) }
|
31
31
|
|
32
|
-
include_examples "Common Event Transformation"
|
32
|
+
include_examples "Common Event Transformation", :disabled, "host"
|
33
|
+
include_examples "Common Event Transformation", :v1, "[@metadata][input][beats][host][name]"
|
33
34
|
|
34
35
|
it "tags the event" do
|
35
36
|
expect(subject.get("tags")).to include("beats_input_codec_plain_applied")
|
@@ -7,5 +7,6 @@ require "spec_helper"
|
|
7
7
|
describe LogStash::Inputs::Beats::EventTransformCommon do
|
8
8
|
subject { described_class.new(input).transform(event) }
|
9
9
|
|
10
|
-
include_examples "Common Event Transformation"
|
10
|
+
include_examples "Common Event Transformation", :disabled, "host"
|
11
|
+
include_examples "Common Event Transformation", :v1, "[@metadata][input][beats][host][name]"
|
11
12
|
end
|
@@ -52,10 +52,73 @@ class DummyCodec < LogStash::Codecs::Base
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
shared_examples "when the message is from any libbeat" do |ecs_compatibility, host_field_name|
|
56
|
+
let(:input) do
|
57
|
+
input = LogStash::Inputs::Beats.new({ "port" => 5555, "codec" => codec, "ecs_compatibility" => "#{ecs_compatibility}" })
|
58
|
+
input.register
|
59
|
+
input
|
60
|
+
end
|
61
|
+
|
62
|
+
#Requires data modeled as Java, not Ruby since the actual code pulls from Java backed (Netty) object
|
63
|
+
let(:data) do
|
64
|
+
d = HashMap.new
|
65
|
+
d.put('@metadata', HashMap.new)
|
66
|
+
d.put('metric', 1)
|
67
|
+
d.put('name', "super-stats")
|
68
|
+
d
|
69
|
+
end
|
70
|
+
|
71
|
+
let(:message) { MockMessage.new("abc", data)}
|
72
|
+
|
73
|
+
it "extract the event" do
|
74
|
+
subject.onNewMessage(ctx, message)
|
75
|
+
event = queue.pop
|
76
|
+
expect(event.get("message")).to be_nil
|
77
|
+
expect(event.get("metric")).to eq(1)
|
78
|
+
expect(event.get("name")).to eq("super-stats")
|
79
|
+
expect(event.get(host_field_name)).to eq(ip_address)
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when the remote address is nil' do
|
83
|
+
let(:ctx) { OngoingMethodMock.new("remoteAddress", nil)}
|
84
|
+
|
85
|
+
it 'extracts the event' do
|
86
|
+
subject.onNewMessage(ctx, message)
|
87
|
+
event = queue.pop
|
88
|
+
expect(event.get("message")).to be_nil
|
89
|
+
expect(event.get("metric")).to eq(1)
|
90
|
+
expect(event.get("name")).to eq("super-stats")
|
91
|
+
expect(event.get(host_field_name)).to eq(nil)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
context 'when getting the remote address raises' do
|
96
|
+
let(:raising_ctx) { double("context")}
|
97
|
+
|
98
|
+
before do
|
99
|
+
allow(raising_ctx).to receive(:channel).and_raise("nope")
|
100
|
+
subject.onNewConnection(raising_ctx)
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'extracts the event' do
|
104
|
+
subject.onNewMessage(raising_ctx, message)
|
105
|
+
event = queue.pop
|
106
|
+
expect(event.get("message")).to be_nil
|
107
|
+
expect(event.get("metric")).to eq(1)
|
108
|
+
expect(event.get("name")).to eq("super-stats")
|
109
|
+
expect(event.get(host_field_name)).to eq(nil)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
55
114
|
describe LogStash::Inputs::Beats::MessageListener do
|
56
115
|
let(:queue) { Queue.new }
|
57
116
|
let(:codec) { DummyCodec.new }
|
58
|
-
let(:input)
|
117
|
+
let(:input) do
|
118
|
+
input = LogStash::Inputs::Beats.new({ "port" => 5555, "codec" => codec })
|
119
|
+
input.register
|
120
|
+
input
|
121
|
+
end
|
59
122
|
|
60
123
|
let(:ip_address) { "10.0.0.1" }
|
61
124
|
let(:remote_address) { OngoingMethodMock.new("getHostAddress", ip_address) }
|
@@ -146,59 +209,8 @@ describe LogStash::Inputs::Beats::MessageListener do
|
|
146
209
|
end
|
147
210
|
end
|
148
211
|
|
149
|
-
|
150
|
-
|
151
|
-
let(:data) do
|
152
|
-
d = HashMap.new
|
153
|
-
d.put('@metadata', HashMap.new)
|
154
|
-
d.put('metric', 1)
|
155
|
-
d.put('name', "super-stats")
|
156
|
-
d
|
157
|
-
end
|
158
|
-
|
159
|
-
let(:message) { MockMessage.new("abc", data)}
|
160
|
-
|
161
|
-
it "extract the event" do
|
162
|
-
subject.onNewMessage(ctx, message)
|
163
|
-
event = queue.pop
|
164
|
-
expect(event.get("message")).to be_nil
|
165
|
-
expect(event.get("metric")).to eq(1)
|
166
|
-
expect(event.get("name")).to eq("super-stats")
|
167
|
-
expect(event.get("[@metadata][ip_address]")).to eq(ip_address)
|
168
|
-
end
|
169
|
-
|
170
|
-
context 'when the remote address is nil' do
|
171
|
-
let(:ctx) { OngoingMethodMock.new("remoteAddress", nil)}
|
172
|
-
|
173
|
-
it 'extracts the event' do
|
174
|
-
subject.onNewMessage(ctx, message)
|
175
|
-
event = queue.pop
|
176
|
-
expect(event.get("message")).to be_nil
|
177
|
-
expect(event.get("metric")).to eq(1)
|
178
|
-
expect(event.get("name")).to eq("super-stats")
|
179
|
-
expect(event.get("[@metadata][ip_address]")).to eq(nil)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
context 'when getting the remote address raises' do
|
184
|
-
let(:raising_ctx) { double("context")}
|
185
|
-
|
186
|
-
before do
|
187
|
-
allow(raising_ctx).to receive(:channel).and_raise("nope")
|
188
|
-
subject.onNewConnection(raising_ctx)
|
189
|
-
end
|
190
|
-
|
191
|
-
it 'extracts the event' do
|
192
|
-
subject.onNewMessage(raising_ctx, message)
|
193
|
-
event = queue.pop
|
194
|
-
expect(event.get("message")).to be_nil
|
195
|
-
expect(event.get("metric")).to eq(1)
|
196
|
-
expect(event.get("name")).to eq("super-stats")
|
197
|
-
expect(event.get("[@metadata][ip_address]")).to eq(nil)
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
end
|
212
|
+
it_behaves_like "when the message is from any libbeat", :disabled, "[@metadata][ip_address]"
|
213
|
+
it_behaves_like "when the message is from any libbeat", :v1, "[@metadata][input][beats][host][ip]"
|
202
214
|
end
|
203
215
|
|
204
216
|
context "onException" do
|
@@ -222,4 +234,20 @@ describe LogStash::Inputs::Beats::MessageListener do
|
|
222
234
|
expect(queue).not_to be_empty
|
223
235
|
end
|
224
236
|
end
|
237
|
+
|
238
|
+
context "set_nested" do
|
239
|
+
let(:hash) {{}}
|
240
|
+
|
241
|
+
it "creates correctly the nested maps" do
|
242
|
+
subject.set_nested(hash, "[root][inner][leaf]", 5)
|
243
|
+
expect(hash["root"]["inner"]["leaf"]).to eq(5)
|
244
|
+
end
|
245
|
+
|
246
|
+
it "doesn't overwrite existing the nested maps" do
|
247
|
+
hash = {"root" => {"foo" => {"bar" => "Hello"}}}
|
248
|
+
subject.set_nested(hash, "[root][inner][leaf]", 5)
|
249
|
+
expect(hash["root"]["inner"]["leaf"]).to eq(5)
|
250
|
+
expect(hash["root"]["foo"]["bar"]).to eq("Hello")
|
251
|
+
end
|
252
|
+
end
|
225
253
|
end
|
@@ -18,7 +18,8 @@ describe LogStash::Inputs::Beats::RawEventTransform do
|
|
18
18
|
|
19
19
|
subject { described_class.new(input).transform(event) }
|
20
20
|
|
21
|
-
include_examples "Common Event Transformation"
|
21
|
+
include_examples "Common Event Transformation", :disabled, "host"
|
22
|
+
include_examples "Common Event Transformation", :v1, "[@metadata][input][beats][host][name]"
|
22
23
|
|
23
24
|
it "tags the event" do
|
24
25
|
expect(subject.get("tags")).to include("beats_input_raw_event")
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
shared_examples "Common Event Transformation" do
|
2
|
+
shared_examples "Common Event Transformation" do |ecs_compatibility, host_field_name|
|
3
3
|
let(:tag) { "140-rpm-beats" }
|
4
4
|
let(:config) do
|
5
5
|
{
|
@@ -21,12 +21,18 @@ shared_examples "Common Event Transformation" do
|
|
21
21
|
}
|
22
22
|
end
|
23
23
|
|
24
|
+
def key_as_nested_maps(key, value)
|
25
|
+
evt = LogStash::Event.new
|
26
|
+
evt.set(key, value)
|
27
|
+
evt.to_hash_with_metadata
|
28
|
+
end
|
29
|
+
|
24
30
|
it "adds configured tags to the event" do
|
25
31
|
expect(subject.get("tags")).to include(tag)
|
26
32
|
end
|
27
33
|
|
28
34
|
context 'when add_hostname is true' do
|
29
|
-
let(:config) { super.merge({'add_hostname' => true})}
|
35
|
+
let(:config) { super.merge({'add_hostname' => true, 'ecs_compatibility' => ecs_compatibility})}
|
30
36
|
|
31
37
|
context 'when a host is provided in beat.host.name' do
|
32
38
|
let(:already_exist) { "already_exist" }
|
@@ -53,35 +59,35 @@ shared_examples "Common Event Transformation" do
|
|
53
59
|
let(:producer_host) { "newhost01" }
|
54
60
|
let(:event_map) { super.merge({ "beat" => { "hostname" => producer_host }}) }
|
55
61
|
|
56
|
-
context "when no `
|
57
|
-
it "copies the value in `beat.hostname` to `
|
58
|
-
expect(subject.get(
|
62
|
+
context "when no `#{host_field_name}` key already exists on the event" do
|
63
|
+
it "copies the value in `beat.hostname` to `#{host_field_name}`" do
|
64
|
+
expect(subject.get(host_field_name)).to eq(producer_host)
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
62
|
-
context "when `
|
68
|
+
context "when `#{host_field_name}` key exists on the event" do
|
63
69
|
let(:already_exist) { "already_exist" }
|
64
|
-
let(:event_map) { super.merge(
|
70
|
+
let(:event_map) { super.merge(key_as_nested_maps(host_field_name, already_exist)) }
|
65
71
|
|
66
72
|
it "doesn't override it" do
|
67
|
-
expect(subject.get(
|
73
|
+
expect(subject.get(host_field_name)).to eq(already_exist)
|
68
74
|
end
|
69
75
|
end
|
70
76
|
end
|
71
77
|
|
72
78
|
context "when no host is provided in beat" do
|
73
|
-
context "when no `
|
79
|
+
context "when no `#{host_field_name}` key already exists on the event" do
|
74
80
|
it "does not set the host" do
|
75
|
-
expect(subject.get(
|
81
|
+
expect(subject.get(host_field_name)).to be_nil
|
76
82
|
end
|
77
83
|
end
|
78
84
|
|
79
|
-
context "when `
|
85
|
+
context "when `#{host_field_name}` key already exists on the event" do
|
80
86
|
let(:already_exist) { "already_exist" }
|
81
|
-
let(:event_map) { super.merge(
|
87
|
+
let(:event_map) { super.merge(key_as_nested_maps(host_field_name, already_exist)) }
|
82
88
|
|
83
89
|
it "doesn't override it" do
|
84
|
-
expect(subject.get(
|
90
|
+
expect(subject.get(host_field_name)).to eq(already_exist)
|
85
91
|
end
|
86
92
|
end
|
87
93
|
end
|
@@ -95,18 +101,18 @@ shared_examples "Common Event Transformation" do
|
|
95
101
|
let(:producer_host) { "newhost01" }
|
96
102
|
let(:event_map) { super.merge({ "beat" => { "host" => {"name" => producer_host }}}) }
|
97
103
|
|
98
|
-
context "when no `
|
104
|
+
context "when no `#{host_field_name}` key already exists on the event" do
|
99
105
|
it "does not set the host" do
|
100
|
-
expect(subject.get(
|
106
|
+
expect(subject.get(host_field_name)).to be_nil
|
101
107
|
end
|
102
108
|
end
|
103
109
|
|
104
|
-
context "when `
|
110
|
+
context "when `#{host_field_name}` key already exists on the event" do
|
105
111
|
let(:already_exist) { "already_exist" }
|
106
|
-
let(:event_map) { super.merge(
|
112
|
+
let(:event_map) { super.merge(key_as_nested_maps(host_field_name, already_exist)) }
|
107
113
|
|
108
114
|
it "doesn't override it" do
|
109
|
-
expect(subject.get(
|
115
|
+
expect(subject.get(host_field_name)).to eq(already_exist)
|
110
116
|
end
|
111
117
|
end
|
112
118
|
end
|
@@ -115,35 +121,35 @@ shared_examples "Common Event Transformation" do
|
|
115
121
|
let(:producer_host) { "newhost01" }
|
116
122
|
let(:event_map) { super.merge({ "beat" => { "hostname" => producer_host }}) }
|
117
123
|
|
118
|
-
context "when no `
|
124
|
+
context "when no `#{host_field_name}` key already exists on the event" do
|
119
125
|
it "does not set the host" do
|
120
|
-
expect(subject.get(
|
126
|
+
expect(subject.get(host_field_name)).to be_nil
|
121
127
|
end
|
122
128
|
end
|
123
129
|
|
124
130
|
context "when `host` key already exists on the event" do
|
125
131
|
let(:already_exist) { "already_exist" }
|
126
|
-
let(:event_map) { super.merge(
|
132
|
+
let(:event_map) { super.merge(key_as_nested_maps(host_field_name, already_exist)) }
|
127
133
|
|
128
134
|
it "doesn't override it" do
|
129
|
-
expect(subject.get(
|
135
|
+
expect(subject.get(host_field_name)).to eq(already_exist)
|
130
136
|
end
|
131
137
|
end
|
132
138
|
end
|
133
139
|
|
134
140
|
context "when no host is provided in beat" do
|
135
|
-
context "when no `
|
141
|
+
context "when no `#{host_field_name}` key already exists on the event" do
|
136
142
|
it "does not set the host" do
|
137
|
-
expect(subject.get(
|
143
|
+
expect(subject.get(host_field_name)).to be_nil
|
138
144
|
end
|
139
145
|
end
|
140
146
|
|
141
|
-
context "when `
|
147
|
+
context "when `#{host_field_name}` key already exists on the event" do
|
142
148
|
let(:already_exist) { "already_exist" }
|
143
|
-
let(:event_map) { super.merge(
|
149
|
+
let(:event_map) { super.merge(key_as_nested_maps(host_field_name, already_exist)) }
|
144
150
|
|
145
151
|
it "doesn't override it" do
|
146
|
-
expect(subject.get(
|
152
|
+
expect(subject.get(host_field_name)).to eq(already_exist)
|
147
153
|
end
|
148
154
|
end
|
149
155
|
end
|
Binary file
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-beats
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0
|
4
|
+
version: 6.1.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-02-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -106,6 +106,20 @@ dependencies:
|
|
106
106
|
- - ">="
|
107
107
|
- !ruby/object:Gem::Version
|
108
108
|
version: 0.3.4
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
requirement: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - "~>"
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '1.1'
|
115
|
+
name: logstash-mixin-ecs_compatibility_support
|
116
|
+
prerelease: false
|
117
|
+
type: :runtime
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - "~>"
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '1.1'
|
109
123
|
- !ruby/object:Gem::Dependency
|
110
124
|
requirement: !ruby/object:Gem::Requirement
|
111
125
|
requirements:
|
@@ -271,7 +285,7 @@ files:
|
|
271
285
|
- vendor/jar-dependencies/io/netty/netty-all/4.1.49.Final/netty-all-4.1.49.Final.jar
|
272
286
|
- vendor/jar-dependencies/org/apache/logging/log4j/log4j-api/2.11.1/log4j-api-2.11.1.jar
|
273
287
|
- vendor/jar-dependencies/org/javassist/javassist/3.24.0-GA/javassist-3.24.0-GA.jar
|
274
|
-
- vendor/jar-dependencies/org/logstash/beats/logstash-input-beats/6.0
|
288
|
+
- vendor/jar-dependencies/org/logstash/beats/logstash-input-beats/6.1.0/logstash-input-beats-6.1.0.jar
|
275
289
|
homepage: http://www.elastic.co/guide/en/logstash/current/index.html
|
276
290
|
licenses:
|
277
291
|
- Apache License (2.0)
|