Skip to content

Commit 6ff00f0

Browse files
yaauieMarc Sensenich
andauthored
Add Retries to the Elasticsearch Client (#160)
* Add Retries to the Elasticsearch Client Co-authored-by: Marc Sensenich <[email protected]> * test setup: ensure presence of /etc/protocols Co-authored-by: Marc Sensenich <[email protected]>
1 parent cec6c6b commit 6ff00f0

File tree

7 files changed

+87
-6
lines changed

7 files changed

+87
-6
lines changed

.ci/setup.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# user_agent requires /etc/protocols, which is provided by netbase.
2+
# https://github.com/jruby/jruby/issues/3955
3+
if [ ! -f "/etc/protocols" ]; then
4+
if [ $(command -v apt-get) ]; then
5+
echo "installing netbase with apt-get"
6+
sudo apt-get install -y netbase
7+
else
8+
echo "installing netbase with yum"
9+
sudo yum install -y netbase
10+
fi
11+
fi

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 3.14.0
2+
- Added support for configurable retries with new `retry_on_failure` and `retry_on_status` options [#160](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/160)
3+
14
## 3.13.0
25
- Added support for this plugin identifying itself to Elasticsearch with an SSL/TLS client certificate using a new `keystore` option [#162](https://github.com/logstash-plugins/logstash-filter-elasticsearch/pull/162)
36

docs/index.asciidoc

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ This plugin supports the following configuration options plus the <<plugins-{typ
142142
| <<plugins-{type}s-{plugin}-query>> |<<string,string>>|No
143143
| <<plugins-{type}s-{plugin}-query_template>> |<<string,string>>|No
144144
| <<plugins-{type}s-{plugin}-result_size>> |<<number,number>>|No
145+
| <<plugins-{type}s-{plugin}-retry_on_failure>> |<<number,number>>|No
146+
| <<plugins-{type}s-{plugin}-result_on_status_>> |<<number,number list>>|No
145147
| <<plugins-{type}s-{plugin}-sort>> |<<string,string>>|No
146148
| <<plugins-{type}s-{plugin}-ssl>> |<<boolean,boolean>>|No
147149
| <<plugins-{type}s-{plugin}-keystore>> |a valid filesystem path|No
@@ -330,11 +332,30 @@ the {ref}/query-dsl.html[Elasticsearch query documentation].
330332
[id="plugins-{type}s-{plugin}-result_size"]
331333
===== `result_size`
332334

333-
* Value type is <<number,number>>
334-
* Default value is `1`
335+
* Value type is <<number,number>>
336+
* Default value is `1`
335337

336338
How many results to return
337339

340+
[id="plugins-{type}s-{plugin}-retry_on_failure"]
341+
===== `retry_on_failure`
342+
343+
* Value type is <<number,number>>
344+
* Default value is `0` (retries disabled)
345+
346+
How many times to retry an individual failed request.
347+
348+
When enabled, retry requests that result in connection errors or an HTTP status code included in <<plugins-{type}s-{plugin}-retry_on_status>>
349+
350+
[id="plugins-{type}s-{plugin}-retry_on_status"]
351+
===== `retry_on_status`
352+
353+
* Value type is <<number,number list>>
354+
* Default value is an empty list `[]`
355+
356+
Which HTTP Status codes to consider for retries (in addition to connection errors) when using <<plugins-{type}s-{plugin}-retry_on_failure>>,
357+
358+
338359
[id="plugins-{type}s-{plugin}-sort"]
339360
===== `sort`
340361

lib/logstash/filters/elasticsearch.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ class LogStash::Filters::Elasticsearch < LogStash::Filters::Base
8282
# Tags the event on failure to look up geo information. This can be used in later analysis.
8383
config :tag_on_failure, :validate => :array, :default => ["_elasticsearch_lookup_failure"]
8484

85+
# How many times to retry on failure?
86+
config :retry_on_failure, :validate => :number, :default => 0
87+
88+
# What status codes to retry on?
89+
config :retry_on_status, :validate => :number, :list => true, :default => [500, 502, 503, 504]
90+
8591
# config :ca_trusted_fingerprint, :validate => :sha_256_hex
8692
include LogStash::PluginMixins::CATrustedFingerprintSupport
8793

@@ -215,6 +221,8 @@ def client_options
215221
:proxy => @proxy,
216222
:ssl => @ssl,
217223
:ca_file => @ca_file,
224+
:retry_on_failure => @retry_on_failure,
225+
:retry_on_status => @retry_on_status,
218226
:keystore => @keystore,
219227
:keystore_password => @keystore_password,
220228
:ssl_trust_strategy => trust_strategy_for_ca_trusted_fingerprint

lib/logstash/filters/elasticsearch/client.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,23 @@ def initialize(logger, hosts, options = {})
3434
# set ca_file even if ssl isn't on, since the host can be an https url
3535
ssl_options.update(ssl: true, ca_file: options[:ca_file]) if options[:ca_file]
3636
ssl_options.update(ssl: true, trust_strategy: options[:ssl_trust_strategy]) if options[:ssl_trust_strategy]
37-
3837
if keystore
3938
ssl_options[:keystore] = keystore
4039
logger.debug("Keystore for client certificate", :keystore => keystore)
4140
ssl_options[:keystore_password] = keystore_password.value if keystore_password
4241
end
4342

43+
client_options = {
44+
hosts: hosts,
45+
transport_class: ::Elasticsearch::Transport::Transport::HTTP::Manticore,
46+
transport_options: transport_options,
47+
ssl: ssl_options,
48+
retry_on_failure: options[:retry_on_failure],
49+
retry_on_status: options[:retry_on_status]
50+
}
51+
4452
logger.info("New ElasticSearch filter client", :hosts => hosts)
45-
@client = ::Elasticsearch::Client.new(hosts: hosts, transport_options: transport_options, transport_class: ::Elasticsearch::Transport::Transport::HTTP::Manticore, :ssl => ssl_options)
53+
@client = ::Elasticsearch::Client.new(client_options)
4654
end
4755

4856
def search(params)

logstash-filter-elasticsearch.gemspec

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Gem::Specification.new do |s|
22

33
s.name = 'logstash-filter-elasticsearch'
4-
s.version = '3.13.0'
4+
s.version = '3.14.0'
55
s.licenses = ['Apache License (2.0)']
66
s.summary = "Copies fields from previous log events in Elasticsearch to current events "
77
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"
@@ -29,4 +29,3 @@ Gem::Specification.new do |s|
2929

3030
s.add_development_dependency 'logstash-devutils'
3131
end
32-

spec/filters/elasticsearch_spec.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,15 @@
301301
end
302302
end
303303

304+
context 'with client-level retries' do
305+
let(:config) do
306+
super().merge(
307+
"retry_on_failure" => 3,
308+
"retry_on_status" => [500]
309+
)
310+
end
311+
end
312+
304313
context "if query is on nested field" do
305314
let(:config) do
306315
{
@@ -559,6 +568,28 @@ def wait_receive_request
559568
end
560569
end
561570
end
571+
572+
describe "retry_on_failure" do
573+
let(:config) { super().merge("retry_on_failure" => 3) }
574+
575+
it 'propagates to the client' do
576+
plugin.register
577+
578+
client = plugin.send(:get_client).client
579+
expect( extract_transport(client).options[:retry_on_failure] ).to eq(3)
580+
end
581+
end
582+
583+
describe "retry_on_status" do
584+
let(:config) { super().merge("retry_on_status" => [500, 502, 503, 504]) }
585+
586+
it 'propagates to the client' do
587+
plugin.register
588+
589+
client = plugin.send(:get_client).client
590+
expect( extract_transport(client).options[:retry_on_status] ).to eq([500, 502, 503, 504])
591+
end
592+
end
562593
end
563594

564595
describe "ca_trusted_fingerprint" do

0 commit comments

Comments
 (0)