Skip to content

Commit 8427d29

Browse files
committed
WIP: Refactor BadResponseCodeError error handling
Instead of trying to handle this at the manticore adapter layer, let callers decide how to handle exit codes and raise or generate errors. This will allow us to DLQ 413 errors and not retry and hanlde 404 for template API interaction without having to rely on catching generic errors.
1 parent a6f09c6 commit 8427d29

File tree

4 files changed

+33
-40
lines changed

4 files changed

+33
-40
lines changed

Diff for: lib/logstash/outputs/elasticsearch/http_client.rb

+22-23
Original file line numberDiff line numberDiff line change
@@ -181,22 +181,15 @@ def join_bulk_responses(bulk_responses)
181181

182182
def bulk_send(body_stream, batch_actions)
183183
params = compression_level? ? {:headers => {"Content-Encoding" => "gzip"}} : {}
184-
185184
response = @pool.post(@bulk_path, params, body_stream.string)
186-
187185
@bulk_response_metrics.increment(response.code.to_s)
188186

189-
case response.code
190-
when 200 # OK
187+
if response.code == 200
191188
LogStash::Json.load(response.body)
192-
when 413 # Payload Too Large
193-
logger.warn("Bulk request rejected: `413 Payload Too Large`", :action_count => batch_actions.size, :content_length => body_stream.size)
194-
emulate_batch_error_response(batch_actions, response.code, 'payload_too_large')
195189
else
190+
logger.warn("Bulk request rejected: `413 Payload Too Large`", :action_count => batch_actions.size, :content_length => body_stream.size) if response.code == 413
196191
url = ::LogStash::Util::SafeURI.new(response.final_url)
197-
raise ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError.new(
198-
response.code, url, body_stream.to_s, response.body
199-
)
192+
raise ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError.new(response.code, url, body_stream.to_s, response.body)
200193
end
201194
end
202195

@@ -414,13 +407,21 @@ def exists?(path, use_get=false)
414407
end
415408

416409
def template_exists?(template_endpoint, name)
417-
exists?("/#{template_endpoint}/#{name}")
410+
response = @pool.get("/#{template_endpoint}/#{name}")
411+
return true if response.code >= 200 && response.code <= 299
412+
return false if response.code == 404
413+
url = ::LogStash::Util::SafeURI.new(response.final_url)
414+
raise BadResponseCodeError.new(response.code, url, nil, response.body)
418415
end
419416

420417
def template_put(template_endpoint, name, template)
421-
path = "#{template_endpoint}/#{name}"
422418
logger.info("Installing Elasticsearch template", name: name)
423-
@pool.put(path, nil, LogStash::Json.dump(template))
419+
path = "#{template_endpoint}/#{name}"
420+
response = @pool.put(path, nil, LogStash::Json.dump(template))
421+
if response.code < 200 || response.code > 299
422+
url = ::LogStash::Util::SafeURI.new(response.final_url)
423+
raise BadResponseCodeError.new(response.code, url, template, response.body)
424+
end
424425
end
425426

426427
# ILM methods
@@ -432,16 +433,14 @@ def rollover_alias_exists?(name)
432433

433434
# Create a new rollover alias
434435
def rollover_alias_put(alias_name, alias_definition)
435-
begin
436-
@pool.put(CGI::escape(alias_name), nil, LogStash::Json.dump(alias_definition))
437-
logger.info("Created rollover alias", name: alias_name)
438-
# If the rollover alias already exists, ignore the error that comes back from Elasticsearch
439-
rescue ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError => e
440-
if e.response_code == 400
441-
logger.info("Rollover alias already exists, skipping", name: alias_name)
442-
return
443-
end
444-
raise e
436+
response = @pool.put(CGI::escape(alias_name), nil, LogStash::Json.dump(alias_definition))
437+
if response.code == 400
438+
logger.info("Rollover alias already exists, skipping", name: alias_name)
439+
return
440+
end
441+
unless rresponse.code >= 200 && response.code <= 299
442+
url = ::LogStash::Util::SafeURI.new(response.final_url)
443+
raise BadResponseCodeError.new(response.code, url, alias_definition, response.body)
445444
end
446445
end
447446

Diff for: lib/logstash/outputs/elasticsearch/http_client/manticore_adapter.rb

-9
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,6 @@ def perform_request(url, method, path, params={}, body=nil)
7676
raise ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError.new(e, request_uri_as_string)
7777
end
7878

79-
# 404s are excluded because they are valid codes in the case of
80-
# template installation. 413s are excluded to allow the bulk_send
81-
# error handling to process "Payload Too Large" responses rather
82-
# than triggering retries.
83-
code = resp.code
84-
if code < 200 || (code > 299 && ![404, 413].include?(code))
85-
raise ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError.new(code, request_uri, body, resp.body)
86-
end
87-
8879
resp
8980
end
9081

Diff for: lib/logstash/outputs/elasticsearch/http_client/pool.rb

+5-6
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,12 @@ def get_license(url)
253253
def health_check_request(url)
254254
logger.debug("Running health check to see if an Elasticsearch connection is working",
255255
:healthcheck_url => url.sanitized.to_s, :path => @healthcheck_path)
256-
begin
257-
response = perform_request_to_url(url, :head, @healthcheck_path)
258-
return response, nil
259-
rescue ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError => e
260-
logger.warn("Health check failed", code: e.response_code, url: e.url, message: e.message)
261-
return nil, e
256+
response = perform_request_to_url(url, :head, @healthcheck_path)
257+
if response.code < 200 || response.code > 299
258+
logger.warn("Health check failed", code: response.code, url: url.sanitized.to_s)
259+
return nil, BadResponseCodeError.new(response.code, url, nil, response.body)
262260
end
261+
return response, nil
263262
end
264263

265264
def healthcheck!(register_phase = true)

Diff for: lib/logstash/plugin_mixins/elasticsearch/common.rb

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ module Common
77

88
attr_reader :hosts
99

10-
# These codes apply to documents, not at the request level
11-
DOC_DLQ_CODES = [400, 404]
10+
# These codes apply to documents, not at the request level. While the 413 error technically is at the request level
11+
# it should be treated like an error at the document level. Specifically when the payload is too large it is wholesale
12+
# not accepted by ES, in this case it is dumped to DLQ and not retried. Note that this applies to batches or a single message,
13+
# if the batch size results in a 413 due to exceeding ES limit *all* events in the batch are rejected, regardless of whether
14+
# the individual parts that were rejected would have been accepted.
15+
DOC_DLQ_CODES = [400, 404, 413]
1216
DOC_SUCCESS_CODES = [200, 201]
1317
DOC_CONFLICT_CODE = 409
1418

0 commit comments

Comments
 (0)