logstash-input-elasticsearch 4.7.0 → 4.9.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/CONTRIBUTORS +1 -0
- data/README.md +1 -1
- data/docs/index.asciidoc +78 -12
- data/lib/logstash/inputs/elasticsearch.rb +63 -16
- data/lib/logstash/inputs/patch.rb +48 -0
- data/logstash-input-elasticsearch.gemspec +2 -1
- data/spec/inputs/elasticsearch_spec.rb +124 -42
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70ea634a4cac65bd247f61462fc51679e7f331191879200061538f5996f3f832
|
4
|
+
data.tar.gz: c813467a5737330193d68c248e35cdc74fa1ba5150823e59530623ace7b62ed4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acd8b8807b116d1b926a5d286edce78b4aee0c3d37c86df18933f973c8684b870a63b70626bcc21bcc29f5cb0ec8420b3b1e64715df24eccd9d091f6b7669334
|
7
|
+
data.tar.gz: 6b2c2b47af0b30881120a36118c9dac6b77ff6d01a2f0db396cc218977ad361fd8b9a56966ba623135709d74ad1fc2c6640dddb80148ecb44f5d5f24aef06b83
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
## 4.9.1
|
2
|
+
- [DOC] Replaced hard-coded links with shared attributes [#143](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/143)
|
3
|
+
- [DOC] Added missing quote to docinfo_fields example [#145](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/145)
|
4
|
+
|
5
|
+
## 4.9.0
|
6
|
+
- Added `target` option, allowing the hit's source to target a specific field instead of being expanded at the root of the event. This allows the input to play nicer with the Elastic Common Schema when the input does not follow the schema. [#117](https://github.com/logstash-plugins/logstash-input-elasticsearch/issues/117)
|
7
|
+
|
8
|
+
## 4.8.3
|
9
|
+
- [DOC] Fixed links to restructured Logstash-to-cloud docs [#139](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/139)
|
10
|
+
|
11
|
+
## 4.8.2
|
12
|
+
- [DOC] Document the permissions required in secured clusters [#137](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/137)
|
13
|
+
|
14
|
+
## 4.8.1
|
15
|
+
- Fixed connection error when using multiple `slices`. [#133](https://github.com/logstash-plugins/logstash-input-elasticsearch/issues/133)
|
16
|
+
|
17
|
+
## 4.8.0
|
18
|
+
- Added the ability to configure connection-, request-, and socket-timeouts with `connect_timeout_seconds`, `request_timeout_seconds`, and `socket_timeout_seconds` [#121](https://github.com/logstash-plugins/logstash-input-elasticsearch/issues/121)
|
19
|
+
|
20
|
+
## 4.7.1
|
21
|
+
- [DOC] Updated sliced scroll link to resolve to correct location after doc structure change [#135](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/135)
|
22
|
+
- [DOC] Added usage example of docinfo metadata [#98](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/98)
|
23
|
+
|
1
24
|
## 4.7.0
|
2
25
|
- Added api_key support [#131](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/131)
|
3
26
|
|
data/CONTRIBUTORS
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Logstash Plugin
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/logstash-input-elasticsearch.svg)](https://badge.fury.io/rb/logstash-input-elasticsearch)
|
4
|
-
[![Travis Build Status](https://travis-ci.
|
4
|
+
[![Travis Build Status](https://travis-ci.com/logstash-plugins/logstash-input-elasticsearch.svg)](https://travis-ci.com/logstash-plugins/logstash-input-elasticsearch)
|
5
5
|
|
6
6
|
This is a plugin for [Logstash](https://github.com/elastic/logstash).
|
7
7
|
|
data/docs/index.asciidoc
CHANGED
@@ -77,6 +77,11 @@ Authentication to a secure Elasticsearch cluster is possible using _one_ of the
|
|
77
77
|
* <<plugins-{type}s-{plugin}-cloud_auth>>
|
78
78
|
* <<plugins-{type}s-{plugin}-api_key>>
|
79
79
|
|
80
|
+
[id="plugins-{type}s-{plugin}-autz"]
|
81
|
+
==== Authorization
|
82
|
+
|
83
|
+
Authorization to a secure Elasticsearch cluster requires `read` permission at index level and `monitoring` permissions at cluster level.
|
84
|
+
The `monitoring` permission at cluster level is necessary to perform periodic connectivity checks.
|
80
85
|
|
81
86
|
[id="plugins-{type}s-{plugin}-options"]
|
82
87
|
==== Elasticsearch Input Configuration Options
|
@@ -90,6 +95,7 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
90
95
|
| <<plugins-{type}s-{plugin}-ca_file>> |a valid filesystem path|No
|
91
96
|
| <<plugins-{type}s-{plugin}-cloud_auth>> |<<password,password>>|No
|
92
97
|
| <<plugins-{type}s-{plugin}-cloud_id>> |<<string,string>>|No
|
98
|
+
| <<plugins-{type}s-{plugin}-connect_timeout_seconds>> | <<number,number>>|No
|
93
99
|
| <<plugins-{type}s-{plugin}-docinfo>> |<<boolean,boolean>>|No
|
94
100
|
| <<plugins-{type}s-{plugin}-docinfo_fields>> |<<array,array>>|No
|
95
101
|
| <<plugins-{type}s-{plugin}-docinfo_target>> |<<string,string>>|No
|
@@ -98,11 +104,14 @@ This plugin supports the following configuration options plus the <<plugins-{typ
|
|
98
104
|
| <<plugins-{type}s-{plugin}-password>> |<<password,password>>|No
|
99
105
|
| <<plugins-{type}s-{plugin}-proxy>> |<<uri,uri>>|No
|
100
106
|
| <<plugins-{type}s-{plugin}-query>> |<<string,string>>|No
|
107
|
+
| <<plugins-{type}s-{plugin}-request_timeout_seconds>> | <<number,number>>|No
|
101
108
|
| <<plugins-{type}s-{plugin}-schedule>> |<<string,string>>|No
|
102
109
|
| <<plugins-{type}s-{plugin}-scroll>> |<<string,string>>|No
|
103
110
|
| <<plugins-{type}s-{plugin}-size>> |<<number,number>>|No
|
104
111
|
| <<plugins-{type}s-{plugin}-slices>> |<<number,number>>|No
|
105
112
|
| <<plugins-{type}s-{plugin}-ssl>> |<<boolean,boolean>>|No
|
113
|
+
| <<plugins-{type}s-{plugin}-socket_timeout_seconds>> | <<number,number>>|No
|
114
|
+
| <<plugins-{type}s-{plugin}-target>> | {logstash-ref}/field-references-deepdive.html[field reference] | No
|
106
115
|
| <<plugins-{type}s-{plugin}-user>> |<<string,string>>|No
|
107
116
|
|=======================================================================
|
108
117
|
|
@@ -119,7 +128,10 @@ input plugins.
|
|
119
128
|
|
120
129
|
Authenticate using Elasticsearch API key. Note that this option also requires enabling the `ssl` option.
|
121
130
|
|
122
|
-
Format is `id:api_key` where `id` and `api_key` are as returned by the
|
131
|
+
Format is `id:api_key` where `id` and `api_key` are as returned by the
|
132
|
+
Elasticsearch
|
133
|
+
{ref}/security-api-create-api-key.html[Create
|
134
|
+
API key API].
|
123
135
|
|
124
136
|
[id="plugins-{type}s-{plugin}-ca_file"]
|
125
137
|
===== `ca_file`
|
@@ -137,7 +149,8 @@ SSL Certificate Authority file in PEM encoded format, must also include any chai
|
|
137
149
|
|
138
150
|
Cloud authentication string ("<username>:<password>" format) is an alternative for the `user`/`password` pair.
|
139
151
|
|
140
|
-
For more info, check out the
|
152
|
+
For more info, check out the
|
153
|
+
{logstash-ref}/connecting-to-cloud.html[Logstash-to-Cloud documentation].
|
141
154
|
|
142
155
|
[id="plugins-{type}s-{plugin}-cloud_id"]
|
143
156
|
===== `cloud_id`
|
@@ -147,7 +160,17 @@ For more info, check out the https://www.elastic.co/guide/en/logstash/current/co
|
|
147
160
|
|
148
161
|
Cloud ID, from the Elastic Cloud web console. If set `hosts` should not be used.
|
149
162
|
|
150
|
-
For more info, check out the
|
163
|
+
For more info, check out the
|
164
|
+
{logstash-ref}/connecting-to-cloud.html[Logstash-to-Cloud documentation].
|
165
|
+
|
166
|
+
[id="plugins-{type}s-{plugin}-connect_timeout_seconds"]
|
167
|
+
===== `connect_timeout_seconds`
|
168
|
+
|
169
|
+
* Value type is <<number,number>>
|
170
|
+
* Default value is `10`
|
171
|
+
|
172
|
+
The maximum amount of time, in seconds, to wait while establishing a connection to Elasticsearch.
|
173
|
+
Connect timeouts tend to occur when Elasticsearch or an intermediate proxy is overloaded with requests and has exhausted its connection pool.
|
151
174
|
|
152
175
|
[id="plugins-{type}s-{plugin}-docinfo"]
|
153
176
|
===== `docinfo`
|
@@ -184,6 +207,19 @@ Example
|
|
184
207
|
}
|
185
208
|
}
|
186
209
|
|
210
|
+
If set, you can use metadata information in the <<plugins-{type}s-{plugin}-add_field>> common option.
|
211
|
+
|
212
|
+
Example
|
213
|
+
[source, ruby]
|
214
|
+
input {
|
215
|
+
elasticsearch {
|
216
|
+
docinfo => true
|
217
|
+
add_field => {
|
218
|
+
identifier => "%{[@metadata][_index]}:%{[@metadata][_type]}:%{[@metadata][_id]}"
|
219
|
+
}
|
220
|
+
}
|
221
|
+
}
|
222
|
+
|
187
223
|
|
188
224
|
[id="plugins-{type}s-{plugin}-docinfo_fields"]
|
189
225
|
===== `docinfo_fields`
|
@@ -222,10 +258,9 @@ can be either IP, HOST, IP:port, or HOST:port. The port defaults to
|
|
222
258
|
* Value type is <<string,string>>
|
223
259
|
* Default value is `"logstash-*"`
|
224
260
|
|
225
|
-
The index or alias to search. See
|
226
|
-
|
227
|
-
|
228
|
-
multiple indices.
|
261
|
+
The index or alias to search. See {ref}/multi-index.html[Multi Indices
|
262
|
+
documentation] in the Elasticsearch documentation for more information on how to
|
263
|
+
reference multiple indices.
|
229
264
|
|
230
265
|
|
231
266
|
[id="plugins-{type}s-{plugin}-password"]
|
@@ -254,9 +289,18 @@ environment variables e.g. `proxy => '${LS_PROXY:}'`.
|
|
254
289
|
* Value type is <<string,string>>
|
255
290
|
* Default value is `'{ "sort": [ "_doc" ] }'`
|
256
291
|
|
257
|
-
The query to be executed. Read the
|
258
|
-
|
259
|
-
|
292
|
+
The query to be executed. Read the {ref}/query-dsl.html[Elasticsearch query DSL
|
293
|
+
documentation] for more information.
|
294
|
+
|
295
|
+
[id="plugins-{type}s-{plugin}-request_timeout_seconds"]
|
296
|
+
===== `request_timeout_seconds`
|
297
|
+
|
298
|
+
* Value type is <<number,number>>
|
299
|
+
* Default value is `60`
|
300
|
+
|
301
|
+
The maximum amount of time, in seconds, for a single request to Elasticsearch.
|
302
|
+
Request timeouts tend to occur when an individual page of data is very large, such as when it contains large-payload
|
303
|
+
documents and/or the <<plugins-{type}s-{plugin}-size>> has been specified as a large value.
|
260
304
|
|
261
305
|
[id="plugins-{type}s-{plugin}-schedule"]
|
262
306
|
===== `schedule`
|
@@ -296,8 +340,8 @@ This allows you to set the maximum number of hits returned per scroll.
|
|
296
340
|
* Sensible values range from 2 to about 8.
|
297
341
|
|
298
342
|
In some cases, it is possible to improve overall throughput by consuming multiple
|
299
|
-
distinct slices of a query simultaneously using
|
300
|
-
|
343
|
+
distinct slices of a query simultaneously using
|
344
|
+
{ref}/paginate-search-results.html#slice-scroll[sliced scrolls],
|
301
345
|
especially if the pipeline is spending significant time waiting on Elasticsearch
|
302
346
|
to provide results.
|
303
347
|
|
@@ -321,6 +365,28 @@ instructions into the query.
|
|
321
365
|
If enabled, SSL will be used when communicating with the Elasticsearch
|
322
366
|
server (i.e. HTTPS will be used instead of plain HTTP).
|
323
367
|
|
368
|
+
[id="plugins-{type}s-{plugin}-socket_timeout_seconds"]
|
369
|
+
===== `socket_timeout_seconds`
|
370
|
+
|
371
|
+
* Value type is <<number,number>>
|
372
|
+
* Default value is `60`
|
373
|
+
|
374
|
+
The maximum amount of time, in seconds, to wait on an incomplete response from Elasticsearch while no additional data has been appended.
|
375
|
+
Socket timeouts usually occur while waiting for the first byte of a response, such as when executing a particularly complex query.
|
376
|
+
|
377
|
+
|
378
|
+
[id="plugins-{type}s-{plugin}-target"]
|
379
|
+
===== `target`
|
380
|
+
|
381
|
+
* Value type is {logstash-ref}/field-references-deepdive.html[field reference]
|
382
|
+
* There is no default value for this setting.
|
383
|
+
|
384
|
+
Without a `target`, events are created from each hit's `_source` at the root level.
|
385
|
+
When the `target` is set to a field reference, the `_source` of the hit is placed in the target field instead.
|
386
|
+
|
387
|
+
This option can be useful to avoid populating unknown fields when a downstream schema such as ECS is enforced.
|
388
|
+
It is also possible to target an entry in the event's metadata, which will be available during event processing but not exported to your outputs (e.g., `target \=> "[@metadata][_source]"`).
|
389
|
+
|
324
390
|
[id="plugins-{type}s-{plugin}-user"]
|
325
391
|
===== `user`
|
326
392
|
|
@@ -3,7 +3,9 @@ require "logstash/inputs/base"
|
|
3
3
|
require "logstash/namespace"
|
4
4
|
require "logstash/json"
|
5
5
|
require "logstash/util/safe_uri"
|
6
|
+
require 'logstash/plugin_mixins/validator_support/field_reference_validation_adapter'
|
6
7
|
require "base64"
|
8
|
+
require_relative "patch"
|
7
9
|
|
8
10
|
|
9
11
|
# .Compatibility Note
|
@@ -61,6 +63,8 @@ require "base64"
|
|
61
63
|
#
|
62
64
|
#
|
63
65
|
class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
|
66
|
+
extend LogStash::PluginMixins::ValidatorSupport::FieldReferenceValidationAdapter
|
67
|
+
|
64
68
|
config_name "elasticsearch"
|
65
69
|
|
66
70
|
default :codec, "json"
|
@@ -135,6 +139,15 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
|
|
135
139
|
# Basic Auth - password
|
136
140
|
config :password, :validate => :password
|
137
141
|
|
142
|
+
# Connection Timeout, in Seconds
|
143
|
+
config :connect_timeout_seconds, :validate => :positive_whole_number, :default => 10
|
144
|
+
|
145
|
+
# Request Timeout, in Seconds
|
146
|
+
config :request_timeout_seconds, :validate => :positive_whole_number, :default => 60
|
147
|
+
|
148
|
+
# Socket Timeout, in Seconds
|
149
|
+
config :socket_timeout_seconds, :validate => :positive_whole_number, :default => 60
|
150
|
+
|
138
151
|
# Cloud ID, from the Elastic Cloud web console. If set `hosts` should not be used.
|
139
152
|
#
|
140
153
|
# For more info, check out the https://www.elastic.co/guide/en/logstash/current/connecting-to-cloud.html#_cloud_id[Logstash-to-Cloud documentation]
|
@@ -165,6 +178,9 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
|
|
165
178
|
# exactly once.
|
166
179
|
config :schedule, :validate => :string
|
167
180
|
|
181
|
+
# If set, the _source of each hit will be added nested under the target instead of at the top-level
|
182
|
+
config :target, :validate => :field_reference
|
183
|
+
|
168
184
|
def register
|
169
185
|
require "elasticsearch"
|
170
186
|
require "rufus/scheduler"
|
@@ -189,6 +205,9 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
|
|
189
205
|
transport_options = {:headers => {}}
|
190
206
|
transport_options[:headers].merge!(setup_basic_auth(user, password))
|
191
207
|
transport_options[:headers].merge!(setup_api_key(api_key))
|
208
|
+
transport_options[:request_timeout] = @request_timeout_seconds unless @request_timeout_seconds.nil?
|
209
|
+
transport_options[:connect_timeout] = @connect_timeout_seconds unless @connect_timeout_seconds.nil?
|
210
|
+
transport_options[:socket_timeout] = @socket_timeout_seconds unless @socket_timeout_seconds.nil?
|
192
211
|
|
193
212
|
hosts = setup_hosts
|
194
213
|
ssl_options = setup_ssl
|
@@ -205,22 +224,7 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
|
|
205
224
|
)
|
206
225
|
end
|
207
226
|
|
208
|
-
##
|
209
|
-
# @override to handle proxy => '' as if none was set
|
210
|
-
# @param value [Array<Object>]
|
211
|
-
# @param validator [nil,Array,Symbol]
|
212
|
-
# @return [Array(true,Object)]: if validation is a success, a tuple containing `true` and the coerced value
|
213
|
-
# @return [Array(false,String)]: if validation is a failure, a tuple containing `false` and the failure reason.
|
214
|
-
def self.validate_value(value, validator)
|
215
|
-
return super unless validator == :uri_or_empty
|
216
227
|
|
217
|
-
value = deep_replace(value)
|
218
|
-
value = hash_or_array(value)
|
219
|
-
|
220
|
-
return true, value.first if value.size == 1 && value.first.empty?
|
221
|
-
|
222
|
-
return super(value, :uri)
|
223
|
-
end
|
224
228
|
|
225
229
|
def run(output_queue)
|
226
230
|
if @schedule
|
@@ -300,7 +304,12 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
|
|
300
304
|
end
|
301
305
|
|
302
306
|
def push_hit(hit, output_queue)
|
303
|
-
|
307
|
+
if @target.nil?
|
308
|
+
event = LogStash::Event.new(hit['_source'])
|
309
|
+
else
|
310
|
+
event = LogStash::Event.new
|
311
|
+
event.set(@target, hit['_source'])
|
312
|
+
end
|
304
313
|
|
305
314
|
if @docinfo
|
306
315
|
# do not assume event[@docinfo_target] to be in-place updatable. first get it, update it, then at the end set it in the event.
|
@@ -439,4 +448,42 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
|
|
439
448
|
[ cloud_auth.username, cloud_auth.password ]
|
440
449
|
end
|
441
450
|
|
451
|
+
module URIOrEmptyValidator
|
452
|
+
##
|
453
|
+
# @override to provide :uri_or_empty validator
|
454
|
+
# @param value [Array<Object>]
|
455
|
+
# @param validator [nil,Array,Symbol]
|
456
|
+
# @return [Array(true,Object)]: if validation is a success, a tuple containing `true` and the coerced value
|
457
|
+
# @return [Array(false,String)]: if validation is a failure, a tuple containing `false` and the failure reason.
|
458
|
+
def validate_value(value, validator)
|
459
|
+
return super unless validator == :uri_or_empty
|
460
|
+
|
461
|
+
value = deep_replace(value)
|
462
|
+
value = hash_or_array(value)
|
463
|
+
|
464
|
+
return true, value.first if value.size == 1 && value.first.empty?
|
465
|
+
|
466
|
+
return super(value, :uri)
|
467
|
+
end
|
468
|
+
end
|
469
|
+
extend(URIOrEmptyValidator)
|
470
|
+
|
471
|
+
module PositiveWholeNumberValidator
|
472
|
+
##
|
473
|
+
# @override to provide :positive_whole_number validator
|
474
|
+
# @param value [Array<Object>]
|
475
|
+
# @param validator [nil,Array,Symbol]
|
476
|
+
# @return [Array(true,Object)]: if validation is a success, a tuple containing `true` and the coerced value
|
477
|
+
# @return [Array(false,String)]: if validation is a failure, a tuple containing `false` and the failure reason.
|
478
|
+
def validate_value(value, validator)
|
479
|
+
return super unless validator == :positive_whole_number
|
480
|
+
|
481
|
+
is_number, coerced_number = super(value, :number)
|
482
|
+
|
483
|
+
return [true, coerced_number.to_i] if is_number && coerced_number.denominator == 1 && coerced_number > 0
|
484
|
+
|
485
|
+
return [false, "Expected positive whole number, got `#{value.inspect}`"]
|
486
|
+
end
|
487
|
+
end
|
488
|
+
extend(PositiveWholeNumberValidator)
|
442
489
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
if Gem.loaded_specs['elasticsearch-transport'].version >= Gem::Version.new("7.2.0")
|
2
|
+
# elasticsearch-transport versions prior to 7.2.0 suffered of a race condition on accessing
|
3
|
+
# the connection pool. This issue was fixed with https://github.com/elastic/elasticsearch-ruby/commit/15f9d78591a6e8823948494d94b15b0ca38819d1
|
4
|
+
# This plugin, at the moment, is forced to use v5.x so we have to monkey patch the gem. When this requirement
|
5
|
+
# ceases, this patch could be removed.
|
6
|
+
puts "WARN remove the patch code into logstash-input-elasticsearch plugin"
|
7
|
+
else
|
8
|
+
module Elasticsearch
|
9
|
+
module Transport
|
10
|
+
module Transport
|
11
|
+
module Connections
|
12
|
+
module Selector
|
13
|
+
|
14
|
+
# "Round-robin" selector strategy (default).
|
15
|
+
#
|
16
|
+
class RoundRobin
|
17
|
+
include Base
|
18
|
+
|
19
|
+
# @option arguments [Connections::Collection] :connections Collection with connections.
|
20
|
+
#
|
21
|
+
def initialize(arguments = {})
|
22
|
+
super
|
23
|
+
@mutex = Mutex.new
|
24
|
+
@current = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns the next connection from the collection, rotating them in round-robin fashion.
|
28
|
+
#
|
29
|
+
# @return [Connections::Connection]
|
30
|
+
#
|
31
|
+
def select(options={})
|
32
|
+
@mutex.synchronize do
|
33
|
+
conns = connections
|
34
|
+
if @current && (@current < conns.size-1)
|
35
|
+
@current += 1
|
36
|
+
else
|
37
|
+
@current = 0
|
38
|
+
end
|
39
|
+
conns[@current]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-input-elasticsearch'
|
4
|
-
s.version = '4.
|
4
|
+
s.version = '4.9.1'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Reads query results from an Elasticsearch cluster"
|
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"
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.metadata = { "logstash_plugin" => "true", "logstash_group" => "input" }
|
21
21
|
|
22
22
|
# Gem dependencies
|
23
|
+
s.add_runtime_dependency "logstash-mixin-validator_support", '~> 1.0'
|
23
24
|
s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
|
24
25
|
|
25
26
|
s.add_runtime_dependency 'elasticsearch', '>= 5.0.3'
|
@@ -40,57 +40,91 @@ describe LogStash::Inputs::TestableElasticsearch do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
|
-
config
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
43
|
+
context 'creating events from Elasticsearch' do
|
44
|
+
let(:config) do
|
45
|
+
%q[
|
46
|
+
input {
|
47
|
+
elasticsearch {
|
48
|
+
hosts => ["localhost"]
|
49
|
+
query => '{ "query": { "match": { "city_name": "Okinawa" } }, "fields": ["message"] }'
|
50
|
+
}
|
49
51
|
}
|
52
|
+
]
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:mock_response) do
|
56
|
+
{
|
57
|
+
"_scroll_id" => "cXVlcnlUaGVuRmV0Y2g",
|
58
|
+
"took" => 27,
|
59
|
+
"timed_out" => false,
|
60
|
+
"_shards" => {
|
61
|
+
"total" => 169,
|
62
|
+
"successful" => 169,
|
63
|
+
"failed" => 0
|
64
|
+
},
|
65
|
+
"hits" => {
|
66
|
+
"total" => 1,
|
67
|
+
"max_score" => 1.0,
|
68
|
+
"hits" => [ {
|
69
|
+
"_index" => "logstash-2014.10.12",
|
70
|
+
"_type" => "logs",
|
71
|
+
"_id" => "C5b2xLQwTZa76jBmHIbwHQ",
|
72
|
+
"_score" => 1.0,
|
73
|
+
"_source" => { "message" => ["ohayo"] }
|
74
|
+
} ]
|
75
|
+
}
|
50
76
|
}
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
"_shards" => {
|
58
|
-
"total" => 169,
|
59
|
-
"successful" => 169,
|
60
|
-
"failed" => 0
|
61
|
-
},
|
62
|
-
"hits" => {
|
63
|
-
"total" => 1,
|
64
|
-
"max_score" => 1.0,
|
65
|
-
"hits" => [ {
|
66
|
-
"_index" => "logstash-2014.10.12",
|
67
|
-
"_type" => "logs",
|
68
|
-
"_id" => "C5b2xLQwTZa76jBmHIbwHQ",
|
69
|
-
"_score" => 1.0,
|
70
|
-
"_source" => { "message" => ["ohayo"] }
|
71
|
-
} ]
|
77
|
+
end
|
78
|
+
|
79
|
+
let(:mock_scroll_response) do
|
80
|
+
{
|
81
|
+
"_scroll_id" => "r453Wc1jh0caLJhSDg",
|
82
|
+
"hits" => { "hits" => [] }
|
72
83
|
}
|
73
|
-
|
84
|
+
end
|
74
85
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
86
|
+
before(:each) do
|
87
|
+
client = Elasticsearch::Client.new
|
88
|
+
expect(Elasticsearch::Client).to receive(:new).with(any_args).and_return(client)
|
89
|
+
expect(client).to receive(:search).with(any_args).and_return(mock_response)
|
90
|
+
expect(client).to receive(:scroll).with({ :body => { :scroll_id => "cXVlcnlUaGVuRmV0Y2g" }, :scroll=> "1m" }).and_return(mock_scroll_response)
|
91
|
+
expect(client).to receive(:clear_scroll).and_return(nil)
|
92
|
+
end
|
79
93
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
expect(client).to receive(:clear_scroll).and_return(nil)
|
94
|
+
it 'creates the events from the hits' do
|
95
|
+
event = input(config) do |pipeline, queue|
|
96
|
+
queue.pop
|
97
|
+
end
|
85
98
|
|
86
|
-
|
87
|
-
|
99
|
+
expect(event).to be_a(LogStash::Event)
|
100
|
+
puts event.to_hash_with_metadata
|
101
|
+
expect(event.get("message")).to eql [ "ohayo" ]
|
88
102
|
end
|
89
103
|
|
90
|
-
|
91
|
-
|
92
|
-
|
104
|
+
context 'when a target is set' do
|
105
|
+
let(:config) do
|
106
|
+
%q[
|
107
|
+
input {
|
108
|
+
elasticsearch {
|
109
|
+
hosts => ["localhost"]
|
110
|
+
query => '{ "query": { "match": { "city_name": "Okinawa" } }, "fields": ["message"] }'
|
111
|
+
target => "[@metadata][_source]"
|
112
|
+
}
|
113
|
+
}
|
114
|
+
]
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'creates the event using the target' do
|
118
|
+
event = input(config) do |pipeline, queue|
|
119
|
+
queue.pop
|
120
|
+
end
|
93
121
|
|
122
|
+
expect(event).to be_a(LogStash::Event)
|
123
|
+
puts event.to_hash_with_metadata
|
124
|
+
expect(event.get("[@metadata][_source][message]")).to eql [ "ohayo" ]
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
94
128
|
|
95
129
|
# This spec is an adapter-spec, ensuring that we send the right sequence of messages to our Elasticsearch Client
|
96
130
|
# to support sliced scrolling. The underlying implementation will spawn its own threads to consume, so we must be
|
@@ -640,6 +674,54 @@ describe LogStash::Inputs::TestableElasticsearch do
|
|
640
674
|
end
|
641
675
|
end
|
642
676
|
end
|
677
|
+
|
678
|
+
shared_examples'configurable timeout' do |config_name, manticore_transport_option|
|
679
|
+
let(:config_value) { fail NotImplementedError }
|
680
|
+
let(:config) { super().merge(config_name => config_value) }
|
681
|
+
{
|
682
|
+
:string => 'banana',
|
683
|
+
:negative => -123,
|
684
|
+
:zero => 0,
|
685
|
+
}.each do |value_desc, value|
|
686
|
+
let(:config_value) { value }
|
687
|
+
context "with an invalid #{value_desc} value" do
|
688
|
+
it 'prevents instantiation with a helpful message' do
|
689
|
+
expect(described_class.logger).to receive(:error).with(/Expected positive whole number/)
|
690
|
+
expect { described_class.new(config) }.to raise_error(LogStash::ConfigurationError)
|
691
|
+
end
|
692
|
+
end
|
693
|
+
end
|
694
|
+
|
695
|
+
context 'with a valid value' do
|
696
|
+
let(:config_value) { 17 }
|
697
|
+
|
698
|
+
it "instantiates the elasticsearch client with the timeout value set via #{manticore_transport_option} in the transport options" do
|
699
|
+
expect(Elasticsearch::Client).to receive(:new) do |new_elasticsearch_client_params|
|
700
|
+
# We rely on Manticore-specific transport options, fail early if we are using a different
|
701
|
+
# transport or are allowing the client to determine its own transport class.
|
702
|
+
expect(new_elasticsearch_client_params).to include(:transport_class)
|
703
|
+
expect(new_elasticsearch_client_params[:transport_class].name).to match(/\bManticore\b/)
|
704
|
+
|
705
|
+
expect(new_elasticsearch_client_params).to include(:transport_options)
|
706
|
+
transport_options = new_elasticsearch_client_params[:transport_options]
|
707
|
+
expect(transport_options).to include(manticore_transport_option)
|
708
|
+
expect(transport_options[manticore_transport_option]).to eq(config_value.to_i)
|
709
|
+
end
|
710
|
+
|
711
|
+
plugin.register
|
712
|
+
end
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
context 'connect_timeout_seconds' do
|
717
|
+
include_examples('configurable timeout', 'connect_timeout_seconds', :connect_timeout)
|
718
|
+
end
|
719
|
+
context 'request_timeout_seconds' do
|
720
|
+
include_examples('configurable timeout', 'request_timeout_seconds', :request_timeout)
|
721
|
+
end
|
722
|
+
context 'socket_timeout_seconds' do
|
723
|
+
include_examples('configurable timeout', 'socket_timeout_seconds', :socket_timeout)
|
724
|
+
end
|
643
725
|
end
|
644
726
|
|
645
727
|
context "when scheduling" do
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-elasticsearch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.9.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '1.0'
|
19
|
+
name: logstash-mixin-validator_support
|
20
|
+
prerelease: false
|
21
|
+
type: :runtime
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
requirement: !ruby/object:Gem::Requirement
|
15
29
|
requirements:
|
@@ -200,6 +214,7 @@ files:
|
|
200
214
|
- README.md
|
201
215
|
- docs/index.asciidoc
|
202
216
|
- lib/logstash/inputs/elasticsearch.rb
|
217
|
+
- lib/logstash/inputs/patch.rb
|
203
218
|
- logstash-input-elasticsearch.gemspec
|
204
219
|
- spec/es_helper.rb
|
205
220
|
- spec/fixtures/test_certs/ca/ca.crt
|