logstash-output-elasticsearch 11.15.0-java → 11.15.2-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 -0
- data/lib/logstash/outputs/elasticsearch.rb +25 -21
- data/lib/logstash/plugin_mixins/elasticsearch/common.rb +7 -13
- data/logstash-output-elasticsearch.gemspec +1 -1
- data/spec/es_spec_helper.rb +12 -7
- data/spec/integration/outputs/templates_spec.rb +3 -1
- data/spec/unit/outputs/elasticsearch_spec.rb +69 -9
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d000a73f7c5397c4e4643c0d1dbb4efb0c04b290054b0d455f020ec3443765d5
|
4
|
+
data.tar.gz: 9330ee2b0e8a903cc966c502fdc321e39fb2ee15b7b2782f2539567743346d71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddcee04fc7e64d4dd77b6c868c34e65e9fff345c7d1d2c37da5752ae612f09ae8147d0686cfdcdee8494c9c6e6c6045a204ddc157db959733c677f719ca958f9
|
7
|
+
data.tar.gz: '032939b34d7fbf6b4107295ea12c80ea651da05b29290154da37e6ff2b04cb123dcc07dee3bdce2ba184f06d2a2d0b4036dac9b3d8099e403bfda836efb4f29e'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 11.15.2
|
2
|
+
- Restores DLQ logging behavior from 11.8.x to include the action-tuple as structured [#1105](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1105)
|
3
|
+
|
4
|
+
## 11.15.1
|
5
|
+
- Move async finish_register to bottom of register to avoid race condition [#1125](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1125)
|
6
|
+
|
1
7
|
## 11.15.0
|
2
8
|
- 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)
|
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
|
@@ -401,7 +405,7 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
401
405
|
|
402
406
|
event_mapping_errors.each do |event_mapping_error|
|
403
407
|
detailed_message = "#{event_mapping_error.message}; event: `#{event_mapping_error.event.to_hash_with_metadata}`"
|
404
|
-
|
408
|
+
@dlq_writer ? @dlq_writer.write(event_mapping_error.event, detailed_message) : @logger.warn(detailed_message)
|
405
409
|
end
|
406
410
|
@document_level_metrics.increment(:non_retryable_failures, event_mapping_errors.size)
|
407
411
|
end
|
@@ -418,7 +422,7 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
418
422
|
successful_events << @event_mapper.call(event)
|
419
423
|
rescue EventMappingError => ie
|
420
424
|
event_mapping_errors << FailedEventMapping.new(event, ie.message)
|
421
|
-
|
425
|
+
end
|
422
426
|
end
|
423
427
|
MapEventsResult.new(successful_events, event_mapping_errors)
|
424
428
|
end
|
@@ -227,22 +227,16 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
227
227
|
end
|
228
228
|
|
229
229
|
def handle_dlq_response(message, action, status, response)
|
230
|
-
|
230
|
+
event, action_params = action.event, [action[0], action[1], action[2]]
|
231
231
|
|
232
|
-
# TODO: Change this to send a map with { :status => status, :action => action } in the future
|
233
|
-
detailed_message = "#{message} status: #{status}, action: #{action_params}, response: #{response}"
|
234
|
-
|
235
|
-
log_level = dig_value(response, 'index', 'error', 'type') == 'invalid_index_name_exception' ? :error : :warn
|
236
|
-
|
237
|
-
handle_dlq_status(action.event, log_level, detailed_message)
|
238
|
-
end
|
239
|
-
|
240
|
-
def handle_dlq_status(event, log_level, message)
|
241
|
-
# To support bwc, we check if DLQ exists. otherwise we log and drop event (previous behavior)
|
242
232
|
if @dlq_writer
|
243
|
-
|
233
|
+
# TODO: Change this to send a map with { :status => status, :action => action } in the future
|
234
|
+
detailed_message = "#{message} status: #{status}, action: #{action_params}, response: #{response}"
|
235
|
+
@dlq_writer.write(event, "#{detailed_message}")
|
244
236
|
else
|
245
|
-
|
237
|
+
log_level = dig_value(response, 'index', 'error', 'type') == 'invalid_index_name_exception' ? :error : :warn
|
238
|
+
|
239
|
+
@logger.public_send(log_level, message, status: status, action: action_params, response: response)
|
246
240
|
end
|
247
241
|
end
|
248
242
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'logstash-output-elasticsearch'
|
3
|
-
s.version = '11.15.
|
3
|
+
s.version = '11.15.2'
|
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"
|
data/spec/es_spec_helper.rb
CHANGED
@@ -67,19 +67,24 @@ module ESHelper
|
|
67
67
|
end
|
68
68
|
|
69
69
|
RSpec::Matchers.define :have_hits do |expected|
|
70
|
+
hits_count_path = ESHelper.es_version_satisfies?(">=7") ? %w(hits total value) : %w(hits total)
|
71
|
+
|
70
72
|
match do |actual|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
73
|
+
@actual_hits_count = actual&.dig(*hits_count_path)
|
74
|
+
values_match? expected, @actual_hits_count
|
75
|
+
end
|
76
|
+
failure_message do |actual|
|
77
|
+
"expected that #{actual} with #{@actual_hits_count || "UNKNOWN" } hits would have #{expected} hits"
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
81
|
RSpec::Matchers.define :have_index_pattern do |expected|
|
80
82
|
match do |actual|
|
81
|
-
|
82
|
-
|
83
|
+
@actual_index_pattterns = Array(actual['index_patterns'].nil? ? actual['template'] : actual['index_patterns'])
|
84
|
+
@actual_index_pattterns.any? { |v| values_match? expected, v }
|
85
|
+
end
|
86
|
+
failure_message do |actual|
|
87
|
+
"expected that #{actual} with index patterns #{@actual_index_pattterns} would have included `#{expected}`"
|
83
88
|
end
|
84
89
|
end
|
85
90
|
|
@@ -23,7 +23,9 @@ describe "index template expected behavior", :integration => true do
|
|
23
23
|
|
24
24
|
elasticsearch_client.indices.delete_template(:name => '*')
|
25
25
|
# This can fail if there are no indexes, ignore failure.
|
26
|
-
elasticsearch_client.indices.delete(:index => '*') rescue
|
26
|
+
elasticsearch_client.indices.delete(:index => '*') rescue puts("DELETE INDICES ERROR: #{$!}")
|
27
|
+
# Since we are pinned to ES client 7.x, we need to delete data streams the hard way...
|
28
|
+
elasticsearch_client.perform_request("DELETE", "/_data_stream/*") rescue puts("DELETE DATA STREAMS ERROR: #{$!}")
|
27
29
|
end
|
28
30
|
|
29
31
|
context 'with ecs_compatibility => disabled' do
|
@@ -1121,41 +1121,63 @@ describe LogStash::Outputs::ElasticSearch do
|
|
1121
1121
|
end if LOGSTASH_VERSION > '6.0'
|
1122
1122
|
|
1123
1123
|
context 'handling elasticsearch document-level status meant for the DLQ' do
|
1124
|
+
let(:es_api_action) { "CUSTOM_ACTION" }
|
1125
|
+
let(:es_api_params) { Hash['_index' => 'MY_INDEX'] }
|
1126
|
+
|
1124
1127
|
let(:options) { { "manage_template" => false, "data_stream" => 'false' } }
|
1125
|
-
let(:action) { LogStash::Outputs::ElasticSearch::EventActionTuple.new(
|
1128
|
+
let(:action) { LogStash::Outputs::ElasticSearch::EventActionTuple.new(es_api_action, es_api_params, LogStash::Event.new("foo" => "bar")) }
|
1129
|
+
|
1130
|
+
let(:logger) { double('logger').as_null_object }
|
1131
|
+
before(:each) { subject.instance_variable_set(:@logger, logger) }
|
1126
1132
|
|
1127
1133
|
context 'when @dlq_writer is nil' do
|
1128
1134
|
before { subject.instance_variable_set '@dlq_writer', nil }
|
1129
|
-
let(:action) { LogStash::Outputs::ElasticSearch::EventActionTuple.new(:action, :params, LogStash::Event.new("foo" => "bar")) }
|
1130
1135
|
|
1131
1136
|
context 'resorting to previous behaviour of logging the error' do
|
1132
1137
|
context 'getting an invalid_index_name_exception' do
|
1133
1138
|
it 'should log at ERROR level' do
|
1134
|
-
|
1139
|
+
# logger = double("logger").as_null_object
|
1140
|
+
# subject.instance_variable_set(:@logger, logger)
|
1141
|
+
|
1135
1142
|
mock_response = { 'index' => { 'error' => { 'type' => 'invalid_index_name_exception' } } }
|
1136
1143
|
subject.handle_dlq_response("Could not index event to Elasticsearch.", action, :some_status, mock_response)
|
1144
|
+
|
1145
|
+
expect(logger).to have_received(:error).with(a_string_including("Could not index event to Elasticsearch"),
|
1146
|
+
a_hash_including(:status => :some_status,
|
1147
|
+
:action => [es_api_action, es_api_params, action.event.to_hash],
|
1148
|
+
:response => mock_response))
|
1137
1149
|
end
|
1138
1150
|
end
|
1139
1151
|
|
1140
1152
|
context 'when getting any other exception' do
|
1141
1153
|
it 'should log at WARN level' do
|
1142
|
-
logger = double("logger").as_null_object
|
1143
|
-
subject.instance_variable_set(:@logger, logger)
|
1144
|
-
|
1154
|
+
# logger = double("logger").as_null_object
|
1155
|
+
# subject.instance_variable_set(:@logger, logger)
|
1156
|
+
|
1145
1157
|
mock_response = { 'index' => { 'error' => { 'type' => 'illegal_argument_exception' } } }
|
1146
1158
|
subject.handle_dlq_response("Could not index event to Elasticsearch.", action, :some_status, mock_response)
|
1159
|
+
|
1160
|
+
expect(logger).to have_received(:warn).with(a_string_including("Could not index event to Elasticsearch"),
|
1161
|
+
a_hash_including(:status => :some_status,
|
1162
|
+
:action => [es_api_action, es_api_params, action.event.to_hash],
|
1163
|
+
:response => mock_response))
|
1147
1164
|
end
|
1148
1165
|
end
|
1149
1166
|
|
1150
1167
|
context 'when the response does not include [error]' do
|
1151
1168
|
it 'should not fail, but just log a warning' do
|
1152
|
-
logger = double("logger").as_null_object
|
1153
|
-
subject.instance_variable_set(:@logger, logger)
|
1154
|
-
|
1169
|
+
# logger = double("logger").as_null_object
|
1170
|
+
# subject.instance_variable_set(:@logger, logger)
|
1171
|
+
|
1155
1172
|
mock_response = { 'index' => {} }
|
1156
1173
|
expect do
|
1157
1174
|
subject.handle_dlq_response("Could not index event to Elasticsearch.", action, :some_status, mock_response)
|
1158
1175
|
end.to_not raise_error
|
1176
|
+
|
1177
|
+
expect(logger).to have_received(:warn).with(a_string_including("Could not index event to Elasticsearch"),
|
1178
|
+
a_hash_including(:status => :some_status,
|
1179
|
+
:action => [es_api_action, es_api_params, action.event.to_hash],
|
1180
|
+
:response => mock_response))
|
1159
1181
|
end
|
1160
1182
|
end
|
1161
1183
|
end
|
@@ -1175,6 +1197,8 @@ describe LogStash::Outputs::ElasticSearch do
|
|
1175
1197
|
mock_response = { 'index' => { 'error' => { 'type' => 'illegal_argument_exception' } } }
|
1176
1198
|
action = LogStash::Outputs::ElasticSearch::EventActionTuple.new(:action, :params, event)
|
1177
1199
|
subject.handle_dlq_response("Could not index event to Elasticsearch.", action, 404, mock_response)
|
1200
|
+
|
1201
|
+
expect(logger).to_not have_received(:warn).with(a_string_including("Could not index event to Elasticsearch"))
|
1178
1202
|
end
|
1179
1203
|
end
|
1180
1204
|
|
@@ -1456,6 +1480,42 @@ describe LogStash::Outputs::ElasticSearch do
|
|
1456
1480
|
end
|
1457
1481
|
|
1458
1482
|
end
|
1483
|
+
|
1484
|
+
context 'during register/finish_register' do
|
1485
|
+
|
1486
|
+
let(:options) { { 'hosts' => '127.0.0.1:9999', 'data_stream' => 'true' } }
|
1487
|
+
let(:es_version) { '8.7.0' } # DS default on LS 8.x
|
1488
|
+
|
1489
|
+
before do
|
1490
|
+
allow(subject).to receive(:discover_cluster_uuid)
|
1491
|
+
allow(subject).to receive(:maybe_create_rollover_alias)
|
1492
|
+
allow(subject).to receive(:maybe_create_ilm_policy)
|
1493
|
+
allow(subject).to receive(:build_client)
|
1494
|
+
end
|
1495
|
+
|
1496
|
+
# this test could not have been done using latches as the fix to the race
|
1497
|
+
# condition alters the order of the instructions in elasticsearch.rb
|
1498
|
+
#
|
1499
|
+
# the race condition happened when the @index was set to the datastream
|
1500
|
+
# after `ilm_in_use?` is called but before `setup_ilm`
|
1501
|
+
it 'doesn\'t have a race condition leading to resetting back to ILM' do
|
1502
|
+
ilm_in_use = subject.method(:ilm_in_use?)
|
1503
|
+
expect(subject).to receive(:ilm_in_use?) do |params|
|
1504
|
+
ret = ilm_in_use.call
|
1505
|
+
sleep 3
|
1506
|
+
ret
|
1507
|
+
end
|
1508
|
+
setup_mapper_and_target = subject.method(:setup_mapper_and_target)
|
1509
|
+
expect(subject).to receive(:setup_mapper_and_target).once do |params|
|
1510
|
+
sleep 1
|
1511
|
+
setup_mapper_and_target.call(params)
|
1512
|
+
end
|
1513
|
+
subject.register
|
1514
|
+
sleep 6
|
1515
|
+
expect(subject.index).to eq("logs-generic-default")
|
1516
|
+
end
|
1517
|
+
|
1518
|
+
end
|
1459
1519
|
end
|
1460
1520
|
|
1461
1521
|
@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.15.
|
4
|
+
version: 11.15.2
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-04-
|
11
|
+
date: 2023-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|