logstash-output-elasticsearch 9.1.2-java → 9.1.3-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 123fca22f700bc5760a15f5beaa40ecae654e6e9b39fa19a3d8662d04963ab3c
4
- data.tar.gz: 495fa3272f872a14cd6b4361017f4cbba5d846cdad47e99321cf06ac2ce66b70
3
+ metadata.gz: c039da495adec68b5bb57018b408430dede45c5389744d0d8b043d6210a60d08
4
+ data.tar.gz: e2a28d5dee5519a151fd501d61f41b1bf182dcd2f262a0b2588b6be7272c2067
5
5
  SHA512:
6
- metadata.gz: ae33f09690b8e90cb679a18b655f9349d6d6204bb9932d6c0ecde987c5871fbd16d60c65e66e52a5d38427a22099611bc5df4ac8ee529c98f6618e5e47a8ea5b
7
- data.tar.gz: f2cbe7d567b6f46a3d396b2316db05499209e769415760ddda080f60366ed1e69bcd7ed64d3084742394186b9ff79650d7db7c95fab9aa3715bc074b7a2ed18e
6
+ metadata.gz: 4fa67d4e34cbf2d0c7de02cece71c2ea1e938a820a839878d9d07535590da657b71069312d843ef37e6e444f24149d165f61189abff7f0d4d59e1e0273d06cde
7
+ data.tar.gz: 908fed926ba7ccdecbd77f6e1493a811214824756e396f287ca9e82b5dd280c60b79c51299c4963bf0e1168561404a3d567a63f5f930915658a062e914289cc1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 9.1.3
2
+ - Improve plugin behavior when Elasticsearch is down on startup #758
3
+
1
4
  ## 9.1.2
2
5
  - No user facing changes, removed unnecessary test dep.
3
6
 
@@ -233,6 +233,7 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
233
233
 
234
234
  def close
235
235
  @stopping.make_true
236
+ stop_template_installer
236
237
  @client.close if @client
237
238
  end
238
239
 
@@ -16,26 +16,48 @@ module LogStash; module Outputs; class ElasticSearch;
16
16
  VERSION_TYPES_PERMITTING_CONFLICT = ["external", "external_gt", "external_gte"]
17
17
 
18
18
  def register
19
+ @template_installed = Concurrent::AtomicBoolean.new(false)
19
20
  @stopping = Concurrent::AtomicBoolean.new(false)
20
21
  # To support BWC, we check if DLQ exists in core (< 5.4). If it doesn't, we use nil to resort to previous behavior.
21
22
  @dlq_writer = dlq_enabled? ? execution_context.dlq_writer : nil
22
23
 
23
24
  setup_hosts # properly sets @hosts
24
25
  build_client
25
-
26
- install_template
27
26
  check_action_validity
28
27
  @bulk_request_metrics = metric.namespace(:bulk_requests)
29
28
  @document_level_metrics = metric.namespace(:documents)
30
-
29
+ install_template_after_successful_connection
31
30
  @logger.info("New Elasticsearch output", :class => self.class.name, :hosts => @hosts.map(&:sanitized).map(&:to_s))
32
31
  end
33
32
 
34
33
  # Receive an array of events and immediately attempt to index them (no buffering)
35
34
  def multi_receive(events)
35
+ until @template_installed.true?
36
+ sleep 1
37
+ end
36
38
  retrying_submit(events.map {|e| event_action_tuple(e)})
37
39
  end
38
40
 
41
+ def install_template_after_successful_connection
42
+ @template_installer ||= Thread.new do
43
+ sleep_interval = @retry_initial_interval
44
+ until successful_connection? || @stopping.true?
45
+ @logger.debug("Waiting for connectivity to Elasticsearch cluster. Retrying in #{sleep_interval}s")
46
+ Stud.stoppable_sleep(sleep_interval) { @stopping.true? }
47
+ sleep_interval = next_sleep_interval(sleep_interval)
48
+ end
49
+ install_template if successful_connection?
50
+ end
51
+ end
52
+
53
+ def stop_template_installer
54
+ @template_installer.join unless @template_installer.nil?
55
+ end
56
+
57
+ def successful_connection?
58
+ !!maximum_seen_major_version
59
+ end
60
+
39
61
  # Convert the event into a 3-tuple of action, params, and event
40
62
  def event_action_tuple(event)
41
63
 
