logstash-output-elasticsearch 11.19.0-java → 11.20.1-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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0490f311461b39c49e3edaf045af9a7172dbd97da8bc456bf044a031c18e5afb'
4
- data.tar.gz: fbf05190ed352c12f0948aecfa6ed08e760b03985b83aa2e6830167a00c431bc
3
+ metadata.gz: 3f3f97949dede5ce24e127df3a0cf4c809f1436d1ff34831cea6d0b873784968
4
+ data.tar.gz: cadc8d310da90f1cc853b24734520859101cd787efe29b5371394248303999f9
5
5
  SHA512:
6
- metadata.gz: b50084b6fb4fd31e7592be7e35e23963dce4cf284763baa4c1c042d1f159f20cebe09c1013ace38a986dbf4c8ee3cc9ae4eda7f38042956bd10dbdfc0ad20114
7
- data.tar.gz: 91643fa15c48a29a02659967c75e0b879f98af2a6e7f1582c83b141f67826337ccaa3d0513b1372266dd068cbccfcdbbe59a5fcf36ceff81318126dd1bdf64cc
6
+ metadata.gz: 9ef570b20433e6b3d69c24c9e402c39aa59a9f5556cb8c03f5643be65a7800b1a66b744be3095d11fe640a262902506fa78a7a10c3ea5b6ce1dfa81da98ea4e9
7
+ data.tar.gz: c323b23e45dfa795df06fdd206134ba340c5745529c690543bf94cfdb81526306c415723bb7a9cba759df658f38cbe6b6c62a4e6d1bbc6d777b224da830e8613
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
+ ## 11.20.1
2
+ - Doc: Replace `document_already_exist_exception` with `version_conflict_engine_exception` in the `silence_errors_in_log` setting example [#1159](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1159)
3
+
4
+ ## 11.20.0
5
+ - Changed the register to initiate pipeline shutdown upon bootstrap failure instead of simply logging the error [#1151](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1151)
6
+
1
7
  ## 11.19.0
2
- - Added `filter_path` to bulk requests to reduce the size of responses from elasticsearch
8
+ - Added `filter_path` to bulk requests to reduce the size of responses from elasticsearch [#1154](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1154)
3
9
 
4
10
  ## 11.18.0
5
11
  - Added request header `Elastic-Api-Version` for serverless [#1147](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1147)
data/docs/index.asciidoc CHANGED
@@ -988,12 +988,12 @@ if enabled, script is in charge of creating non-existent document (scripted upda
988
988
 
989
989
  Defines the list of Elasticsearch errors that you don't want to log.
990
990
  A useful example is when you want to skip all 409 errors
991
- which are `document_already_exists_exception`.
991
+ which are `version_conflict_engine_exception`.
992
992
 
993
993
  [source,ruby]
994
994
  output {
995
995
  elasticsearch {
996
- silence_errors_in_log => ["document_already_exists_exception"]
996
+ silence_errors_in_log => ["version_conflict_engine_exception"]
997
997
  }
998
998
  }
999
999
 
@@ -145,12 +145,12 @@ module LogStash module Outputs class ElasticSearch
145
145
  # @note assumes to be running AFTER {after_successful_connection} completed, due ES version checks
146
146
  # @return [Gem::Version] if ES supports DS nil (or raise) otherwise
147
147
  def assert_es_version_supports_data_streams
148
- fail 'no last_es_version' unless last_es_version # assert - should not happen
148
+ raise LogStash::ConfigurationError 'no last_es_version' unless last_es_version # assert - should not happen
149
149
  es_version = ::Gem::Version.create(last_es_version)
150
150
  if es_version < ::Gem::Version.create(DATA_STREAMS_ORIGIN_ES_VERSION)
151
151
  @logger.error "Elasticsearch version does not support data streams, Logstash might end up writing to an index", es_version: es_version.version
152
152
  # NOTE: when switching to synchronous check from register, this should be a ConfigurationError
153
- raise LogStash::Error, "A data_stream configuration is only supported since Elasticsearch #{DATA_STREAMS_ORIGIN_ES_VERSION} " +
153
+ raise LogStash::ConfigurationError, "A data_stream configuration is only supported since Elasticsearch #{DATA_STREAMS_ORIGIN_ES_VERSION} " +
154
154
  "(detected version #{es_version.version}), please upgrade your cluster"
155
155
  end
156
156
  es_version # return truthy
@@ -28,7 +28,12 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
28
28
  @response_code == 403
29
29
  end
30
30
 
31
+ def too_many_requests?
32
+ @response_code == 429
33
+ end
34
+
31
35
  end
36
+
32
37
  class HostUnreachableError < Error;
33
38
  attr_reader :original_error, :url
34
39
 
@@ -69,7 +74,7 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
69
74
  @adapter = adapter
70
75
  @metric = options[:metric]
71
76
  @initial_urls = initial_urls
72
-
77
+
73
78
  raise ArgumentError, "No URL Normalizer specified!" unless options[:url_normalizer]
74
79
  @url_normalizer = options[:url_normalizer]
75
80
  DEFAULT_OPTIONS.merge(options).tap do |merged|
@@ -159,7 +164,7 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
159
164
  :error_message => e.message,
160
165
  :class => e.class.name,
161
166
  :backtrace => e.backtrace
162
- )
167
+ )
163
168
  end
164
169
  end
165
170
  end
@@ -197,11 +202,11 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
197
202
  sniff(nodes)
198
203
  end
199
204
  end
200
-
205
+
201
206
  def major_version(version_string)
202
207
  version_string.split('.').first.to_i
203
208
  end
204
-
209
+
205
210
  def sniff(nodes)
206
211
  nodes.map do |id,info|
207
212
  # Skip master-only nodes
@@ -360,7 +365,7 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
360
365
 
361
366
  def update_urls(new_urls)
362
367
  return if new_urls.nil?
363
-
368
+
364
369
  # Normalize URLs
365
370
  new_urls = new_urls.map(&method(:normalize_url))
366
371
 
@@ -388,14 +393,14 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
388
393
  if state_changes[:removed].size > 0 || state_changes[:added].size > 0
389
394
  logger.info? && logger.info("Elasticsearch pool URLs updated", :changes => state_changes)
390
395
  end
391
-
396
+
392
397
  # Run an inline healthcheck anytime URLs are updated
393
398
  # This guarantees that during startup / post-startup
394
399
  # sniffing we don't have idle periods waiting for the
395
400
  # periodic sniffer to allow new hosts to come online
396
- healthcheck!
401
+ healthcheck!
397
402
  end
398
-
403
+
399
404
  def size
400
405
  @state_mutex.synchronize { @url_info.size }
401
406
  end
@@ -37,7 +37,7 @@ module LogStash; module Outputs; class ElasticSearch
37
37
  template_path = default_template_path(es_major_version, ecs_compatibility)
38
38
  read_template_file(template_path)
39
39
  rescue => e
40
- fail "Failed to load default template for Elasticsearch v#{es_major_version} with ECS #{ecs_compatibility}; caused by: #{e.inspect}"
40
+ raise LogStash::ConfigurationError, "Failed to load default template for Elasticsearch v#{es_major_version} with ECS #{ecs_compatibility}; caused by: #{e.inspect}"
41
41
  end
42
42
 
43
43
  def self.install(client, template_endpoint, template_name, template, template_overwrite)
@@ -99,9 +99,11 @@ module LogStash; module Outputs; class ElasticSearch
99
99
  end
100
100
 
101
101
  def self.read_template_file(template_path)
102
- raise ArgumentError, "Template file '#{template_path}' could not be found" unless ::File.exists?(template_path)
102
+ raise LogStash::ConfigurationError, "Template file '#{template_path}' could not be found" unless ::File.exists?(template_path)
103
103
  template_data = ::IO.read(template_path)
104
104
  LogStash::Json.load(template_data)
105
+ rescue => e
106
+ raise LogStash::ConfigurationError, "Failed to load template file '#{template_path}': #{e.message}"
105
107
  end
106
108
 
107
109
  def self.template_endpoint(plugin)
@@ -322,12 +322,29 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
322
322
  @bulk_request_metrics = metric.namespace(:bulk_requests)
323
323
  @document_level_metrics = metric.namespace(:documents)
324
324
 
325
+ @shutdown_from_finish_register = Concurrent::AtomicBoolean.new(false)
325
326
  @after_successful_connection_thread = after_successful_connection do
326
327
  begin
327
328
  finish_register
328
329
  true # thread.value
330
+ rescue LogStash::ConfigurationError, LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError => e
331
+ return e if pipeline_shutdown_requested?
332
+
333
+ # retry when 429
334
+ @logger.debug("Received a 429 status code during registration. Retrying..") && retry if too_many_requests?(e)
335
+
336
+ # shut down pipeline
337
+ if execution_context&.agent.respond_to?(:stop_pipeline)
338
+ details = { message: e.message, exception: e.class }
339
+ details[:backtrace] = e.backtrace if @logger.debug?
340
+ @logger.error("Failed to bootstrap. Pipeline \"#{execution_context.pipeline_id}\" is going to shut down", details)
341
+
342
+ @shutdown_from_finish_register.make_true
343
+ execution_context.agent.stop_pipeline(execution_context.pipeline_id)
344
+ end
345
+
346
+ e
329
347
  rescue => e
330
- # we do not want to halt the thread with an exception as that has consequences for LS
331
348
  e # thread.value
332
349
  ensure
333
350
  @after_successful_connection_done.make_true
@@ -450,7 +467,11 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
450
467
  private
451
468
 
452
469
  def stop_after_successful_connection_thread
453
- @after_successful_connection_thread.join unless @after_successful_connection_thread.nil?
470
+ # avoid deadlock when finish_register calling execution_context.agent.stop_pipeline
471
+ # stop_pipeline triggers plugin close and the plugin close waits for after_successful_connection_thread to join
472
+ return if @shutdown_from_finish_register&.true?
473
+
474
+ @after_successful_connection_thread.join if @after_successful_connection_thread&.alive?
454
475
  end
455
476
 
456
477
  # Convert the event into a 3-tuple of action, params and event hash
@@ -599,6 +620,7 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
599
620
  details = { message: e.message, exception: e.class, backtrace: e.backtrace }
600
621
  details[:body] = e.response_body if e.respond_to?(:response_body)
601
622
  @logger.error("Failed to install template", details)
623
+ raise e if register_termination_error?(e)
602
624
  end
603
625
 
604
626
  def setup_ecs_compatibility_related_defaults
@@ -149,7 +149,7 @@ module LogStash; module PluginMixins; module ElasticSearch
149
149
 
150
150
  # Defines the list of Elasticsearch errors that you don't want to log.
151
151
  # A useful example is when you want to skip all 409 errors
152
- # which are `document_already_exists_exception`.
152
+ # which are `version_conflict_engine_exception`.
153
153
  # Deprecates `failure_type_logging_whitelist`.
154
154
  :silence_errors_in_log => { :validate => :array, :default => [] },
155
155
 
@@ -407,5 +407,14 @@ module LogStash; module PluginMixins; module ElasticSearch
407
407
  return val if rest_keys.empty? || val == nil
408
408
  dig_value(val, *rest_keys)
409
409
  end
410
+
411
+ def register_termination_error?(e)
412
+ e.is_a?(LogStash::ConfigurationError) || e.is_a?(LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError)
413
+ end
414
+
415
+ def too_many_requests?(e)
416
+ e.is_a?(LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError) &&
417
+ e.too_many_requests?
418
+ end
410
419
  end
411
420
  end; end; end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-elasticsearch'
3
- s.version = '11.19.0'
3
+ s.version = '11.20.1'
4
4
  s.licenses = ['apache-2.0']
5
5
  s.summary = "Stores logs in Elasticsearch"
6
6
  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"
@@ -33,11 +33,11 @@ describe "elasticsearch is down on startup", :integration => true do
33
33
  end
34
34
 
35
35
  it 'should ingest events when Elasticsearch recovers before documents are sent' do
36
- allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_es_version).and_raise(
36
+ allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_root_path).with(any_args).and_raise(
37
37
  ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError.new StandardError.new("TEST: before docs are sent"), 'http://test.es/'
38
38
  )
39
39
  subject.register
40
- allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_es_version).and_return(ESHelper.es_version)
40
+ allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_root_path).with(any_args).and_call_original
41
41
  subject.multi_receive([event1, event2])
