logstash-output-elasticsearch 11.6.0-java → 11.8.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/docs/index.asciidoc +36 -5
- data/lib/logstash/outputs/elasticsearch.rb +34 -0
- data/lib/logstash/plugin_mixins/elasticsearch/api_configs.rb +6 -2
- data/lib/logstash/plugin_mixins/elasticsearch/common.rb +2 -2
- data/logstash-output-elasticsearch.gemspec +1 -1
- data/spec/unit/outputs/elasticsearch_spec.rb +47 -14
- data/spec/unit/outputs/error_whitelist_spec.rb +2 -2
- 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,9 @@
|
|
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
|
+
|
4
|
+
## 11.7.0
|
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)
|
6
|
+
|
1
7
|
## 11.6.0
|
2
8
|
- Added support for `ca_trusted_fingerprint` when run on Logstash 8.3+ [#1074](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1074)
|
3
9
|
|
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
|
@@ -332,6 +335,7 @@ This plugin supports the following configuration options plus the
|
|
332
335
|
| <<plugins-{type}s-{plugin}-index>> |<<string,string>>|No
|
333
336
|
| <<plugins-{type}s-{plugin}-keystore>> |a valid filesystem path|No
|
334
337
|
| <<plugins-{type}s-{plugin}-keystore_password>> |<<password,password>>|No
|
338
|
+
| <<plugins-{type}s-{plugin}-silence_errors_in_log>> |<<array,array>>|No
|
335
339
|
| <<plugins-{type}s-{plugin}-manage_template>> |<<boolean,boolean>>|No
|
336
340
|
| <<plugins-{type}s-{plugin}-parameters>> |<<hash,hash>>|No
|
337
341
|
| <<plugins-{type}s-{plugin}-parent>> |<<string,string>>|No
|
@@ -518,6 +522,17 @@ overwritten with a warning.
|
|
518
522
|
The data stream type used to construct the data stream at index time.
|
519
523
|
Currently, only `logs`, `metrics`, `synthetics` and `traces` are supported.
|
520
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
|
+
|
521
536
|
[id="plugins-{type}s-{plugin}-doc_as_upsert"]
|
522
537
|
===== `doc_as_upsert`
|
523
538
|
|
@@ -584,9 +599,7 @@ of this setting affects the _default_ values of:
|
|
584
599
|
* Value type is <<array,array>>
|
585
600
|
* Default value is `[]`
|
586
601
|
|
587
|
-
|
588
|
-
A useful example is when you want to skip all 409 errors
|
589
|
-
which are `document_already_exists_exception`.
|
602
|
+
NOTE: Deprecated, refer to <<plugins-{type}s-{plugin}-silence_errors_in_log>>.
|
590
603
|
|
591
604
|
[id="plugins-{type}s-{plugin}-custom_headers"]
|
592
605
|
===== `custom_headers`
|
@@ -743,8 +756,7 @@ Indexes may not contain uppercase characters.
|
|
743
756
|
For weekly indexes ISO 8601 format is recommended, eg. logstash-%{+xxxx.ww}.
|
744
757
|
Logstash uses
|
745
758
|
http://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html[Joda
|
746
|
-
formats]
|
747
|
-
|
759
|
+
formats] and the `@timestamp` field of each event is being used as source for the date.
|
748
760
|
|
749
761
|
[id="plugins-{type}s-{plugin}-keystore"]
|
750
762
|
===== `keystore`
|
@@ -963,6 +975,25 @@ Set variable name passed to script (scripted update)
|
|
963
975
|
|
964
976
|
if enabled, script is in charge of creating non-existent document (scripted update)
|
965
977
|
|
978
|
+
[id="plugins-{type}s-{plugin}-silence_errors_in_log"]
|
979
|
+
===== `silence_errors_in_log`
|
980
|
+
|
981
|
+
* Value type is <<array,array>>
|
982
|
+
* Default value is `[]`
|
983
|
+
|
984
|
+
Defines the list of Elasticsearch errors that you don't want to log.
|
985
|
+
A useful example is when you want to skip all 409 errors
|
986
|
+
which are `document_already_exists_exception`.
|
987
|
+
|
988
|
+
[source,ruby]
|
989
|
+
output {
|
990
|
+
elasticsearch {
|
991
|
+
silence_errors_in_log => ["document_already_exists_exception"]
|
992
|
+
}
|
993
|
+
}
|
994
|
+
|
995
|
+
NOTE: Deprecates <<plugins-{type}s-{plugin}-failure_type_logging_whitelist>>.
|
996
|
+
|
966
997
|
[id="plugins-{type}s-{plugin}-sniffing"]
|
967
998
|
===== `sniffing`
|
968
999
|
|
@@ -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
|
@@ -266,6 +272,14 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
266
272
|
end
|
267
273
|
|
268
274
|
def register
|
275
|
+
if !failure_type_logging_whitelist.empty?
|
276
|
+
log_message = "'failure_type_logging_whitelist' is deprecated and in a future version of Elasticsearch " +
|
277
|
+
"output plugin will be removed, please use 'silence_errors_in_log' instead."
|
278
|
+
@deprecation_logger.deprecated log_message
|
279
|
+
@logger.warn log_message
|
280
|
+
@silence_errors_in_log = silence_errors_in_log | failure_type_logging_whitelist
|
281
|
+
end
|
282
|
+
|
269
283
|
@after_successful_connection_done = Concurrent::AtomicBoolean.new(false)
|
270
284
|
@stopping = Concurrent::AtomicBoolean.new(false)
|
271
285
|
|
@@ -293,6 +307,15 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
293
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.
|
294
308
|
@dlq_writer = dlq_enabled? ? execution_context.dlq_writer : nil
|
295
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
|
+
|
296
319
|
if data_stream_config?
|
297
320
|
@event_mapper = -> (e) { data_stream_event_action_tuple(e) }
|
298
321
|
@event_target = -> (e) { data_stream_name(e) }
|
@@ -531,4 +554,15 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
531
554
|
|
532
555
|
raise LogStash::ConfigurationError, "Action '#{@action}' is invalid! Pick one of #{valid_actions} or use a sprintf style statement"
|
533
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
|
534
568
|
end
|
@@ -99,10 +99,14 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
99
99
|
# a timeout occurs, the request will be retried.
|
100
100
|
:timeout => { :validate => :number, :default => 60 },
|
101
101
|
|
102
|
-
#
|
102
|
+
# Deprecated, refer to `silence_errors_in_log`.
|
103
|
+
:failure_type_logging_whitelist => { :validate => :array, :default => [] },
|
104
|
+
|
105
|
+
# Defines the list of Elasticsearch errors that you don't want to log.
|
103
106
|
# A useful example is when you want to skip all 409 errors
|
104
107
|
# which are `document_already_exists_exception`.
|
105
|
-
|
108
|
+
# Deprecates `failure_type_logging_whitelist`.
|
109
|
+
:silence_errors_in_log => { :validate => :array, :default => [] },
|
106
110
|
|
107
111
|
# While the output tries to reuse connections efficiently we have a maximum.
|
108
112
|
# This sets the maximum number of open connections the output will create.
|
@@ -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
|
@@ -284,7 +284,7 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
284
284
|
end
|
285
285
|
|
286
286
|
def log_failure_type?(failure)
|
287
|
-
!
|
287
|
+
!silence_errors_in_log.include?(failure["type"])
|
288
288
|
end
|
289
289
|
|
290
290
|
# Rescue retryable errors during bulk submission
|
@@ -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'
|
@@ -45,8 +45,8 @@ describe "whitelisting error types in expected behavior" do
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
-
describe "when failure logging is disabled for
|
49
|
-
let(:settings) { super().merge("
|
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"]) }
|
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.
|
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
|