logstash-output-elasticsearch 11.7.0-java → 11.8.0-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 +3 -0
- data/docs/index.asciidoc +14 -0
- data/lib/logstash/outputs/elasticsearch.rb +26 -0
- data/lib/logstash/plugin_mixins/elasticsearch/common.rb +1 -1
- data/logstash-output-elasticsearch.gemspec +1 -1
- data/spec/unit/outputs/elasticsearch_spec.rb +47 -14
- 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: 28dfa1d2a757a4cb14aa7972f13c13f78975a52db0cac8d39425fa6bb34a462c
|
4
|
+
data.tar.gz: 7a9b9e05f59e2d9024f8faf7d6d5faa58aeb123cb77fd4f89b88826787d5d4f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ee227e4dcb1f1af9cb7d1baf11cabb1e4f1a8ab87781494ca71f2d3a9ad57e6635819827c00090f597f79d33d8724f1a2e5e4047f506a0fde144c0dc5d4d71a
|
7
|
+
data.tar.gz: 6ad8e717ade5b09f46cf4bab5d9749c782cf654dd3e69f79010a230237cd251b7fd034b18f42ed09ffb46aa729c8596eae62a3cb41a8b33c36a7c23e7084adcf
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
## 11.8.0
|
2
|
+
- Feature: Adds a new `dlq_custom_codes` option to customize DLQ codes [#1067](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1067)
|
3
|
+
|
1
4
|
## 11.7.0
|
2
5
|
- Feature: deprecates the `failure_type_logging_whitelist` configuration option, renaming it `silence_errors_in_log` [#1068](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1068)
|
3
6
|
|
data/docs/index.asciidoc
CHANGED
@@ -196,6 +196,8 @@ processed at a later time. Often times, the offending field can be removed and
|
|
196
196
|
re-indexed to Elasticsearch. If the DLQ is not enabled, and a mapping error
|
197
197
|
happens, the problem is logged as a warning, and the event is dropped. See
|
198
198
|
<<dead-letter-queues>> for more information about processing events in the DLQ.
|
199
|
+
The list of error codes accepted for DLQ could be customized with <<plugins-{type}s-{plugin}-dlq_custom_codes>>
|
200
|
+
but should be used only in motivated cases.
|
199
201
|
|
200
202
|
[id="plugins-{type}s-{plugin}-ilm"]
|
201
203
|
==== Index Lifecycle Management
|
@@ -317,6 +319,7 @@ This plugin supports the following configuration options plus the
|
|
317
319
|
| <<plugins-{type}s-{plugin}-data_stream_namespace>> |<<string,string>>|No
|
318
320
|
| <<plugins-{type}s-{plugin}-data_stream_sync_fields>> |<<boolean,boolean>>|No
|
319
321
|
| <<plugins-{type}s-{plugin}-data_stream_type>> |<<string,string>>|No
|
322
|
+
| <<plugins-{type}s-{plugin}-dlq_custom_codes>> |<<number,number>>|No
|
320
323
|
| <<plugins-{type}s-{plugin}-doc_as_upsert>> |<<boolean,boolean>>|No
|
321
324
|
| <<plugins-{type}s-{plugin}-document_id>> |<<string,string>>|No
|
322
325
|
| <<plugins-{type}s-{plugin}-document_type>> |<<string,string>>|No
|
@@ -519,6 +522,17 @@ overwritten with a warning.
|
|
519
522
|
The data stream type used to construct the data stream at index time.
|
520
523
|
Currently, only `logs`, `metrics`, `synthetics` and `traces` are supported.
|
521
524
|
|
525
|
+
[id="plugins-{type}s-{plugin}-dlq_custom_codes"]
|
526
|
+
===== `dlq_custom_codes`
|
527
|
+
|
528
|
+
* Value type is <<number,number>>
|
529
|
+
* Default value is `[]`.
|
530
|
+
|
531
|
+
List single-action error codes from Elasticsearch's Bulk API that are considered valid to move the events into the dead letter queue.
|
532
|
+
This list is an addition to the ordinary error codes considered for this feature, 400 and 404.
|
533
|
+
It's considered a configuration error to re-use the same predefined codes for success, DLQ or conflict.
|
534
|
+
The option accepts a list of natural numbers corresponding to HTTP errors codes.
|
535
|
+
|
522
536
|
[id="plugins-{type}s-{plugin}-doc_as_upsert"]
|
523
537
|
===== `doc_as_upsert`
|
524
538
|
|
@@ -9,6 +9,7 @@ require "socket" # for Socket.gethostname
|
|
9
9
|
require "thread" # for safe queueing
|
10
10
|
require "uri" # for escaping user input
|
11
11
|
require "forwardable"
|
12
|
+
require "set"
|
12
13
|
|
13
14
|
# .Compatibility Note
|
14
15
|
# [NOTE]
|
@@ -255,6 +256,11 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
255
256
|
# ILM policy to use, if undefined the default policy will be used.
|
256
257
|
config :ilm_policy, :validate => :string, :default => DEFAULT_POLICY
|
257
258
|
|
259
|
+
# List extra HTTP's error codes that are considered valid to move the events into the dead letter queue.
|
260
|
+
# It's considered a configuration error to re-use the same predefined codes for success, DLQ or conflict.
|
261
|
+
# The option accepts a list of natural numbers corresponding to HTTP errors codes.
|
262
|
+
config :dlq_custom_codes, :validate => :number, :list => true, :default => []
|
263
|
+
|
258
264
|
attr_reader :client
|
259
265
|
attr_reader :default_index
|
260
266
|
attr_reader :default_ilm_rollover_alias
|
@@ -301,6 +307,15 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
301
307
|
# To support BWC, we check if DLQ exists in core (< 5.4). If it doesn't, we use nil to resort to previous behavior.
|
302
308
|
@dlq_writer = dlq_enabled? ? execution_context.dlq_writer : nil
|
303
309
|
|
310
|
+
@dlq_codes = DOC_DLQ_CODES.to_set
|
311
|
+
|
312
|
+
if dlq_enabled?
|
313
|
+
check_dlq_custom_codes
|
314
|
+
@dlq_codes.merge(dlq_custom_codes)
|
315
|
+
else
|
316
|
+
raise LogStash::ConfigurationError, "DLQ feature (dlq_custom_codes) is configured while DLQ is not enabled" unless dlq_custom_codes.empty?
|
317
|
+
end
|
318
|
+
|
304
319
|
if data_stream_config?
|
305
320
|
@event_mapper = -> (e) { data_stream_event_action_tuple(e) }
|
306
321
|
@event_target = -> (e) { data_stream_name(e) }
|
@@ -539,4 +554,15 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
539
554
|
|
540
555
|
raise LogStash::ConfigurationError, "Action '#{@action}' is invalid! Pick one of #{valid_actions} or use a sprintf style statement"
|
541
556
|
end
|
557
|
+
|
558
|
+
def check_dlq_custom_codes
|
559
|
+
intersection = dlq_custom_codes & DOC_DLQ_CODES
|
560
|
+
raise LogStash::ConfigurationError, "#{intersection} are already defined as standard DLQ error codes" unless intersection.empty?
|
561
|
+
|
562
|
+
intersection = dlq_custom_codes & DOC_SUCCESS_CODES
|
563
|
+
raise LogStash::ConfigurationError, "#{intersection} are success codes which cannot be redefined in dlq_custom_codes" unless intersection.empty?
|
564
|
+
|
565
|
+
intersection = dlq_custom_codes & [DOC_CONFLICT_CODE]
|
566
|
+
raise LogStash::ConfigurationError, "#{intersection} are error codes already defined as conflict which cannot be redefined in dlq_custom_codes" unless intersection.empty?
|
567
|
+
end
|
542
568
|
end
|
@@ -268,7 +268,7 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
268
268
|
@document_level_metrics.increment(:non_retryable_failures)
|
269
269
|
@logger.warn "Failed action", status: status, action: action, response: response if log_failure_type?(error)
|
270
270
|
next
|
271
|
-
elsif
|
271
|
+
elsif @dlq_codes.include?(status)
|
272
272
|
handle_dlq_status("Could not index event to Elasticsearch.", action, status, response)
|
273
273
|
@document_level_metrics.increment(:non_retryable_failures)
|
274
274
|
next
|
@@ -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.8.0'
|
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"
|
@@ -260,6 +260,24 @@ describe LogStash::Outputs::ElasticSearch do
|
|
260
260
|
end
|
261
261
|
end
|
262
262
|
|
263
|
+
describe "when 'dlq_custom_codes'" do
|
264
|
+
let(:options) { super().merge('dlq_custom_codes' => [404]) }
|
265
|
+
let(:do_register) { false }
|
266
|
+
|
267
|
+
context "contains already defined codes" do
|
268
|
+
it "should raise a configuration error" do
|
269
|
+
expect{ subject.register }.to raise_error(LogStash::ConfigurationError, /are already defined as standard DLQ error codes/)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context "is configured but DLQ is not enabled" do
|
274
|
+
it "raise a configuration error" do
|
275
|
+
allow(subject).to receive(:dlq_enabled?).and_return(false)
|
276
|
+
expect{ subject.register }.to raise_error(LogStash::ConfigurationError, /configured while DLQ is not enabled/)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end if LOGSTASH_VERSION > '7.0'
|
280
|
+
|
263
281
|
describe "#multi_receive" do
|
264
282
|
let(:events) { [double("one"), double("two"), double("three")] }
|
265
283
|
let(:events_tuples) { [double("one t"), double("two t"), double("three t")] }
|
@@ -807,7 +825,7 @@ describe LogStash::Outputs::ElasticSearch do
|
|
807
825
|
end
|
808
826
|
end
|
809
827
|
|
810
|
-
context 'with response status
|
828
|
+
context 'with error response status' do
|
811
829
|
|
812
830
|
let(:options) { super().merge 'document_id' => '%{foo}' }
|
813
831
|
|
@@ -815,11 +833,13 @@ describe LogStash::Outputs::ElasticSearch do
|
|
815
833
|
|
816
834
|
let(:dlq_writer) { subject.instance_variable_get(:@dlq_writer) }
|
817
835
|
|
836
|
+
let(:error_code) { 400 }
|
837
|
+
|
818
838
|
let(:bulk_response) do
|
819
839
|
{
|
820
840
|
"took"=>1, "ingest_took"=>11, "errors"=>true, "items"=>
|
821
841
|
[{
|
822
|
-
"index"=>{"_index"=>"bar", "_type"=>"_doc", "_id"=>'bar', "status"=>
|
842
|
+
"index"=>{"_index"=>"bar", "_type"=>"_doc", "_id"=>'bar', "status" => error_code,
|
823
843
|
"error"=>{"type" => "illegal_argument_exception", "reason" => "TEST" }
|
824
844
|
}
|
825
845
|
}]
|
@@ -830,21 +850,34 @@ describe LogStash::Outputs::ElasticSearch do
|
|
830
850
|
allow(subject.client).to receive(:bulk_send).and_return(bulk_response)
|
831
851
|
end
|
832
852
|
|
833
|
-
|
834
|
-
|
835
|
-
expect(
|
853
|
+
shared_examples "should write event to DLQ" do
|
854
|
+
it "should write event to DLQ" do
|
855
|
+
expect(dlq_writer).to receive(:write).and_wrap_original do |method, *args|
|
856
|
+
expect( args.size ).to eql 2
|
857
|
+
|
858
|
+
event, reason = *args
|
859
|
+
expect( event ).to be_a LogStash::Event
|
860
|
+
expect( event ).to be events.first
|
861
|
+
expect( reason ).to start_with "Could not index event to Elasticsearch. status: #{error_code}, action: [\"index\""
|
862
|
+
expect( reason ).to match /_id=>"bar".*"foo"=>"bar".*response:.*"reason"=>"TEST"/
|
836
863
|
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
864
|
+
method.call(*args) # won't hurt to call LogStash::Util::DummyDeadLetterQueueWriter
|
865
|
+
end.once
|
866
|
+
|
867
|
+
event_action_tuples = subject.map_events(events)
|
868
|
+
subject.send(:submit, event_action_tuples)
|
869
|
+
end
|
870
|
+
end
|
871
|
+
|
872
|
+
context "is one of the predefined codes" do
|
873
|
+
include_examples "should write event to DLQ"
|
874
|
+
end
|
842
875
|
|
843
|
-
|
844
|
-
|
876
|
+
context "when user customized dlq_custom_codes option" do
|
877
|
+
let(:error_code) { 403 }
|
878
|
+
let(:options) { super().merge 'dlq_custom_codes' => [error_code] }
|
845
879
|
|
846
|
-
|
847
|
-
subject.send(:submit, event_action_tuples)
|
880
|
+
include_examples "should write event to DLQ"
|
848
881
|
end
|
849
882
|
|
850
883
|
end if LOGSTASH_VERSION > '7.0'
|
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.8.0
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|