42
42
  @es.indices.refresh
43
43
  r = @es.search(index: 'logstash-*')
@@ -45,13 +45,13 @@ describe "elasticsearch is down on startup", :integration => true do
45
45
  end
46
46
 
47
47
  it 'should ingest events when Elasticsearch recovers after documents are sent' do
48
- allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_es_version).and_raise(
48
+ allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_root_path).with(any_args).and_raise(
49
49
  ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError.new StandardError.new("TEST: after docs are sent"), 'http://test.es/'
50
50
  )
51
51
  subject.register
52
52
  Thread.new do
53
53
  sleep 4
54
- allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_es_version).and_return(ESHelper.es_version)
54
+ allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_root_path).with(any_args).and_call_original
55
55
  end
56
56
  subject.multi_receive([event1, event2])
57
57
  @es.indices.refresh
@@ -25,7 +25,7 @@ describe "whitelisting error types in expected behavior" do
25
25
  "create" => {
26
26
  "status" => 409,
27
27
  "error" => {
28
- "type" => "document_already_exists_exception",
28
+ "type" => "version_conflict_engine_exception",
29
29
  "reason" => "[shard] document already exists"
30
30
  }
31
31
  }
@@ -46,7 +46,7 @@ describe "whitelisting error types in expected behavior" do
46
46
  end
47
47
 
48
48
  describe "when failure logging is disabled for document exists error" do
49
- let(:settings) { super().merge("silence_errors_in_log" => ["document_already_exists_exception"]) }
49
+ let(:settings) { super().merge("silence_errors_in_log" => ["version_conflict_engine_exception"]) }
50
50
 
51
51
  it "should log a failure on the action" do
52
52
  expect(subject.logger).not_to have_received(:warn).with("Failed action", anything)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 11.19.0
4
+ version: 11.20.1
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-25 00:00:00.000000000 Z
11
+ date: 2023-11-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement