logstash-output-elasticsearch 11.14.1-java → 11.15.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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ad6b80e4c6db7a54c8b7a830f6a922a7057b2e7585820db8a6c093b57db3800
|
4
|
+
data.tar.gz: 82cd893394fc7ac08ae7a79b2cd953f80fbf258ec2faad225300a2ce516ab208
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b861d195377c3eeadf4489d21780be6627597aa0b93992bd7378b7cf680f6f99ac120ae342a4b48739ee6ef2652aa9238ee9fc08838cbed0f6dae0c887b06daa
|
7
|
+
data.tar.gz: 16091be406132dbb590ad76a0ba2e83cb0729717d8229b410bccbcabc660a7a26146fd2c7aaae6976f954bd17f1f763c6353552699ffd67173efb9917b913658
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 11.15.1
|
2
|
+
- Move async finish_register to bottom of register to avoid race condition [#1125](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1125)
|
3
|
+
|
4
|
+
## 11.15.0
|
5
|
+
- Added the ability to negatively acknowledge the batch under processing if the plugin is blocked in a retry-error-loop and a shutdown is requested. [#1119](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1119)
|
6
|
+
|
1
7
|
## 11.14.1
|
2
8
|
- [DOC] Fixed incorrect pull request link on the CHANGELOG `11.14.0` entry [#1122](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1122)
|
3
9
|
|
@@ -313,6 +313,27 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
313
313
|
data_stream_enabled = data_stream_config?
|
314
314
|
|
315
315
|
setup_template_manager_defaults(data_stream_enabled)
|
316
|
+
# To support BWC, we check if DLQ exists in core (< 5.4). If it doesn't, we use nil to resort to previous behavior.
|
317
|
+
@dlq_writer = dlq_enabled? ? execution_context.dlq_writer : nil
|
318
|
+
|
319
|
+
@dlq_codes = DOC_DLQ_CODES.to_set
|
320
|
+
|
321
|
+
if dlq_enabled?
|
322
|
+
check_dlq_custom_codes
|
323
|
+
@dlq_codes.merge(dlq_custom_codes)
|
324
|
+
else
|
325
|
+
raise LogStash::ConfigurationError, "DLQ feature (dlq_custom_codes) is configured while DLQ is not enabled" unless dlq_custom_codes.empty?
|
326
|
+
end
|
327
|
+
|
328
|
+
setup_mapper_and_target(data_stream_enabled)
|
329
|
+
|
330
|
+
@bulk_request_metrics = metric.namespace(:bulk_requests)
|
331
|
+
@document_level_metrics = metric.namespace(:documents)
|
332
|
+
|
333
|
+
if ecs_compatibility == :v8
|
334
|
+
@logger.warn("Elasticsearch Output configured with `ecs_compatibility => v8`, which resolved to an UNRELEASED preview of version 8.0.0 of the Elastic Common Schema. " +
|
335
|
+
"Once ECS v8 and an updated release of this plugin are publicly available, you will need to update this plugin to resolve this warning.")
|
336
|
+
end
|
316
337
|
|
317
338
|
@after_successful_connection_thread = after_successful_connection do
|
318
339
|
begin
|
@@ -326,18 +347,9 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
326
347
|
end
|
327
348
|
end
|
328
349
|
|
329
|
-
|
330
|
-
@dlq_writer = dlq_enabled? ? execution_context.dlq_writer : nil
|
331
|
-
|
332
|
-
@dlq_codes = DOC_DLQ_CODES.to_set
|
333
|
-
|
334
|
-
if dlq_enabled?
|
335
|
-
check_dlq_custom_codes
|
336
|
-
@dlq_codes.merge(dlq_custom_codes)
|
337
|
-
else
|
338
|
-
raise LogStash::ConfigurationError, "DLQ feature (dlq_custom_codes) is configured while DLQ is not enabled" unless dlq_custom_codes.empty?
|
339
|
-
end
|
350
|
+
end
|
340
351
|
|
352
|
+
def setup_mapper_and_target(data_stream_enabled)
|
341
353
|
if data_stream_enabled
|
342
354
|
@event_mapper = -> (e) { data_stream_event_action_tuple(e) }
|
343
355
|
@event_target = -> (e) { data_stream_name(e) }
|
@@ -346,14 +358,6 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
346
358
|
@event_mapper = -> (e) { event_action_tuple(e) }
|
347
359
|
@event_target = -> (e) { e.sprintf(@index) }
|
348
360
|
end
|
349
|
-
|
350
|
-
@bulk_request_metrics = metric.namespace(:bulk_requests)
|
351
|
-
@document_level_metrics = metric.namespace(:documents)
|
352
|
-
|
353
|
-
if ecs_compatibility == :v8
|
354
|
-
@logger.warn("Elasticsearch Output configured with `ecs_compatibility => v8`, which resolved to an UNRELEASED preview of version 8.0.0 of the Elastic Common Schema. " +
|
355
|
-
"Once ECS v8 and an updated release of this plugin are publicly available, you will need to update this plugin to resolve this warning.")
|
356
|
-
end
|
357
361
|
end
|
358
362
|
|
359
363
|
# @override post-register when ES connection established
|
@@ -431,7 +435,12 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
431
435
|
def wait_for_successful_connection
|
432
436
|
after_successful_connection_done = @after_successful_connection_done
|
433
437
|
return unless after_successful_connection_done
|
434
|
-
stoppable_sleep 1 until after_successful_connection_done.true?
|
438
|
+
stoppable_sleep 1 until (after_successful_connection_done.true? || pipeline_shutdown_requested?)
|
439
|
+
|
440
|
+
if pipeline_shutdown_requested?
|
441
|
+
logger.info "Aborting the batch due to shutdown request while waiting for connections to become live"
|
442
|
+
abort_batch_if_available!
|
443
|
+
end
|
435
444
|
|
436
445
|
status = @after_successful_connection_thread && @after_successful_connection_thread.value
|
437
446
|
if status.is_a?(Exception) # check if thread 'halted' with an error
|
@@ -159,6 +159,8 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
159
159
|
def after_successful_connection(&block)
|
160
160
|
Thread.new do
|
161
161
|
sleep_interval = @retry_initial_interval
|
162
|
+
# in case of a pipeline's shutdown_requested?, the method #close shutdown also this thread
|
163
|
+
# so no need to explicitly handle it here and return an AbortedBatchException.
|
162
164
|
until successful_connection? || @stopping.true?
|
163
165
|
@logger.debug("Waiting for connectivity to Elasticsearch cluster, retrying in #{sleep_interval}s")
|
164
166
|
sleep_interval = sleep_for_interval(sleep_interval)
|
@@ -191,8 +193,14 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
191
193
|
@logger.info("Retrying individual bulk actions that failed or were rejected by the previous bulk request", count: submit_actions.size)
|
192
194
|
end
|
193
195
|
rescue => e
|
194
|
-
|
195
|
-
|
196
|
+
if abort_batch_present? && e.instance_of?(org.logstash.execution.AbortedBatchException)
|
197
|
+
# if Logstash support abort of a batch and the batch is aborting,
|
198
|
+
# bubble up the exception so that the pipeline can handle it
|
199
|
+
raise e
|
200
|
+
else
|
201
|
+
@logger.error("Encountered an unexpected error submitting a bulk request, will retry",
|
202
|
+
message: e.message, exception: e.class, backtrace: e.backtrace)
|
203
|
+
end
|
196
204
|
end
|
197
205
|
|
198
206
|
# Everything was a success!
|
@@ -331,6 +339,11 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
331
339
|
|
332
340
|
sleep_interval = sleep_for_interval(sleep_interval)
|
333
341
|
@bulk_request_metrics.increment(:failures)
|
342
|
+
if pipeline_shutdown_requested?
|
343
|
+
# when any connection is available and a shutdown is requested
|
344
|
+
# the batch can be aborted, eventually for future retry.
|
345
|
+
abort_batch_if_available!
|
346
|
+
end
|
334
347
|
retry unless @stopping.true?
|
335
348
|
rescue ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError => e
|
336
349
|
@bulk_request_metrics.increment(:failures)
|
@@ -349,6 +362,11 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
349
362
|
end
|
350
363
|
|
351
364
|
sleep_interval = sleep_for_interval(sleep_interval)
|
365
|
+
if pipeline_shutdown_requested?
|
366
|
+
# In case ES side changes access credentials and a pipeline reload is triggered
|
367
|
+
# this error becomes a retry on restart
|
368
|
+
abort_batch_if_available!
|
369
|
+
end
|
352
370
|
retry
|
353
371
|
rescue => e # Stuff that should never happen - print out full connection issues
|
354
372
|
@logger.error(
|
@@ -363,6 +381,19 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
363
381
|
end
|
364
382
|
end
|
365
383
|
|
384
|
+
def pipeline_shutdown_requested?
|
385
|
+
return super if defined?(super) # since LS 8.1.0
|
386
|
+
execution_context&.pipeline&.shutdown_requested
|
387
|
+
end
|
388
|
+
|
389
|
+
def abort_batch_if_available!
|
390
|
+
raise org.logstash.execution.AbortedBatchException.new if abort_batch_present?
|
391
|
+
end
|
392
|
+
|
393
|
+
def abort_batch_present?
|
394
|
+
::Gem::Version.create(LOGSTASH_VERSION) >= ::Gem::Version.create('8.8.0')
|
395
|
+
end
|
396
|
+
|
366
397
|
def dlq_enabled?
|
367
398
|
# TODO there should be a better way to query if DLQ is enabled
|
368
399
|
# See more in: https://github.com/elastic/logstash/issues/8064
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'logstash-output-elasticsearch'
|
3
|
-
s.version = '11.
|
3
|
+
s.version = '11.15.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"
|
@@ -50,6 +50,104 @@ describe LogStash::Outputs::ElasticSearch do
|
|
50
50
|
subject.close
|
51
51
|
end
|
52
52
|
|
53
|
+
context "check aborting of a batch" do
|
54
|
+
context "on an unreachable ES instance" do
|
55
|
+
let(:events) { [ ::LogStash::Event.new("foo" => "bar1"), ::LogStash::Event.new("foo" => "bar2") ] }
|
56
|
+
|
57
|
+
let(:shutdown_value) { true }
|
58
|
+
|
59
|
+
let(:logger) { double("logger") }
|
60
|
+
|
61
|
+
before(:each) do
|
62
|
+
allow(subject).to receive(:logger).and_return(logger)
|
63
|
+
allow(logger).to receive(:info)
|
64
|
+
|
65
|
+
allow(subject).to receive(:pipeline_shutdown_requested?) do
|
66
|
+
shutdown_value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "the #multi_receive abort while waiting on unreachable and a shutdown is requested" do
|
71
|
+
expect { subject.multi_receive(events) }.to raise_error(org.logstash.execution.AbortedBatchException)
|
72
|
+
expect(logger).to have_received(:info).with(/Aborting the batch due to shutdown request while waiting for connections to become live/i)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when a connected ES becomes unreachable" do
|
77
|
+
# let(:error) do
|
78
|
+
# ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError.new(
|
79
|
+
# 429, double("url").as_null_object, request_body, double("response body")
|
80
|
+
# )
|
81
|
+
# end
|
82
|
+
|
83
|
+
shared_examples 'raise an abort error' do
|
84
|
+
let(:options) {
|
85
|
+
{
|
86
|
+
"index" => "my-index",
|
87
|
+
"hosts" => ["localhost","localhost:9202"],
|
88
|
+
"path" => "some-path",
|
89
|
+
"manage_template" => false
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
let(:manticore_urls) { subject.client.pool.urls }
|
94
|
+
let(:manticore_url) { manticore_urls.first }
|
95
|
+
|
96
|
+
let(:stub_http_client_pool!) do
|
97
|
+
[:start_resurrectionist, :start_sniffer, :healthcheck!].each do |method|
|
98
|
+
allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(method)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
let(:event) { ::LogStash::Event.new("foo" => "bar") }
|
103
|
+
|
104
|
+
let(:logger) { double("logger").as_null_object }
|
105
|
+
let(:response) { { :errors => [], :items => [] } }
|
106
|
+
|
107
|
+
let(:request_body) { double(:request_body, :bytesize => 1023) }
|
108
|
+
|
109
|
+
before(:each) do
|
110
|
+
bulk_param = [["index", anything, event.to_hash]]
|
111
|
+
|
112
|
+
allow(subject).to receive(:logger).and_return(logger)
|
113
|
+
|
114
|
+
# fail consistently for ever
|
115
|
+
allow(subject.client).to receive(:bulk).with(bulk_param).and_raise(error)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should exit the retry with an abort exception if shutdown is requested" do
|
119
|
+
# execute in another thread because it blocks in a retry loop until the shutdown is triggered
|
120
|
+
th = Thread.new do
|
121
|
+
subject.multi_receive([event])
|
122
|
+
rescue org.logstash.execution.AbortedBatchException => e
|
123
|
+
# return exception's class so that it can be verified when retrieving the thread's value
|
124
|
+
e.class
|
125
|
+
end
|
126
|
+
|
127
|
+
# trigger the shutdown signal
|
128
|
+
allow(subject).to receive(:pipeline_shutdown_requested?) { true }
|
129
|
+
|
130
|
+
expect(th.value).to eq(org.logstash.execution.AbortedBatchException)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "with 429 error" do
|
135
|
+
let(:error) do
|
136
|
+
::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError.new(
|
137
|
+
429, double("url").as_null_object, request_body, double("response body")
|
138
|
+
)
|
139
|
+
end
|
140
|
+
|
141
|
+
it_behaves_like 'raise an abort error'
|
142
|
+
end
|
143
|
+
|
144
|
+
context "with 'no connections' error" do
|
145
|
+
let(:error) { ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::NoConnectionAvailableError.new }
|
146
|
+
|
147
|
+
it_behaves_like 'raise an abort error'
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end if LOGSTASH_VERSION >= '8.8'
|
53
151
|
|
54
152
|
context "with an active instance" do
|
55
153
|
let(:options) {
|
@@ -1358,6 +1456,42 @@ describe LogStash::Outputs::ElasticSearch do
|
|
1358
1456
|
end
|
1359
1457
|
|
1360
1458
|
end
|
1459
|
+
|
1460
|
+
context 'during register/finish_register' do
|
1461
|
+
|
1462
|
+
let(:options) { { 'hosts' => '127.0.0.1:9999', 'data_stream' => 'true' } }
|
1463
|
+
let(:es_version) { '8.7.0' } # DS default on LS 8.x
|
1464
|
+
|
1465
|
+
before do
|
1466
|
+
allow(subject).to receive(:discover_cluster_uuid)
|
1467
|
+
allow(subject).to receive(:maybe_create_rollover_alias)
|
1468
|
+
allow(subject).to receive(:maybe_create_ilm_policy)
|
1469
|
+
allow(subject).to receive(:build_client)
|
1470
|
+
end
|
1471
|
+
|
1472
|
+
# this test could not have been done using latches as the fix to the race
|
1473
|
+
# condition alters the order of the instructions in elasticsearch.rb
|
1474
|
+
#
|
1475
|
+
# the race condition happened when the @index was set to the datastream
|
1476
|
+
# after `ilm_in_use?` is called but before `setup_ilm`
|
1477
|
+
it 'doesn\'t have a race condition leading to resetting back to ILM' do
|
1478
|
+
ilm_in_use = subject.method(:ilm_in_use?)
|
1479
|
+
expect(subject).to receive(:ilm_in_use?) do |params|
|
1480
|
+
ret = ilm_in_use.call
|
1481
|
+
sleep 3
|
1482
|
+
ret
|
1483
|
+
end
|
1484
|
+
setup_mapper_and_target = subject.method(:setup_mapper_and_target)
|
1485
|
+
expect(subject).to receive(:setup_mapper_and_target).once do |params|
|
1486
|
+
sleep 1
|
1487
|
+
setup_mapper_and_target.call(params)
|
1488
|
+
end
|
1489
|
+
subject.register
|
1490
|
+
sleep 6
|
1491
|
+
expect(subject.index).to eq("logs-generic-default")
|
1492
|
+
end
|
1493
|
+
|
1494
|
+
end
|
1361
1495
|
end
|
1362
1496
|
|
1363
1497
|
@private
|
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.
|
4
|
+
version: 11.15.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-
|
11
|
+
date: 2023-04-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -356,7 +356,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
356
356
|
- !ruby/object:Gem::Version
|
357
357
|
version: '0'
|
358
358
|
requirements: []
|
359
|
-
rubygems_version: 3.
|
359
|
+
rubygems_version: 3.2.29
|
360
360
|
signing_key:
|
361
361
|
specification_version: 4
|
362
362
|
summary: Stores logs in Elasticsearch
|