@@ -60,6 +60,9 @@ class LogStash::Outputs::Http < LogStash::Outputs::Base
60
60
# If encountered as response codes this plugin will retry these requests
61
61
config :retryable_codes , :validate => :number , :list => true , :default => [ 429 , 500 , 502 , 503 , 504 ]
62
62
63
+ # If encountered as response codes, this plugin will write these events to DLQ
64
+ config :dlq_retryable_codes , :validate => :number , :list => true , :default => [ 400 , 403 , 404 , 401 ]
65
+
63
66
# If you would like to consider some non-2xx codes to be successes
64
67
# enumerate them here. Responses returning these codes will be considered successes
65
68
config :ignorable_codes , :validate => :number , :list => true
@@ -97,7 +100,7 @@ def register
97
100
# tokens must be added back by the client on success
98
101
@request_tokens = SizedQueue . new ( @pool_max )
99
102
@pool_max . times { |t | @request_tokens << true }
100
-
103
+ @dlq_writer = dlq_enabled? ? execution_context . dlq_writer : nil
101
104
@requests = Array . new
102
105
103
106
if @content_type . nil?
@@ -154,6 +157,15 @@ def log_error_response(response, url, event)
154
157
)
155
158
end
156
159
160
+ def write_to_dlq ( url , event , response )
161
+ # To support bwc, we check if DLQ exists. otherwise we log and drop event (previous behavior)
162
+ if @dlq_writer
163
+ @dlq_writer . write ( event , "Sending #{ response . code } erred HTTP request to DLQ, url: #{ url } , response: #{ response } " )
164
+ else
165
+ log_error_response ( response , url , event )
166
+ end
167
+ end
168
+
157
169
def send_events ( events )
158
170
successes = java . util . concurrent . atomic . AtomicInteger . new ( 0 )
159
171
failures = java . util . concurrent . atomic . AtomicInteger . new ( 0 )
@@ -242,6 +254,9 @@ def send_event(event, attempt)
242
254
if retryable_response? ( response )
243
255
log_retryable_response ( response )
244
256
return :retry , event , attempt
257
+ elsif dlq_retryable_response? ( response )
258
+ write_to_dlq ( url , event , response )
259
+ return :failure , event , attempt
245
260
else
246
261
log_error_response ( response , url , event )
247
262
return :failure , event , attempt
@@ -287,6 +302,10 @@ def retryable_response?(response)
287
302
@retryable_codes && @retryable_codes . include? ( response . code )
288
303
end
289
304
305
+ def dlq_retryable_response? ( response )
306
+ @dlq_retryable_codes && @dlq_retryable_codes . include? ( response . code )
307
+ end
308
+
290
309
def retryable_exception? ( exception )
291
310
RETRYABLE_MANTICORE_EXCEPTIONS . any? { |me | exception . is_a? ( me ) }
292
311
end
@@ -379,4 +398,11 @@ def validate_format!
379
398
end
380
399
end
381
400
end
401
+
402
+ def dlq_enabled?
403
+ # this is the only way to determine if current logstash is supporting a dlq and dlq is also enabled
404
+ # Reference: https://github.com/elastic/logstash/issues/8064
405
+ respond_to? ( :execution_context ) && execution_context . respond_to? ( :dlq_writer ) &&
406
+ !execution_context . dlq_writer . inner_writer . is_a? ( ::LogStash ::Util ::DummyDeadLetterQueueWriter )
407
+ end
382
408
end
0 commit comments