logstash-input-elasticsearch 4.17.0 → 4.17.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 43e3c8e44ba8bd1ce4065a1410b26a63d621180d0354b4b4aa8f3891962d9986
4
- data.tar.gz: c9f6d3b53d1bb90c9ad77eab86b92818128f310aa95a80e2908bdc5b981a780f
3
+ metadata.gz: 54b223c24702d4e9eb27efc05d351dbe9138d7be576a72e552bea3ef40254bb5
4
+ data.tar.gz: 697ade265dd83a9b87a6802e650a9100e64195315577e927c8228cdb6b18e720
5
5
  SHA512:
6
- metadata.gz: 5799d6ef93349a2ca9a6408bba0bbaa78f5c985137a4d126c70efe53122b7eac4d1fcda48aeb51f629651ea04e4457e9bb9705b760744b0ff22cd462f617c7b8
7
- data.tar.gz: f0057cebd50dc79156d8f05be48341f009366fc9057df0f61d50327a3cecf0a95ebccd05bed120173ab429caab295d5b71f25edc04232fd36ecf862ad58bd974
6
+ metadata.gz: 50ac2baa3e825cca7ffd51321bf42530b5c6f32dd88db94c9a0ce5ec2e978de5e0e82f645d6c8116972b40e6efae01782a73dc38bbda50d513df1bb88acf6e75
7
+ data.tar.gz: 50290a768d6f8985cef40b393bdf4d80842416825c5d3e8d835485b9a96adf4f52cbfd654fb687c92cc22fdcc616cf70147f0d9ded807e1a07d135f23e6a2fd7
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 4.17.2
2
+ - Fixes a regression introduced in 4.17.0 which could prevent a connection from being established to Elasticsearch in some SSL configurations [#193](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/193)
3
+
4
+ ## 4.17.1
5
+ - Fix: scroll slice high memory consumption [#189](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/189)
6
+
1
7
  ## 4.17.0
2
8
  - Added SSL settings for: [#185](https://github.com/logstash-plugins/logstash-input-elasticsearch/pull/185)
3
9
  - `ssl_enabled`: Enable/disable the SSL settings. If not provided, the value is inferred from the hosts scheme
data/docs/index.asciidoc CHANGED
@@ -353,6 +353,7 @@ documents and/or the <<plugins-{type}s-{plugin}-size>> has been specified as a l
353
353
  The number of times to re-run the query after the first failure. If the query fails after all retries, it logs an error message.
354
354
  The default is 0 (no retry). This value should be equal to or greater than zero.
355
355
 
356
+ NOTE: Partial failures - such as errors in a subset of all slices - can result in the entire query being retried, which can lead to duplication of data. Avoiding this would require Logstash to store the entire result set of a query in memory which is often not possible.
356
357
 
357
358
  [id="plugins-{type}s-{plugin}-schedule"]
358
359
  ===== `schedule`
@@ -256,6 +256,8 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
256
256
  # config :ca_trusted_fingerprint, :validate => :sha_256_hex
257
257
  include LogStash::PluginMixins::CATrustedFingerprintSupport
258
258
 
259
+ attr_reader :pipeline_id
260
+
259
261
  def initialize(params={})
260
262
  super(params)
261
263
 
@@ -267,6 +269,8 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
267
269
  def register
268
270
  require "rufus/scheduler"
269
271
 
272
+ @pipeline_id = execution_context&.pipeline_id || 'main'
273
+
270
274
  fill_hosts_from_cloud_id
271
275
  setup_ssl_params!
272
276
 
@@ -326,20 +330,22 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
326
330
  def do_run(output_queue)
327
331
  # if configured to run a single slice, don't bother spinning up threads
328
332
  if @slices.nil? || @slices <= 1
329
- success, events = retryable_slice
330
- success && events.each { |event| output_queue << event }
331
- return
333
+ return retryable(JOB_NAME) do
334
+ do_run_slice(output_queue)
335
+ end
332
336
  end
333
337
 
334
338
  logger.warn("managed slices for query is very large (#{@slices}); consider reducing") if @slices > 8
335
339
 
336
- slice_results = parallel_slice # array of tuple(ok, events)
337
340
 
338
- # insert events to queue if all slices success
339
- if slice_results.all?(&:first)
340
- slice_results.flat_map { |success, events| events }
341
- .each { |event| output_queue << event }
342
- end
341
+ @slices.times.map do |slice_id|
342
+ Thread.new do
343
+ LogStash::Util::set_thread_name("[#{pipeline_id}]|input|elasticsearch|slice_#{slice_id}")
344
+ retryable(JOB_NAME) do
345
+ do_run_slice(output_queue, slice_id)
346
+ end
347
+ end
348
+ end.map(&:join)
343
349
 
344
350
  logger.trace("#{@slices} slices completed")
345
351
  end
@@ -347,42 +353,14 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
347
353
  def retryable(job_name, &block)
348
354
  begin
349
355
  stud_try = ::LogStash::Helpers::LoggableTry.new(logger, job_name)
350
- output = stud_try.try((@retries + 1).times) { yield }
351
- [true, output]
356
+ stud_try.try((@retries + 1).times) { yield }
352
357
  rescue => e
353
358
  error_details = {:message => e.message, :cause => e.cause}
354
359
  error_details[:backtrace] = e.backtrace if logger.debug?
355
360
  logger.error("Tried #{job_name} unsuccessfully", error_details)
356
- [false, nil]
357
361
  end
358
362
  end
359
363
 
360
-
361
- # @return [(ok, events)] : Array of tuple(Boolean, [Logstash::Event])
362
- def parallel_slice
363
- pipeline_id = execution_context&.pipeline_id || 'main'
364
- @slices.times.map do |slice_id|
365
- Thread.new do
366
- LogStash::Util::set_thread_name("[#{pipeline_id}]|input|elasticsearch|slice_#{slice_id}")
367
- retryable_slice(slice_id)
368
- end
369
- end.map do |t|
370
- t.join
371
- t.value
372
- end
373
- end
374
-
375
- # @param scroll_id [Integer]
376
- # @return (ok, events) [Boolean, Array(Logstash::Event)]
377
- def retryable_slice(slice_id=nil)
378
- retryable(JOB_NAME) do
379
- output = []
380
- do_run_slice(output, slice_id)
381
- output
382
- end
383
- end
384
-
385
-
386
364
  def do_run_slice(output_queue, slice_id=nil)
387
365
  slice_query = @base_query
388
366
  slice_query = slice_query.merge('slice' => { 'id' => slice_id, 'max' => @slices}) unless slice_id.nil?
@@ -543,7 +521,9 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
543
521
  "to make sure your data is secure set `ssl_verification_mode => full`"
544
522
  ssl_options[:verify] = :disable
545
523
  else
546
- ssl_options[:verify] = :strict
524
+ # Manticore's :default maps to Apache HTTP Client's DefaultHostnameVerifier,
525
+ # which is the modern STRICT verifier that replaces the deprecated StrictHostnameVerifier
526
+ ssl_options[:verify] = :default
547
527
  end
548
528
  end
549
529
 
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-input-elasticsearch'
4
- s.version = '4.17.0'
4
+ s.version = '4.17.2'
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"
@@ -204,7 +204,7 @@ describe LogStash::Inputs::Elasticsearch, :ecs_compatibility_support do
204
204
  context 'with `slices => 1`' do
205
205
  let(:slices) { 1 }
206
206
  it 'runs just one slice' do
207
- expect(plugin).to receive(:do_run_slice).with(duck_type(:<<), nil)
207
+ expect(plugin).to receive(:do_run_slice).with(duck_type(:<<))
208
208
  expect(Thread).to_not receive(:new)
209
209
 
210
210
  plugin.register
@@ -215,7 +215,7 @@ describe LogStash::Inputs::Elasticsearch, :ecs_compatibility_support do
215
215
  context 'without slices directive' do
216
216
  let(:config) { super().tap { |h| h.delete('slices') } }
217
217
  it 'runs just one slice' do
218
- expect(plugin).to receive(:do_run_slice).with(duck_type(:<<), nil)
218
+ expect(plugin).to receive(:do_run_slice).with(duck_type(:<<))
219
219
  expect(Thread).to_not receive(:new)
220
220
 
221
221
  plugin.register
@@ -414,18 +414,19 @@ describe LogStash::Inputs::Elasticsearch, :ecs_compatibility_support do
414
414
  expect(Elasticsearch::Client).to receive(:new).with(any_args).and_return(client)
415
415
  plugin.register
416
416
 
417
- expect(client).to receive(:clear_scroll).and_return(nil)
417
+ expect(client).to receive(:clear_scroll).twice.and_return(nil)
418
418
 
419
- # SLICE0 is a three-page scroll in which the second page throw exception
419
+ # SLICE0 is a three-page scroll
420
420
  slice0_query = LogStash::Json.dump(query.merge('slice' => { 'id' => 0, 'max' => 2}))
421
421
  expect(client).to receive(:search).with(hash_including(:body => slice0_query)).and_return(slice0_response0)
422
- expect(client).to receive(:scroll).with(hash_including(:body => { :scroll_id => slice0_scroll1 })).and_raise("boom")
422
+ expect(client).to receive(:scroll).with(hash_including(:body => { :scroll_id => slice0_scroll1 })).and_return(slice0_response1)
423
+ expect(client).to receive(:scroll).with(hash_including(:body => { :scroll_id => slice0_scroll2 })).and_return(slice0_response2)
423
424
  allow(client).to receive(:ping)
424
425
 
425
- # SLICE1 is a two-page scroll in which the last page has no next scroll id
426
+ # SLICE1 is a two-page scroll in which the last page throws exception
426
427
  slice1_query = LogStash::Json.dump(query.merge('slice' => { 'id' => 1, 'max' => 2}))
427
428
  expect(client).to receive(:search).with(hash_including(:body => slice1_query)).and_return(slice1_response0)
428
- expect(client).to receive(:scroll).with(hash_including(:body => { :scroll_id => slice1_scroll1 })).and_return(slice1_response1)
429
+ expect(client).to receive(:scroll).with(hash_including(:body => { :scroll_id => slice1_scroll1 })).and_raise("boom")
429
430
 
430
431
  synchronize_method!(plugin, :scroll_request)
431
432
  synchronize_method!(plugin, :search_request)
@@ -433,18 +434,22 @@ describe LogStash::Inputs::Elasticsearch, :ecs_compatibility_support do
433
434
 
434
435
  let(:client) { Elasticsearch::Client.new }
435
436
 
436
- it 'does not insert event to queue' do
437
- expect(plugin).to receive(:parallel_slice).and_wrap_original do |m, *args|
438
- slice0, slice1 = m.call
439
- expect(slice0[0]).to be_falsey
440
- expect(slice1[0]).to be_truthy
441
- expect(slice1[1].size).to eq(4) # four items from SLICE1
442
- [slice0, slice1]
437
+ it 'insert event to queue without waiting other slices' do
438
+ expect(plugin).to receive(:do_run_slice).twice.and_wrap_original do |m, *args|
439
+ q = args[0]
440
+ slice_id = args[1]
441
+ if slice_id == 0
442
+ m.call(*args)
443
+ expect(q.size).to eq(3)
444
+ else
445
+ sleep(1)
446
+ m.call(*args)
447
+ end
443
448
  end
444
449
 
445
450
  queue = Queue.new
446
451
  plugin.run(queue)
447
- expect(queue.size).to eq(0)
452
+ expect(queue.size).to eq(5)
448
453
  end
449
454
  end
450
455
  end
@@ -123,7 +123,7 @@ describe "SSL options" do
123
123
 
124
124
  it "should pass the flag to the ES client" do
125
125
  expect(::Elasticsearch::Client).to receive(:new) do |args|
126
- expect(args[:ssl]).to match hash_including(:ssl => true, :verify => :strict)
126
+ expect(args[:ssl]).to match hash_including(:ssl => true, :verify => :default)
127
127
  end.and_return(es_client_double)
128
128
 
129
129
  subject.register
@@ -200,7 +200,7 @@ describe "SSL options" do
200
200
  :truststore => ssl_truststore_path,
201
201
  :truststore_type => "jks",
202
202
  :truststore_password => "foo",
203
- :verify => :strict,
203
+ :verify => :default,
204
204
  :cipher_suites => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
205
205
  :protocols => ["TLSv1.3"],
206
206
  )
@@ -236,7 +236,7 @@ describe "SSL options" do
236
236
  :ca_file => ssl_certificate_authorities_path,
237
237
  :client_cert => ssl_certificate_path,
238
238
  :client_key => ssl_key_path,
239
- :verify => :strict,
239
+ :verify => :default,
240
240
  :cipher_suites => ["TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"],
241
241
  :protocols => ["TLSv1.3"],
242
242
  )
@@ -4,7 +4,7 @@ require "logstash/plugin"
4
4
  require "logstash/inputs/elasticsearch"
5
5
  require_relative "../../../spec/es_helper"
6
6
 
7
- describe LogStash::Inputs::Elasticsearch do
7
+ describe LogStash::Inputs::Elasticsearch, :integration => true do
8
8
 
9
9
  SECURE_INTEGRATION = ENV['SECURE_INTEGRATION'].eql? 'true'
10
10
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.17.0
4
+ version: 4.17.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-10 00:00:00.000000000 Z
11
+ date: 2023-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -304,7 +304,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
304
304
  - !ruby/object:Gem::Version
305
305
  version: '0'
306
306
  requirements: []
307
- rubygems_version: 3.1.6
307
+ rubygems_version: 3.2.33
308
308
  signing_key:
309
309
  specification_version: 4
310
310
  summary: Reads query results from an Elasticsearch cluster