@@ -94,6 +116,7 @@ module LogStash; module Outputs; class ElasticSearch;
94
116
 
95
117
  def install_template
96
118
  TemplateManager.install_template(self)
119
+ @template_installed.make_true
97
120
  end
98
121
 
99
122
  def check_action_validity
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-elasticsearch'
3
- s.version = '9.1.2'
3
+ s.version = '9.1.3'
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"
@@ -11,6 +11,10 @@ module ESHelper
11
11
  Elasticsearch::Client.new(:hosts => [get_host_port])
12
12
  end
13
13
 
14
+ def self.es_version
15
+ RSpec.configuration.filter[:es_version] || ENV['ES_VERSION']
16
+ end
17
+
14
18
  def self.es_version_satisfies?(*requirement)
15
19
  es_version = RSpec.configuration.filter[:es_version] || ENV['ES_VERSION']
16
20
  es_release_version = Gem::Version.new(es_version).release
@@ -60,6 +60,7 @@ if ESHelper.es_version_satisfies?(">= 5")
60
60
  end
61
61
 
62
62
  it "sets the correct content-encoding header and body is compressed" do
63
+ allow(subject.client.pool.adapter.client).to receive(:send).with(anything, /_template/, anything).and_call_original
63
64
  expect(subject.client.pool.adapter.client).to receive(:send).
64
65
  with(anything, anything, {:headers=>{"Content-Encoding"=>"gzip", "Content-Type"=>"application/json"}, :body => a_valid_gzip_encoded_string}).
65
66
  and_call_original
@@ -99,9 +99,10 @@ describe "indexing" do
99
99
  :eager => true
100
100
  }}
101
101
  end
102
-
102
+ # Allow template to be checked for existence/installed
103
+ allow(subject.client.pool.adapter.client).to receive(:send).with(anything, /_template/, anything).and_call_original
103
104
  expect(subject.client.pool.adapter.client).to receive(:send).
104
- with(anything, anything, expected_manticore_opts).
105
+ with(anything, anything, expected_manticore_opts).at_least(:once).
105
106
  and_call_original
106
107
  subject.multi_receive(events)
107
108
  end
@@ -128,7 +129,7 @@ describe "indexing" do
128
129
  it_behaves_like("an indexer")
129
130
  end
130
131
 
131
- describe "a secured indexer", :secure_integration => true do
132
+ describe "a secured indexer", :elasticsearch_secure => true do
132
133
  let(:user) { "simpleuser" }
133
134
  let(:password) { "abc123" }
134
135
  let(:cacert) { "spec/fixtures/test_certs/test.crt" }
@@ -0,0 +1,58 @@
1
+ require "logstash/outputs/elasticsearch"
2
+ require_relative "../../../spec/es_spec_helper"
3
+
4
+ describe "elasticsearch is down on startup", :integration => true do
5
+ let(:event1) { LogStash::Event.new("somevalue" => 100, "@timestamp" => "2014-11-17T20:37:17.223Z", "@metadata" => {"retry_count" => 0}) }
6
+ let(:event2) { LogStash::Event.new("message" => "a") }
7
+
8
+ subject {
9
+ LogStash::Outputs::ElasticSearch.new({
10
+ "manage_template" => true,
11
+ "index" => "logstash-2014.11.17",
12
+ "template_overwrite" => true,
13
+ "hosts" => get_host_port(),
14
+ "retry_max_interval" => 64,
15
+ "retry_initial_interval" => 2
16
+ })
17
+ }
18
+
19
+ before :each do
20
+ # Delete all templates first.
21
+ require "elasticsearch"
22
+ allow(Stud).to receive(:stoppable_sleep)
23
+
24
+ # Clean ES of data before we start.
25
+ @es = get_client
26
+ @es.indices.delete_template(:name => "*")
27
+ @es.indices.delete(:index => "*")
28
+ @es.indices.refresh
29
+ end
30
+
31
+ after :each do
32
+ subject.close
33
+ end
34
+
35
+ it 'should ingest events when Elasticsearch recovers before documents are sent' do
36
+ allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_es_version).and_raise(::LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError.new(StandardError.new, "big fail"))
37
+ subject.register
38
+ allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_es_version).and_return(ESHelper.es_version)
39
+ subject.multi_receive([event1, event2])
40
+ @es.indices.refresh
41
+ r = @es.search
42
+ expect(r["hits"]["total"]).to eql(2)
43
+ end
44
+
45
+ it 'should ingest events when Elasticsearch recovers after documents are sent' do
46
+ allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_es_version).and_raise(::LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError.new(StandardError.new, "big fail"))
47
+ subject.register
48
+ Thread.new do
49
+ sleep 4
50
+ allow_any_instance_of(LogStash::Outputs::ElasticSearch::HttpClient::Pool).to receive(:get_es_version).and_return(ESHelper.es_version)
51
+ end
52
+ subject.multi_receive([event1, event2])
53
+ @es.indices.refresh
54
+ r = @es.search
55
+ expect(r["hits"]["total"]).to eql(2)
56
+ end
57
+
58
+ end
@@ -86,7 +86,7 @@ describe LogStash::Outputs::ElasticSearch::HttpClient do
86
86
 
