logstash-output-elasticsearch 10.8.2-java → 11.0.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/docs/index.asciidoc +134 -23
- data/lib/logstash/outputs/elasticsearch.rb +137 -63
- data/lib/logstash/outputs/elasticsearch/data_stream_support.rb +233 -0
- data/lib/logstash/outputs/elasticsearch/http_client.rb +59 -21
- data/lib/logstash/outputs/elasticsearch/http_client/pool.rb +47 -34
- data/lib/logstash/outputs/elasticsearch/ilm.rb +11 -12
- data/lib/logstash/outputs/elasticsearch/license_checker.rb +19 -22
- data/lib/logstash/outputs/elasticsearch/template_manager.rb +3 -5
- data/lib/logstash/plugin_mixins/elasticsearch/api_configs.rb +157 -153
- data/lib/logstash/plugin_mixins/elasticsearch/common.rb +81 -60
- data/logstash-output-elasticsearch.gemspec +2 -2
- data/spec/es_spec_helper.rb +3 -6
- data/spec/integration/outputs/data_stream_spec.rb +61 -0
- data/spec/integration/outputs/ilm_spec.rb +22 -18
- data/spec/integration/outputs/ingest_pipeline_spec.rb +4 -2
- data/spec/integration/outputs/retry_spec.rb +14 -2
- data/spec/integration/outputs/sniffer_spec.rb +0 -1
- data/spec/spec_helper.rb +14 -0
- data/spec/unit/http_client_builder_spec.rb +9 -9
- data/spec/unit/outputs/elasticsearch/data_stream_support_spec.rb +542 -0
- data/spec/unit/outputs/elasticsearch/http_client/manticore_adapter_spec.rb +1 -0
- data/spec/unit/outputs/elasticsearch/http_client/pool_spec.rb +27 -13
- data/spec/unit/outputs/elasticsearch/http_client_spec.rb +59 -41
- data/spec/unit/outputs/elasticsearch/template_manager_spec.rb +1 -3
- data/spec/unit/outputs/elasticsearch_proxy_spec.rb +4 -5
- data/spec/unit/outputs/elasticsearch_spec.rb +280 -47
- data/spec/unit/outputs/elasticsearch_ssl_spec.rb +1 -2
- data/spec/unit/outputs/error_whitelist_spec.rb +4 -3
- data/spec/unit/outputs/license_check_spec.rb +0 -16
- metadata +23 -16
@@ -5,7 +5,7 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
5
5
|
|
6
6
|
# This module defines common methods that can be reused by alternate elasticsearch output plugins such as the elasticsearch_data_streams output.
|
7
7
|
|
8
|
-
attr_reader :
|
8
|
+
attr_reader :hosts
|
9
9
|
|
10
10
|
# These codes apply to documents, not at the request level
|
11
11
|
DOC_DLQ_CODES = [400, 404]
|
@@ -31,7 +31,7 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
31
31
|
if @proxy.eql?('')
|
32
32
|
@logger.warn "Supplied proxy setting (proxy => '') has no effect"
|
33
33
|
end
|
34
|
-
|
34
|
+
::LogStash::Outputs::ElasticSearch::HttpClientBuilder.build(@logger, @hosts, params)
|
35
35
|
end
|
36
36
|
|
37
37
|
def validate_authentication
|
@@ -115,6 +115,15 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
115
115
|
end
|
116
116
|
private :parse_user_password_from_cloud_auth
|
117
117
|
|
118
|
+
# Plugin initialization extension point (after a successful ES connection).
|
119
|
+
def finish_register
|
120
|
+
end
|
121
|
+
protected :finish_register
|
122
|
+
|
123
|
+
def last_es_version
|
124
|
+
client.last_es_version
|
125
|
+
end
|
126
|
+
|
118
127
|
def maximum_seen_major_version
|
119
128
|
client.maximum_seen_major_version
|
120
129
|
end
|
@@ -126,25 +135,24 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
126
135
|
# launch a thread that waits for an initial successful connection to the ES cluster to call the given block
|
127
136
|
# @param block [Proc] the block to execute upon initial successful connection
|
128
137
|
# @return [Thread] the successful connection wait thread
|
129
|
-
def
|
138
|
+
def after_successful_connection(&block)
|
130
139
|
Thread.new do
|
131
140
|
sleep_interval = @retry_initial_interval
|
132
141
|
until successful_connection? || @stopping.true?
|
133
|
-
@logger.debug("Waiting for connectivity to Elasticsearch cluster
|
134
|
-
|
135
|
-
sleep_interval = next_sleep_interval(sleep_interval)
|
142
|
+
@logger.debug("Waiting for connectivity to Elasticsearch cluster, retrying in #{sleep_interval}s")
|
143
|
+
sleep_interval = sleep_for_interval(sleep_interval)
|
136
144
|
end
|
137
145
|
block.call if successful_connection?
|
138
146
|
end
|
139
147
|
end
|
148
|
+
private :after_successful_connection
|
140
149
|
|
141
150
|
def discover_cluster_uuid
|
142
151
|
return unless defined?(plugin_metadata)
|
143
152
|
cluster_info = client.get('/')
|
144
153
|
plugin_metadata.set(:cluster_uuid, cluster_info['cluster_uuid'])
|
145
154
|
rescue => e
|
146
|
-
|
147
|
-
# @logger.error("Unable to retrieve elasticsearch cluster uuid", error => e.message)
|
155
|
+
@logger.error("Unable to retrieve Elasticsearch cluster uuid", message: e.message, exception: e.class, backtrace: e.backtrace)
|
148
156
|
end
|
149
157
|
|
150
158
|
def retrying_submit(actions)
|
@@ -159,13 +167,11 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
159
167
|
begin
|
160
168
|
submit_actions = submit(submit_actions)
|
161
169
|
if submit_actions && submit_actions.size > 0
|
162
|
-
@logger.info("Retrying individual bulk actions that failed or were rejected by the previous bulk request
|
170
|
+
@logger.info("Retrying individual bulk actions that failed or were rejected by the previous bulk request", count: submit_actions.size)
|
163
171
|
end
|
164
172
|
rescue => e
|
165
|
-
@logger.error("Encountered an unexpected error submitting a bulk request
|
166
|
-
|
167
|
-
:class => e.class.name,
|
168
|
-
:backtrace => e.backtrace)
|
173
|
+
@logger.error("Encountered an unexpected error submitting a bulk request, will retry",
|
174
|
+
message: e.message, exception: e.class, backtrace: e.backtrace)
|
169
175
|
end
|
170
176
|
|
171
177
|
# Everything was a success!
|
@@ -173,21 +179,42 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
173
179
|
|
174
180
|
# If we're retrying the action sleep for the recommended interval
|
175
181
|
# Double the interval for the next time through to achieve exponential backoff
|
176
|
-
|
177
|
-
sleep_interval = next_sleep_interval(sleep_interval)
|
182
|
+
sleep_interval = sleep_for_interval(sleep_interval)
|
178
183
|
end
|
179
184
|
end
|
180
185
|
|
181
186
|
def sleep_for_interval(sleep_interval)
|
182
|
-
|
187
|
+
stoppable_sleep(sleep_interval)
|
183
188
|
next_sleep_interval(sleep_interval)
|
184
189
|
end
|
185
190
|
|
191
|
+
def stoppable_sleep(interval)
|
192
|
+
Stud.stoppable_sleep(interval) { @stopping.true? }
|
193
|
+
end
|
194
|
+
|
186
195
|
def next_sleep_interval(current_interval)
|
187
196
|
doubled = current_interval * 2
|
188
197
|
doubled > @retry_max_interval ? @retry_max_interval : doubled
|
189
198
|
end
|
190
199
|
|
200
|
+
def handle_dlq_status(message, action, status, response)
|
201
|
+
# To support bwc, we check if DLQ exists. otherwise we log and drop event (previous behavior)
|
202
|
+
if @dlq_writer
|
203
|
+
event, action = action.event, [action[0], action[1], action[2]]
|
204
|
+
# TODO: Change this to send a map with { :status => status, :action => action } in the future
|
205
|
+
@dlq_writer.write(event, "#{message} status: #{status}, action: #{action}, response: #{response}")
|
206
|
+
else
|
207
|
+
if dig_value(response, 'index', 'error', 'type') == 'invalid_index_name_exception'
|
208
|
+
level = :error
|
209
|
+
else
|
210
|
+
level = :warn
|
211
|
+
end
|
212
|
+
@logger.send level, message, status: status, action: action, response: response
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
private
|
217
|
+
|
191
218
|
def submit(actions)
|
192
219
|
bulk_response = safe_bulk(actions)
|
193
220
|
|
@@ -204,12 +231,20 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
204
231
|
return
|
205
232
|
end
|
206
233
|
|
234
|
+
responses = bulk_response["items"]
|
235
|
+
if responses.size != actions.size # can not map action -> response reliably
|
236
|
+
# an ES bug (on 7.10.2, 7.11.1) where a _bulk request to index X documents would return Y (> X) items
|
237
|
+
msg = "Sent #{actions.size} documents but Elasticsearch returned #{responses.size} responses"
|
238
|
+
@logger.warn(msg, actions: actions, responses: responses)
|
239
|
+
fail("#{msg} (likely a bug with _bulk endpoint)")
|
240
|
+
end
|
241
|
+
|
207
242
|
actions_to_retry = []
|
208
|
-
|
243
|
+
responses.each_with_index do |response,idx|
|
209
244
|
action_type, action_props = response.first
|
210
245
|
|
211
246
|
status = action_props["status"]
|
212
|
-
|
247
|
+
error = action_props["error"]
|
213
248
|
action = actions[idx]
|
214
249
|
action_params = action[1]
|
215
250
|
|
@@ -222,7 +257,7 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
222
257
|
next
|
223
258
|
elsif DOC_CONFLICT_CODE == status
|
224
259
|
@document_level_metrics.increment(:non_retryable_failures)
|
225
|
-
@logger.warn "Failed action
|
260
|
+
@logger.warn "Failed action", status: status, action: action, response: response if log_failure_type?(error)
|
226
261
|
next
|
227
262
|
elsif DOC_DLQ_CODES.include?(status)
|
228
263
|
handle_dlq_status("Could not index event to Elasticsearch.", action, status, response)
|
@@ -231,7 +266,7 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
231
266
|
else
|
232
267
|
# only log what the user whitelisted
|
233
268
|
@document_level_metrics.increment(:retryable_failures)
|
234
|
-
@logger.info "
|
269
|
+
@logger.info "Retrying failed action", status: status, action: action, error: error if log_failure_type?(error)
|
235
270
|
actions_to_retry << action
|
236
271
|
end
|
237
272
|
end
|
@@ -239,40 +274,25 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
239
274
|
actions_to_retry
|
240
275
|
end
|
241
276
|
|
242
|
-
def
|
243
|
-
|
244
|
-
if @dlq_writer
|
245
|
-
# TODO: Change this to send a map with { :status => status, :action => action } in the future
|
246
|
-
@dlq_writer.write(action[2], "#{message} status: #{status}, action: #{action}, response: #{response}")
|
247
|
-
else
|
248
|
-
error_type = response.fetch('index', {}).fetch('error', {})['type']
|
249
|
-
if 'invalid_index_name_exception' == error_type
|
250
|
-
level = :error
|
251
|
-
else
|
252
|
-
level = :warn
|
253
|
-
end
|
254
|
-
@logger.send level, message, status: status, action: action, response: response
|
255
|
-
end
|
277
|
+
def log_failure_type?(failure)
|
278
|
+
!failure_type_logging_whitelist.include?(failure["type"])
|
256
279
|
end
|
257
280
|
|
258
281
|
# Rescue retryable errors during bulk submission
|
282
|
+
# @param actions a [action, params, event.to_hash] tuple
|
283
|
+
# @return response [Hash] which contains 'errors' and processed 'items' entries
|
259
284
|
def safe_bulk(actions)
|
260
285
|
sleep_interval = @retry_initial_interval
|
261
286
|
begin
|
262
|
-
|
263
|
-
response = @client.bulk(es_actions)
|
264
|
-
response
|
287
|
+
@client.bulk(actions) # returns { 'errors': ..., 'items': ... }
|
265
288
|
rescue ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError => e
|
266
289
|
# If we can't even connect to the server let's just print out the URL (:hosts is actually a URL)
|
267
290
|
# and let the user sort it out from there
|
268
291
|
@logger.error(
|
269
|
-
"Attempted to send a bulk request to
|
270
|
-
|
271
|
-
:error_message => e.message,
|
272
|
-
:class => e.class.name,
|
273
|
-
:will_retry_in_seconds => sleep_interval
|
292
|
+
"Attempted to send a bulk request but Elasticsearch appears to be unreachable or down",
|
293
|
+
message: e.message, exception: e.class, will_retry_in_seconds: sleep_interval
|
274
294
|
)
|
275
|
-
@logger.debug("Failed actions for last bad bulk request
|
295
|
+
@logger.debug? && @logger.debug("Failed actions for last bad bulk request", :actions => actions)
|
276
296
|
|
277
297
|
# We retry until there are no errors! Errors should all go to the retry queue
|
278
298
|
sleep_interval = sleep_for_interval(sleep_interval)
|
@@ -280,20 +300,19 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
280
300
|
retry unless @stopping.true?
|
281
301
|
rescue ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::NoConnectionAvailableError => e
|
282
302
|
@logger.error(
|
283
|
-
"Attempted to send a bulk request
|
284
|
-
|
285
|
-
:
|
286
|
-
:will_retry_in_seconds => sleep_interval
|
303
|
+
"Attempted to send a bulk request but there are no living connections in the pool " +
|
304
|
+
"(perhaps Elasticsearch is unreachable or down?)",
|
305
|
+
message: e.message, exception: e.class, will_retry_in_seconds: sleep_interval
|
287
306
|
)
|
288
|
-
|
289
|
-
sleep_interval =
|
307
|
+
|
308
|
+
sleep_interval = sleep_for_interval(sleep_interval)
|
290
309
|
@bulk_request_metrics.increment(:failures)
|
291
310
|
retry unless @stopping.true?
|
292
311
|
rescue ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError => e
|
293
312
|
@bulk_request_metrics.increment(:failures)
|
294
|
-
log_hash = {:code => e.response_code, :url => e.url.sanitized.to_s}
|
313
|
+
log_hash = {:code => e.response_code, :url => e.url.sanitized.to_s, :content_length => e.request_body.bytesize}
|
295
314
|
log_hash[:body] = e.response_body if @logger.debug? # Generally this is too verbose
|
296
|
-
message = "Encountered a retryable error
|
315
|
+
message = "Encountered a retryable error (will retry with exponential backoff)"
|
297
316
|
|
298
317
|
# We treat 429s as a special case because these really aren't errors, but
|
299
318
|
# rather just ES telling us to back off a bit, which we do.
|
@@ -307,17 +326,12 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
307
326
|
|
308
327
|
sleep_interval = sleep_for_interval(sleep_interval)
|
309
328
|
retry
|
310
|
-
rescue => e
|
311
|
-
# Stuff that should never happen
|
312
|
-
# For all other errors print out full connection issues
|
329
|
+
rescue => e # Stuff that should never happen - print out full connection issues
|
313
330
|
@logger.error(
|
314
|
-
"An unknown error occurred sending a bulk request to Elasticsearch
|
315
|
-
:
|
316
|
-
:error_class => e.class.name,
|
317
|
-
:backtrace => e.backtrace
|
331
|
+
"An unknown error occurred sending a bulk request to Elasticsearch (will retry indefinitely)",
|
332
|
+
message: e.message, exception: e.class, backtrace: e.backtrace
|
318
333
|
)
|
319
|
-
|
320
|
-
@logger.debug("Failed actions for last bad bulk request!", :actions => actions)
|
334
|
+
@logger.debug? && @logger.debug("Failed actions for last bad bulk request", :actions => actions)
|
321
335
|
|
322
336
|
sleep_interval = sleep_for_interval(sleep_interval)
|
323
337
|
@bulk_request_metrics.increment(:failures)
|
@@ -331,5 +345,12 @@ module LogStash; module PluginMixins; module ElasticSearch
|
|
331
345
|
respond_to?(:execution_context) && execution_context.respond_to?(:dlq_writer) &&
|
332
346
|
!execution_context.dlq_writer.inner_writer.is_a?(::LogStash::Util::DummyDeadLetterQueueWriter)
|
333
347
|
end
|
348
|
+
|
349
|
+
def dig_value(val, first_key, *rest_keys)
|
350
|
+
fail(TypeError, "cannot dig value from #{val.class}") unless val.kind_of?(Hash)
|
351
|
+
val = val[first_key]
|
352
|
+
return val if rest_keys.empty? || val == nil
|
353
|
+
dig_value(val, *rest_keys)
|
354
|
+
end
|
334
355
|
end
|
335
356
|
end; end; end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'logstash-output-elasticsearch'
|
3
|
-
s.version = '
|
3
|
+
s.version = '11.0.1'
|
4
4
|
|
5
5
|
s.licenses = ['apache-2.0']
|
6
6
|
s.summary = "Stores logs in Elasticsearch"
|
@@ -23,13 +23,13 @@ Gem::Specification.new do |s|
|
|
23
23
|
|
24
24
|
s.add_runtime_dependency "manticore", '>= 0.5.4', '< 1.0.0'
|
25
25
|
s.add_runtime_dependency 'stud', ['>= 0.0.17', '~> 0.0']
|
26
|
-
s.add_runtime_dependency 'cabin', ['~> 0.6']
|
27
26
|
s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
|
28
27
|
s.add_runtime_dependency 'logstash-mixin-ecs_compatibility_support', '~>1.0'
|
29
28
|
|
30
29
|
s.add_development_dependency 'logstash-codec-plain'
|
31
30
|
s.add_development_dependency 'logstash-devutils'
|
32
31
|
s.add_development_dependency 'flores'
|
32
|
+
s.add_development_dependency 'cabin', ['~> 0.6']
|
33
33
|
# Still used in some specs, we should remove this ASAP
|
34
34
|
s.add_development_dependency 'elasticsearch'
|
35
35
|
end
|
data/spec/es_spec_helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative './spec_helper'
|
2
|
+
|
3
3
|
require 'elasticsearch'
|
4
4
|
require_relative "support/elasticsearch/api/actions/delete_ilm_policy"
|
5
5
|
require_relative "support/elasticsearch/api/actions/get_alias"
|
@@ -8,10 +8,7 @@ require_relative "support/elasticsearch/api/actions/get_ilm_policy"
|
|
8
8
|
require_relative "support/elasticsearch/api/actions/put_ilm_policy"
|
9
9
|
|
10
10
|
require 'json'
|
11
|
-
|
12
|
-
unless defined?(LogStash::OSS)
|
13
|
-
LogStash::OSS = ENV['DISTRIBUTION'] != "default"
|
14
|
-
end
|
11
|
+
require 'cabin'
|
15
12
|
|
16
13
|
module ESHelper
|
17
14
|
def get_host_port
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative "../../../spec/es_spec_helper"
|
2
|
+
require "logstash/outputs/elasticsearch"
|
3
|
+
|
4
|
+
describe "data streams", :integration => true do
|
5
|
+
|
6
|
+
let(:ds_name) { "logs-#{ds_dataset}-default" }
|
7
|
+
let(:ds_dataset) { 'integration_test' }
|
8
|
+
|
9
|
+
let(:options) do
|
10
|
+
{ "data_stream" => 'true', "data_stream_dataset" => ds_dataset, "hosts" => get_host_port() }
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { LogStash::Outputs::ElasticSearch.new(options) }
|
14
|
+
|
15
|
+
before :each do
|
16
|
+
@es = get_client
|
17
|
+
@es.delete_by_query(index: ".ds-#{ds_name}-*", expand_wildcards: :all, body: { query: { match_all: {} } }) rescue nil
|
18
|
+
|
19
|
+
es_version = @es.info['version']['number']
|
20
|
+
if Gem::Version.create(es_version) < Gem::Version.create('7.9.0')
|
21
|
+
skip "ES version #{es_version} does not support data-streams"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "creates a new document" do
|
26
|
+
subject.register
|
27
|
+
subject.multi_receive([LogStash::Event.new("message" => "MSG 111")])
|
28
|
+
|
29
|
+
@es.indices.refresh
|
30
|
+
|
31
|
+
Stud::try(3.times) do
|
32
|
+
r = @es.search(index: ds_name)
|
33
|
+
|
34
|
+
expect( r['hits']['total']['value'] ).to eq 1
|
35
|
+
doc = r['hits']['hits'].first
|
36
|
+
expect( doc['_source'] ).to include "message"=>"MSG 111"
|
37
|
+
expect( doc['_source'] ).to include "data_stream"=>{"dataset"=>ds_dataset, "type"=>"logs", "namespace"=>"default"}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "with document_id" do
|
42
|
+
|
43
|
+
let(:document_id) { '1234567890' }
|
44
|
+
let(:options) { super().merge("document_id" => document_id) }
|
45
|
+
|
46
|
+
it "creates a new document" do
|
47
|
+
subject.register
|
48
|
+
subject.multi_receive([LogStash::Event.new("message" => "foo")])
|
49
|
+
|
50
|
+
@es.indices.refresh
|
51
|
+
|
52
|
+
Stud::try(3.times) do
|
53
|
+
r = @es.search(index: ds_name, body: { query: { match: { _id: document_id } } })
|
54
|
+
expect( r['hits']['total']['value'] ).to eq 1
|
55
|
+
doc = r['hits']['hits'].first
|
56
|
+
expect( doc['_source'] ).to include "message"=>"foo"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -5,7 +5,7 @@ shared_examples_for 'an ILM enabled Logstash' do
|
|
5
5
|
context 'with a policy with a maximum number of documents' do
|
6
6
|
let (:policy) { small_max_doc_policy }
|
7
7
|
let (:ilm_policy_name) { "logstash-policy-custom"}
|
8
|
-
let (:settings) { super.merge("ilm_policy" => ilm_policy_name)}
|
8
|
+
let (:settings) { super().merge("ilm_policy" => ilm_policy_name)}
|
9
9
|
|
10
10
|
it 'should rollover when the policy max docs is reached' do
|
11
11
|
put_policy(@es, ilm_policy_name, policy)
|
@@ -54,7 +54,7 @@ shared_examples_for 'an ILM enabled Logstash' do
|
|
54
54
|
context 'with a policy where the maximum number of documents is not reached' do
|
55
55
|
let (:policy) { large_max_doc_policy }
|
56
56
|
let (:ilm_policy_name) { "logstash-policy-custom-policy"}
|
57
|
-
let (:settings) { super.merge("ilm_policy" => ilm_policy_name)}
|
57
|
+
let (:settings) { super().merge("ilm_policy" => ilm_policy_name)}
|
58
58
|
|
59
59
|
it 'should ingest into a single index when max docs is not reached' do
|
60
60
|
put_policy(@es,ilm_policy_name, policy)
|
@@ -119,7 +119,7 @@ shared_examples_for 'an ILM disabled Logstash' do
|
|
119
119
|
context 'with an existing policy that will roll over' do
|
120
120
|
let (:policy) { small_max_doc_policy }
|
121
121
|
let (:ilm_policy_name) { "logstash-policy-3_docs"}
|
122
|
-
let (:settings) { super.merge("ilm_policy" => ilm_policy_name)}
|
122
|
+
let (:settings) { super().merge("ilm_policy" => ilm_policy_name)}
|
123
123
|
|
124
124
|
it 'should not roll over indices' do
|
125
125
|
subject.register
|
@@ -155,7 +155,7 @@ shared_examples_for 'an ILM disabled Logstash' do
|
|
155
155
|
|
156
156
|
context 'with a custom template name' do
|
157
157
|
let (:template_name) { "logstash_custom_template_name" }
|
158
|
-
let (:settings) { super.merge('template_name' => template_name)}
|
158
|
+
let (:settings) { super().merge('template_name' => template_name)}
|
159
159
|
|
160
160
|
it 'should not write the ILM settings into the template' do
|
161
161
|
subject.register
|
@@ -195,28 +195,32 @@ shared_examples_for 'an Elasticsearch instance that does not support index lifec
|
|
195
195
|
subject { LogStash::Outputs::ElasticSearch.new(settings) }
|
196
196
|
|
197
197
|
context 'when ilm is enabled in Logstash' do
|
198
|
-
let (:settings) { super.merge!({ 'ilm_enabled' => true }) }
|
198
|
+
let (:settings) { super().merge!({ 'ilm_enabled' => true }) }
|
199
199
|
|
200
200
|
it 'should raise a configuration error' do
|
201
|
+
# TODO should be refactored not to rely on plugin internals
|
202
|
+
finish_register = subject.method(:finish_register)
|
203
|
+
expect(subject).to receive(:finish_register)
|
201
204
|
expect do
|
202
205
|
begin
|
203
206
|
subject.register
|
204
|
-
|
207
|
+
finish_register.call
|
208
|
+
sleep(1.5) # wait_for_successful_connection (for the thread to raise)
|
205
209
|
ensure
|
206
|
-
subject.
|
210
|
+
subject.send :stop_after_successful_connection_thread
|
207
211
|
end
|
208
212
|
end.to raise_error(LogStash::ConfigurationError)
|
209
213
|
end
|
210
214
|
end
|
211
215
|
|
212
216
|
context 'when ilm is disabled in Logstash' do
|
213
|
-
let (:settings) { super.merge!({ 'ilm_enabled' => false }) }
|
217
|
+
let (:settings) { super().merge!({ 'ilm_enabled' => false }) }
|
214
218
|
|
215
219
|
it_behaves_like 'an ILM disabled Logstash'
|
216
220
|
end
|
217
221
|
|
218
222
|
context 'when ilm is set to auto in Logstash' do
|
219
|
-
let (:settings) { super.merge!({ 'ilm_enabled' => 'auto' }) }
|
223
|
+
let (:settings) { super().merge!({ 'ilm_enabled' => 'auto' }) }
|
220
224
|
|
221
225
|
it_behaves_like 'an ILM disabled Logstash'
|
222
226
|
end
|
@@ -286,7 +290,7 @@ if ESHelper.es_version_satisfies?(">= 6.6")
|
|
286
290
|
|
287
291
|
context 'when using the default policy' do
|
288
292
|
context 'with a custom pattern' do
|
289
|
-
let (:settings) { super.merge("ilm_pattern" => "000001")}
|
293
|
+
let (:settings) { super().merge("ilm_pattern" => "000001")}
|
290
294
|
it 'should create a rollover alias' do
|
291
295
|
expect(@es.indices.exists_alias(name: "logstash")).to be_falsey
|
292
296
|
subject.register
|
@@ -346,7 +350,7 @@ if ESHelper.es_version_satisfies?(">= 6.6")
|
|
346
350
|
|
347
351
|
context 'when not using the default policy' do
|
348
352
|
let (:ilm_policy_name) {"logstash-policy-small"}
|
349
|
-
let (:settings) { super.merge("ilm_policy" => ilm_policy_name)}
|
353
|
+
let (:settings) { super().merge("ilm_policy" => ilm_policy_name)}
|
350
354
|
let (:policy) { small_max_doc_policy }
|
351
355
|
|
352
356
|
before do
|
@@ -363,7 +367,7 @@ if ESHelper.es_version_satisfies?(">= 6.6")
|
|
363
367
|
|
364
368
|
context 'when using a time based policy' do
|
365
369
|
let (:ilm_policy_name) {"logstash-policy-time"}
|
366
|
-
let (:settings) { super.merge("ilm_policy" => ilm_policy_name)}
|
370
|
+
let (:settings) { super().merge("ilm_policy" => ilm_policy_name)}
|
367
371
|
let (:policy) { max_age_policy("1d") }
|
368
372
|
|
369
373
|
before do
|
@@ -409,7 +413,7 @@ if ESHelper.es_version_satisfies?(">= 6.6")
|
|
409
413
|
let (:template) { "spec/fixtures/template-with-policy-es6x.json" }
|
410
414
|
end
|
411
415
|
|
412
|
-
let (:settings) { super.merge("template" => template,
|
416
|
+
let (:settings) { super().merge("template" => template,
|
413
417
|
"index" => "overwrite-4")}
|
414
418
|
|
415
419
|
it 'should not overwrite the index patterns' do
|
@@ -426,7 +430,7 @@ if ESHelper.es_version_satisfies?(">= 6.6")
|
|
426
430
|
let (:ilm_rollover_alias) { "logstash_the_cat_in_the_hat" }
|
427
431
|
let (:index) { ilm_rollover_alias }
|
428
432
|
let(:expected_index) { index }
|
429
|
-
let (:settings) { super.merge("ilm_policy" => ilm_policy_name,
|
433
|
+
let (:settings) { super().merge("ilm_policy" => ilm_policy_name,
|
430
434
|
"template" => template,
|
431
435
|
"ilm_rollover_alias" => ilm_rollover_alias)}
|
432
436
|
|
@@ -480,7 +484,7 @@ if ESHelper.es_version_satisfies?(">= 6.6")
|
|
480
484
|
|
481
485
|
context 'with a different template_name' do
|
482
486
|
let (:template_name) { "logstash_custom_template_name" }
|
483
|
-
let (:settings) { super.merge('template_name' => template_name)}
|
487
|
+
let (:settings) { super().merge('template_name' => template_name)}
|
484
488
|
|
485
489
|
it_behaves_like 'an ILM enabled Logstash'
|
486
490
|
|
@@ -514,7 +518,7 @@ if ESHelper.es_version_satisfies?(">= 6.6")
|
|
514
518
|
end
|
515
519
|
|
516
520
|
context 'when ilm_enabled is the default' do
|
517
|
-
let (:settings) { super.tap{|x|x.delete('ilm_enabled')}}
|
521
|
+
let (:settings) { super().tap{|x|x.delete('ilm_enabled')}}
|
518
522
|
|
519
523
|
if ESHelper.es_version_satisfies?(">=7.0")
|
520
524
|
context 'when Elasticsearch is version 7 or above' do
|
@@ -530,13 +534,13 @@ if ESHelper.es_version_satisfies?(">= 6.6")
|
|
530
534
|
end
|
531
535
|
|
532
536
|
context 'with ilm disabled' do
|
533
|
-
let (:settings) { super.merge('ilm_enabled' => false )}
|
537
|
+
let (:settings) { super().merge('ilm_enabled' => false )}
|
534
538
|
|
535
539
|
it_behaves_like 'an ILM disabled Logstash'
|
536
540
|
end
|
537
541
|
|
538
542
|
context 'with ilm disabled using a string' do
|
539
|
-
let (:settings) { super.merge('ilm_enabled' => 'false' )}
|
543
|
+
let (:settings) { super().merge('ilm_enabled' => 'false' )}
|
540
544
|
|
541
545
|
it_behaves_like 'an ILM disabled Logstash'
|
542
546
|
end
|