87
87
  context "with the path option set" do
88
88
  let(:base_options) { super.merge(:client_settings => {:path => "/otherpath"}) }
89
-
89
+
90
90
  it "should not allow paths in two places" do
91
91
  expect {
92
92
  subject.host_to_url(url)
@@ -18,6 +18,10 @@ describe "Proxy option" do
18
18
  subject.register
19
19
  end
20
20
 
21
+ after do
22
+ subject.close
23
+ end
24
+
21
25
  context "when specified as a URI" do
22
26
  shared_examples("hash conversion") do |hash|
23
27
  let(:settings) { super.merge("proxy" => proxy)}
@@ -314,6 +314,7 @@ describe LogStash::Outputs::ElasticSearch do
314
314
  end
315
315
 
316
316
  describe "SSL end to end" do
317
+ let(:do_register) { false } # skip the register in the global before block, as is called here.
317
318
  let(:manticore_double) do
318
319
  double("manticoreX#{self.inspect}")
319
320
  end
@@ -409,6 +410,10 @@ describe LogStash::Outputs::ElasticSearch do
409
410
  allow(::Manticore::Client).to receive(:new).with(any_args).and_call_original
410
411
  end
411
412
 
413
+ after :each do
414
+ subject.close
415
+ end
416
+
412
417
  it "should set the correct http client option for 'validate_after_inactivity'" do
413
418
  subject.register
414
419
  expect(::Manticore::Client).to have_received(:new) do |options|
@@ -457,7 +462,7 @@ describe LogStash::Outputs::ElasticSearch do
457
462
  end
458
463
  end
459
464
 
460
- context "with explicity query parameters" do
465
+ context "with explicit query parameters" do
461
466
  let(:options) {
462
467
  {
463
468
  "hosts" => ["http://localhost:9202/path"],
@@ -470,7 +475,7 @@ describe LogStash::Outputs::ElasticSearch do
470
475
  end
471
476
  end
472
477
 
473
- context "with explicity query parameters and existing url parameters" do
478
+ context "with explicit query parameters and existing url parameters" do
474
479
  let(:existing_query_string) { "existing=param" }
475
480
  let(:options) {
476
481
  {
@@ -58,6 +58,7 @@ describe "SSL option" do
58
58
 
59
59
  after :each do
60
60
  File.delete(keystore_path)
61
+ subject.close
61
62
  end
62
63
 
63
64
  subject do
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: 9.1.2
4
+ version: 9.1.3
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-01 00:00:00.000000000 Z
11
+ date: 2018-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -191,6 +191,7 @@ files:
191
191
  - spec/integration/outputs/index_version_spec.rb
192
192
  - spec/integration/outputs/ingest_pipeline_spec.rb
193
193
  - spec/integration/outputs/metrics_spec.rb
194
+ - spec/integration/outputs/no_es_on_startup_spec.rb
194
195
  - spec/integration/outputs/painless_update_spec.rb
195
196
  - spec/integration/outputs/parent_spec.rb
196
197
  - spec/integration/outputs/retry_spec.rb
@@ -258,6 +259,7 @@ test_files:
258
259
  - spec/integration/outputs/index_version_spec.rb
259
260
  - spec/integration/outputs/ingest_pipeline_spec.rb
260
261
  - spec/integration/outputs/metrics_spec.rb
262
+ - spec/integration/outputs/no_es_on_startup_spec.rb
261
263
  - spec/integration/outputs/painless_update_spec.rb
262
264
  - spec/integration/outputs/parent_spec.rb
263
265
  - spec/integration/outputs/retry_spec.rb