fluent-plugin-elasticsearch 5.0.0 → 5.2.3
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/.github/dependabot.yml +6 -0
- data/.github/workflows/linux.yml +5 -2
- data/.github/workflows/macos.yml +5 -2
- data/.github/workflows/windows.yml +5 -2
- data/Gemfile +1 -1
- data/History.md +65 -1
- data/README.Troubleshooting.md +91 -0
- data/README.md +129 -4
- data/fluent-plugin-elasticsearch.gemspec +2 -1
- data/lib/fluent/plugin/elasticsearch_compat.rb +30 -0
- data/lib/fluent/plugin/elasticsearch_error_handler.rb +19 -4
- data/lib/fluent/plugin/elasticsearch_fallback_selector.rb +2 -2
- data/lib/fluent/plugin/elasticsearch_index_lifecycle_management.rb +18 -4
- data/lib/fluent/plugin/elasticsearch_index_template.rb +20 -4
- data/lib/fluent/plugin/elasticsearch_simple_sniffer.rb +2 -1
- data/lib/fluent/plugin/filter_elasticsearch_genid.rb +1 -1
- data/lib/fluent/plugin/in_elasticsearch.rb +2 -1
- data/lib/fluent/plugin/oj_serializer.rb +2 -1
- data/lib/fluent/plugin/out_elasticsearch.rb +80 -19
- data/lib/fluent/plugin/out_elasticsearch_data_stream.rb +132 -62
- data/lib/fluent/plugin/out_elasticsearch_dynamic.rb +3 -1
- data/test/plugin/mock_chunk.dat +0 -0
- data/test/plugin/test_elasticsearch_error_handler.rb +130 -23
- data/test/plugin/test_elasticsearch_fallback_selector.rb +16 -8
- data/test/plugin/test_elasticsearch_index_lifecycle_management.rb +55 -15
- data/test/plugin/test_filter_elasticsearch_genid.rb +16 -16
- data/test/plugin/test_in_elasticsearch.rb +20 -0
- data/test/plugin/test_out_elasticsearch.rb +795 -134
- data/test/plugin/test_out_elasticsearch_data_stream.rb +717 -117
- data/test/plugin/test_out_elasticsearch_dynamic.rb +150 -18
- metadata +21 -5
- data/.travis.yml +0 -40
- data/appveyor.yml +0 -20
@@ -19,10 +19,26 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
19
19
|
@driver = nil
|
20
20
|
log = Fluent::Engine.log
|
21
21
|
log.out.logs.slice!(0, log.out.logs.length)
|
22
|
-
@bulk_records =
|
22
|
+
@bulk_records = []
|
23
23
|
end
|
24
24
|
|
25
|
-
def
|
25
|
+
def elasticsearch_version
|
26
|
+
if Gem::Version.new(TRANSPORT_CLASS::VERSION) >= Gem::Version.new("7.14.0")
|
27
|
+
TRANSPORT_CLASS::VERSION
|
28
|
+
else
|
29
|
+
'5.0.0'.freeze
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def ilm_endpoint
|
34
|
+
if Gem::Version.new(TRANSPORT_CLASS::VERSION) >= Gem::Version.new("8.0.0")
|
35
|
+
'_enrich'.freeze
|
36
|
+
else
|
37
|
+
'_ilm'.freeze
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def driver(conf='', es_version=elasticsearch_version.to_i, client_version=elasticsearch_version)
|
26
42
|
# For request stub to detect compatibility.
|
27
43
|
@es_version ||= es_version
|
28
44
|
@client_version ||= client_version
|
@@ -45,7 +61,7 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
45
61
|
{
|
46
62
|
'data_streams': [
|
47
63
|
{
|
48
|
-
'name' => '
|
64
|
+
'name' => 'foo',
|
49
65
|
'timestamp_field' => {
|
50
66
|
'name' => '@timestamp'
|
51
67
|
}
|
@@ -54,52 +70,110 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
54
70
|
}
|
55
71
|
end
|
56
72
|
|
73
|
+
SAMPLE_RECORD_TIMESTAMP = Time.now.iso8601
|
57
74
|
def sample_record
|
58
|
-
{'@timestamp' =>
|
75
|
+
{'@timestamp' => SAMPLE_RECORD_TIMESTAMP, 'message' => 'Sample record'}
|
76
|
+
end
|
77
|
+
|
78
|
+
def sample_record_no_timestamp
|
79
|
+
{'message' => 'Sample record no timestamp'}
|
59
80
|
end
|
60
81
|
|
61
82
|
RESPONSE_ACKNOWLEDGED = {"acknowledged": true}
|
62
83
|
DUPLICATED_DATA_STREAM_EXCEPTION = {"error": {}, "status": 400}
|
63
84
|
NONEXISTENT_DATA_STREAM_EXCEPTION = {"error": {}, "status": 404}
|
64
85
|
|
65
|
-
def stub_ilm_policy(name="
|
66
|
-
stub_request(:put, "
|
86
|
+
def stub_ilm_policy(name="foo_ilm_policy", url="http://localhost:9200")
|
87
|
+
stub_request(:put, "#{url}/#{ilm_endpoint}/policy/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
88
|
+
end
|
89
|
+
|
90
|
+
def stub_index_template(name="foo_tpl", url="http://localhost:9200")
|
91
|
+
stub_request(:put, "#{url}/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
92
|
+
end
|
93
|
+
|
94
|
+
def stub_data_stream(name="foo", url="http://localhost:9200")
|
95
|
+
stub_request(:put, "#{url}/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
96
|
+
end
|
97
|
+
|
98
|
+
def stub_existent_data_stream?(name="foo", url="http://localhost:9200")
|
99
|
+
stub_request(:get, "#{url}/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
100
|
+
end
|
101
|
+
|
102
|
+
def stub_existent_ilm?(name="foo_ilm_policy", url="http://localhost:9200")
|
103
|
+
|
104
|
+
stub_request(:get, "#{url}/#{ilm_endpoint}/policy/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
105
|
+
end
|
106
|
+
|
107
|
+
def stub_existent_template?(name="foo_tpl", url="http://localhost:9200")
|
108
|
+
stub_request(:get, "#{url}/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
67
109
|
end
|
68
110
|
|
69
|
-
def
|
70
|
-
stub_request(:
|
111
|
+
def stub_nonexistent_data_stream?(name="foo", url="http://localhost:9200")
|
112
|
+
stub_request(:get, "#{url}/_data_stream/#{name}").to_return(:status => [404, TRANSPORT_CLASS::Transport::Errors::NotFound])
|
71
113
|
end
|
72
114
|
|
73
|
-
def
|
74
|
-
stub_request(:
|
115
|
+
def stub_nonexistent_ilm?(name="foo_ilm_policy", url="http://localhost:9200")
|
116
|
+
stub_request(:get, "#{url}/#{ilm_endpoint}/policy/#{name}").to_return(:status => [404, TRANSPORT_CLASS::Transport::Errors::NotFound])
|
75
117
|
end
|
76
118
|
|
77
|
-
def
|
78
|
-
stub_request(:get, "
|
119
|
+
def stub_nonexistent_template?(name="foo_tpl", url="http://localhost:9200")
|
120
|
+
stub_request(:get, "#{url}/_index_template/#{name}").to_return(:status => [404, TRANSPORT_CLASS::Transport::Errors::NotFound])
|
79
121
|
end
|
80
122
|
|
81
|
-
|
82
|
-
|
123
|
+
|
124
|
+
def push_bulk_request(req_body)
|
125
|
+
# bulk data must be pair of OP and records
|
126
|
+
# {"create": {}}\nhttp://localhost:9200/_ilm/policy/foo_ilm_bar
|
127
|
+
# {"@timestamp": ...}
|
128
|
+
ops = req_body.split("\n")
|
129
|
+
@bulk_records += ops.values_at(
|
130
|
+
* ops.each_index.select {|i| i.odd? }
|
131
|
+
).map{ |i| JSON.parse(i) }
|
132
|
+
end
|
133
|
+
|
134
|
+
def stub_nonexistent_template_retry?(name="foo_tpl", url="http://localhost:9200")
|
135
|
+
stub_request(:get, "#{url}/_index_template/#{name}").
|
136
|
+
to_return({ status: 500, body: 'Internal Server Error' }, { status: 404, body: '{}' })
|
83
137
|
end
|
84
138
|
|
85
|
-
def stub_bulk_feed(
|
86
|
-
stub_request(:post, "
|
139
|
+
def stub_bulk_feed(datastream_name="foo", ilm_name="foo_ilm_policy", template_name="foo_tpl", url="http://localhost:9200")
|
140
|
+
stub_request(:post, "#{url}/#{datastream_name}/_bulk").with do |req|
|
87
141
|
# bulk data must be pair of OP and records
|
88
|
-
# {"create": {}}\
|
142
|
+
# {"create": {}}\nhttp://localhost:9200/_ilm/policy/foo_ilm_bar
|
89
143
|
# {"@timestamp": ...}
|
90
|
-
|
144
|
+
push_bulk_request(req.body)
|
91
145
|
end
|
146
|
+
stub_request(:post, "#{url}/#{ilm_name}/_bulk").with do |req|
|
147
|
+
# bulk data must be pair of OP and records
|
148
|
+
# {"create": {}}\nhttp://localhost:9200/_ilm/policy/foo_ilm_bar
|
149
|
+
# {"@timestamp": ...}
|
150
|
+
push_bulk_request(req.body)
|
151
|
+
end
|
152
|
+
stub_request(:post, "#{url}/#{template_name}/_bulk").with do |req|
|
153
|
+
# bulk data must be pair of OP and records
|
154
|
+
# {"create": {}}\nhttp://localhost:9200/_ilm/policy/foo_ilm_bar
|
155
|
+
# {"@timestamp": ...}
|
156
|
+
push_bulk_request(req.body)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def stub_elastic_info(url="http://localhost:9200/", version=elasticsearch_version, headers={})
|
161
|
+
body ="{\"version\":{\"number\":\"#{version}\", \"build_flavor\":\"default\"},\"tagline\" : \"You Know, for Search\"}"
|
162
|
+
stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json', 'x-elastic-product' => 'Elasticsearch' }.merge(headers) })
|
92
163
|
end
|
93
164
|
|
94
|
-
def stub_default(
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
165
|
+
def stub_default(datastream_name="foo", ilm_name="foo_ilm_policy", template_name="foo_tpl", host="http://localhost:9200")
|
166
|
+
stub_elastic_info(host)
|
167
|
+
stub_nonexistent_ilm?(ilm_name)
|
168
|
+
stub_ilm_policy(ilm_name)
|
169
|
+
stub_nonexistent_template?(template_name)
|
170
|
+
stub_index_template(template_name)
|
171
|
+
stub_nonexistent_data_stream?(datastream_name)
|
172
|
+
stub_data_stream(datastream_name)
|
99
173
|
end
|
100
174
|
|
101
175
|
def data_stream_supported?
|
102
|
-
Gem::Version.create(::
|
176
|
+
Gem::Version.create(::TRANSPORT_CLASS::VERSION) >= Gem::Version.create("7.9.0")
|
103
177
|
end
|
104
178
|
|
105
179
|
# ref. https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-create-data-stream.html
|
@@ -115,82 +189,274 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
115
189
|
end
|
116
190
|
end
|
117
191
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
'
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
192
|
+
sub_test_case "invalid uppercase" do
|
193
|
+
def test_stream_name
|
194
|
+
conf = config_element(
|
195
|
+
'ROOT', '', {
|
196
|
+
'@type' => 'elasticsearch_datastream',
|
197
|
+
'data_stream_name' => 'TEST',
|
198
|
+
'data_stream_ilm_name' => 'default-policy',
|
199
|
+
'data_stream_template_name' => 'template'
|
200
|
+
})
|
201
|
+
assert_raise Fluent::ConfigError.new("'data_stream_name' must be lowercase only: <TEST>") do
|
202
|
+
driver(conf)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
def test_stream_ilm_name
|
206
|
+
conf = config_element(
|
207
|
+
'ROOT', '', {
|
208
|
+
'@type' => 'elasticsearch_datastream',
|
209
|
+
'data_stream_name' => 'data_stream',
|
210
|
+
'data_stream_ilm_name' => 'TEST-ILM',
|
211
|
+
'data_stream_template_name' => 'template'
|
212
|
+
})
|
213
|
+
assert_raise Fluent::ConfigError.new("'data_stream_ilm_name' must be lowercase only: <TEST-ILM>") do
|
214
|
+
driver(conf)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
def test_stream_template_name
|
218
|
+
conf = config_element(
|
219
|
+
'ROOT', '', {
|
220
|
+
'@type' => 'elasticsearch_datastream',
|
221
|
+
'data_stream_name' => 'default',
|
222
|
+
'data_stream_ilm_name' => 'default-policy',
|
223
|
+
'data_stream_template_name' => 'TEST-TPL'
|
224
|
+
})
|
225
|
+
assert_raise Fluent::ConfigError.new("'data_stream_template_name' must be lowercase only: <TEST-TPL>") do
|
226
|
+
driver(conf)
|
227
|
+
end
|
126
228
|
end
|
127
229
|
end
|
128
230
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
'
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
231
|
+
sub_test_case "invalid parameters" do
|
232
|
+
data("backslash" => "\\",
|
233
|
+
"slash" => "/",
|
234
|
+
"asterisk" => "*",
|
235
|
+
"question" => "?",
|
236
|
+
"doublequote" => "\"",
|
237
|
+
"lt" => "<",
|
238
|
+
"gt" => ">",
|
239
|
+
"bar" => "|",
|
240
|
+
"space" => " ",
|
241
|
+
"comma" => ",",
|
242
|
+
"sharp" => "#",
|
243
|
+
"colon" => ":")
|
244
|
+
def test_stream_name(data)
|
245
|
+
c, _ = data
|
246
|
+
conf = config_element(
|
247
|
+
'ROOT', '', {
|
248
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
249
|
+
'data_stream_name' => "TEST#{c}",
|
250
|
+
'data_stream_ilm_name' => "default_policy",
|
251
|
+
'data_stream_template_name' => "data_stream"
|
252
|
+
})
|
253
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_CHARACTERS.join(',')
|
254
|
+
assert_raise Fluent::ConfigError.new("'data_stream_name' must not contain invalid characters #{label}: <TEST#{c}>") do
|
255
|
+
driver(conf)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
data("backslash" => "\\",
|
260
|
+
"slash" => "/",
|
261
|
+
"asterisk" => "*",
|
262
|
+
"question" => "?",
|
263
|
+
"doublequote" => "\"",
|
264
|
+
"lt" => "<",
|
265
|
+
"gt" => ">",
|
266
|
+
"bar" => "|",
|
267
|
+
"space" => " ",
|
268
|
+
"comma" => ",",
|
269
|
+
"sharp" => "#",
|
270
|
+
"colon" => ":")
|
271
|
+
def test_stream_ilm_name(data)
|
272
|
+
c, _ = data
|
273
|
+
conf = config_element(
|
274
|
+
'ROOT', '', {
|
275
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
276
|
+
'data_stream_name' => "default",
|
277
|
+
'data_stream_ilm_name' => "TEST#{c}",
|
278
|
+
'data_stream_template_name' => "data_stream"
|
279
|
+
})
|
280
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_CHARACTERS.join(',')
|
281
|
+
assert_raise Fluent::ConfigError.new("'data_stream_ilm_name' must not contain invalid characters #{label}: <TEST#{c}>") do
|
282
|
+
driver(conf)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
data("backslash" => "\\",
|
287
|
+
"slash" => "/",
|
288
|
+
"asterisk" => "*",
|
289
|
+
"question" => "?",
|
290
|
+
"doublequote" => "\"",
|
291
|
+
"lt" => "<",
|
292
|
+
"gt" => ">",
|
293
|
+
"bar" => "|",
|
294
|
+
"space" => " ",
|
295
|
+
"comma" => ",",
|
296
|
+
"sharp" => "#",
|
297
|
+
"colon" => ":")
|
298
|
+
def test_stream_template_name(data)
|
299
|
+
c, _ = data
|
300
|
+
conf = config_element(
|
301
|
+
'ROOT', '', {
|
302
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
303
|
+
'data_stream_name' => "default",
|
304
|
+
'data_stream_ilm_name' => "default_policy",
|
305
|
+
'data_stream_template_name' => "TEST#{c}"
|
306
|
+
})
|
307
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_CHARACTERS.join(',')
|
308
|
+
assert_raise Fluent::ConfigError.new("'data_stream_template_name' must not contain invalid characters #{label}: <TEST#{c}>") do
|
309
|
+
driver(conf)
|
310
|
+
end
|
151
311
|
end
|
152
312
|
end
|
153
313
|
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
'
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
314
|
+
sub_test_case "invalid start characters" do
|
315
|
+
data("hyphen" => "-",
|
316
|
+
"underscore" => "_",
|
317
|
+
"plus" => "+",
|
318
|
+
"period" => ".")
|
319
|
+
def test_stream_name(data)
|
320
|
+
c, _ = data
|
321
|
+
conf = config_element(
|
322
|
+
'ROOT', '', {
|
323
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
324
|
+
'data_stream_name' => "#{c}TEST",
|
325
|
+
'data_stream_ilm_name' => "default-policy",
|
326
|
+
'data_stream_template_name' => "template"
|
327
|
+
})
|
328
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_START_CHRACTERS.join(',')
|
329
|
+
assert_raise Fluent::ConfigError.new("'data_stream_name' must not start with #{label}: <#{c}TEST>") do
|
330
|
+
driver(conf)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
data("hyphen" => "-",
|
334
|
+
"underscore" => "_",
|
335
|
+
"plus" => "+",
|
336
|
+
"period" => ".")
|
337
|
+
def test_stream_ilm_name(data)
|
338
|
+
c, _ = data
|
339
|
+
conf = config_element(
|
340
|
+
'ROOT', '', {
|
341
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
342
|
+
'data_stream_name' => "default",
|
343
|
+
'data_stream_ilm_name' => "#{c}TEST",
|
344
|
+
'data_stream_template_name' => "template"
|
345
|
+
})
|
346
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_START_CHRACTERS.join(',')
|
347
|
+
assert_raise Fluent::ConfigError.new("'data_stream_ilm_name' must not start with #{label}: <#{c}TEST>") do
|
348
|
+
driver(conf)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
data("hyphen" => "-",
|
352
|
+
"underscore" => "_",
|
353
|
+
"plus" => "+",
|
354
|
+
"period" => ".")
|
355
|
+
def test_stream_template_name(data)
|
356
|
+
c, _ = data
|
357
|
+
conf = config_element(
|
358
|
+
'ROOT', '', {
|
359
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
360
|
+
'data_stream_name' => "default",
|
361
|
+
'data_stream_ilm_name' => "default-policy",
|
362
|
+
'data_stream_template_name' => "#{c}TEST"
|
363
|
+
})
|
364
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_START_CHRACTERS.join(',')
|
365
|
+
assert_raise Fluent::ConfigError.new("'data_stream_template_name' must not start with #{label}: <#{c}TEST>") do
|
366
|
+
driver(conf)
|
367
|
+
end
|
168
368
|
end
|
169
369
|
end
|
170
370
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
'
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
371
|
+
sub_test_case "invalid dots" do
|
372
|
+
data("current" => ".",
|
373
|
+
"parents" => "..")
|
374
|
+
def test_stream_name
|
375
|
+
c, _ = data
|
376
|
+
conf = config_element(
|
377
|
+
'ROOT', '', {
|
378
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
379
|
+
'data_stream_name' => "#{c}",
|
380
|
+
'data_stream_ilm_name' => "default-policy",
|
381
|
+
'data_stream_template_name' => "template"
|
382
|
+
})
|
383
|
+
assert_raise Fluent::ConfigError.new("'data_stream_name' must not be . or ..: <#{c}>") do
|
384
|
+
driver(conf)
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
data("current" => ".",
|
389
|
+
"parents" => "..")
|
390
|
+
def test_stream_ilm_name
|
391
|
+
c, _ = data
|
392
|
+
conf = config_element(
|
393
|
+
'ROOT', '', {
|
394
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
395
|
+
'data_stream_name' => "default",
|
396
|
+
'data_stream_ilm_name' => "#{c}",
|
397
|
+
'data_stream_template_name' => "template"
|
398
|
+
})
|
399
|
+
assert_raise Fluent::ConfigError.new("'data_stream_ilm_name' must not be . or ..: <#{c}>") do
|
400
|
+
driver(conf)
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
404
|
+
data("current" => ".",
|
405
|
+
"parents" => "..")
|
406
|
+
def test_stream_template_name
|
407
|
+
c, _ = data
|
408
|
+
conf = config_element(
|
409
|
+
'ROOT', '', {
|
410
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
411
|
+
'data_stream_name' => "default",
|
412
|
+
'data_stream_ilm_name' => "default-policy",
|
413
|
+
'data_stream_template_name' => "#{c}"
|
414
|
+
})
|
415
|
+
assert_raise Fluent::ConfigError.new("'data_stream_template_name' must not be . or ..: <#{c}>") do
|
416
|
+
driver(conf)
|
417
|
+
end
|
182
418
|
end
|
183
419
|
end
|
184
420
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
'
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
421
|
+
sub_test_case "invalid length" do
|
422
|
+
def test_stream_name
|
423
|
+
c = "a" * 256
|
424
|
+
conf = config_element(
|
425
|
+
'ROOT', '', {
|
426
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
427
|
+
'data_stream_name' => "#{c}",
|
428
|
+
'data_stream_ilm_name' => "default-policy",
|
429
|
+
'data_stream_template_name' => "template"
|
430
|
+
})
|
431
|
+
assert_raise Fluent::ConfigError.new("'data_stream_name' must not be longer than 255 bytes: <#{c}>") do
|
432
|
+
driver(conf)
|
433
|
+
end
|
434
|
+
end
|
435
|
+
def test_stream_ilm_name
|
436
|
+
c = "a" * 256
|
437
|
+
conf = config_element(
|
438
|
+
'ROOT', '', {
|
439
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
440
|
+
'data_stream_name' => "default",
|
441
|
+
'data_stream_ilm_name' => "#{c}",
|
442
|
+
'data_stream_template_name' => "template"
|
443
|
+
})
|
444
|
+
assert_raise Fluent::ConfigError.new("'data_stream_ilm_name' must not be longer than 255 bytes: <#{c}>") do
|
445
|
+
driver(conf)
|
446
|
+
end
|
447
|
+
end
|
448
|
+
def test_stream_template_name
|
449
|
+
c = "a" * 256
|
450
|
+
conf = config_element(
|
451
|
+
'ROOT', '', {
|
452
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
453
|
+
'data_stream_name' => "default",
|
454
|
+
'data_stream_ilm_name' => "default-policy",
|
455
|
+
'data_stream_template_name' => "#{c}"
|
456
|
+
})
|
457
|
+
assert_raise Fluent::ConfigError.new("'data_stream_template_name' must not be longer than 255 bytes: <#{c}>") do
|
458
|
+
driver(conf)
|
459
|
+
end
|
194
460
|
end
|
195
461
|
end
|
196
462
|
end
|
@@ -202,54 +468,192 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
202
468
|
conf = config_element(
|
203
469
|
'ROOT', '', {
|
204
470
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
205
|
-
'data_stream_name' => 'foo'
|
471
|
+
'data_stream_name' => 'foo',
|
472
|
+
'data_stream_ilm_name' => "foo_ilm_policy",
|
473
|
+
'data_stream_template_name' => "foo_tpl"
|
206
474
|
})
|
207
475
|
assert_equal "foo", driver(conf).instance.data_stream_name
|
208
476
|
end
|
209
477
|
|
210
|
-
def
|
478
|
+
def test_datastream_configure_retry
|
479
|
+
stub_elastic_info
|
480
|
+
stub_nonexistent_ilm?
|
481
|
+
stub_ilm_policy
|
482
|
+
stub_nonexistent_template_retry?
|
483
|
+
stub_index_template
|
484
|
+
stub_nonexistent_data_stream?
|
485
|
+
stub_data_stream
|
486
|
+
conf = config_element(
|
487
|
+
'ROOT', '', {
|
488
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
489
|
+
'data_stream_name' => 'foo',
|
490
|
+
'data_stream_ilm_name' => "foo_ilm_policy",
|
491
|
+
'data_stream_template_name' => "foo_tpl"
|
492
|
+
})
|
493
|
+
assert_equal "foo", driver(conf).instance.data_stream_name
|
494
|
+
end
|
495
|
+
|
496
|
+
def test_hosts_list_configure
|
497
|
+
config = %{
|
498
|
+
hosts https://john:password@host1:443/elastic/,http://host2
|
499
|
+
path /default_path
|
500
|
+
user default_user
|
501
|
+
password default_password
|
502
|
+
data_stream_name default
|
503
|
+
}
|
504
|
+
stub_elastic_info("https://host1:443/elastic//", elasticsearch_version,
|
505
|
+
{'Authorization'=>"Basic #{Base64.encode64('john:password').split.first}"})
|
506
|
+
stub_elastic_info("http://host2/default_path/_data_stream/default", elasticsearch_version,
|
507
|
+
{'Authorization'=>"Basic #{Base64.encode64('john:password').split.first}"})
|
508
|
+
stub_existent_data_stream?("default", "https://host1/elastic/")
|
509
|
+
instance = driver(config).instance
|
510
|
+
|
511
|
+
assert_equal 2, instance.get_connection_options[:hosts].length
|
512
|
+
host1, host2 = instance.get_connection_options[:hosts]
|
513
|
+
|
514
|
+
assert_equal 'host1', host1[:host]
|
515
|
+
assert_equal 443, host1[:port]
|
516
|
+
assert_equal 'https', host1[:scheme]
|
517
|
+
assert_equal 'john', host1[:user]
|
518
|
+
assert_equal 'password', host1[:password]
|
519
|
+
assert_equal '/elastic/', host1[:path]
|
520
|
+
|
521
|
+
assert_equal 'host2', host2[:host]
|
522
|
+
assert_equal 'http', host2[:scheme]
|
523
|
+
assert_equal 'default_user', host2[:user]
|
524
|
+
assert_equal 'default_password', host2[:password]
|
525
|
+
assert_equal '/default_path', host2[:path]
|
526
|
+
end
|
527
|
+
|
528
|
+
def test_existent_data_stream
|
211
529
|
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
212
530
|
|
213
531
|
stub_ilm_policy
|
214
532
|
stub_index_template
|
215
|
-
|
533
|
+
stub_existent_data_stream?
|
534
|
+
stub_data_stream
|
535
|
+
stub_elastic_info
|
536
|
+
conf = config_element(
|
537
|
+
'ROOT', '', {
|
538
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
539
|
+
'data_stream_name' => 'foo',
|
540
|
+
'data_stream_ilm_name' => "foo_ilm_policy",
|
541
|
+
'data_stream_template_name' => "foo_tpl"
|
542
|
+
})
|
543
|
+
assert_equal "foo", driver(conf).instance.data_stream_name
|
544
|
+
end
|
545
|
+
|
546
|
+
def test_template_unset
|
547
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
548
|
+
|
549
|
+
stub_ilm_policy
|
550
|
+
stub_index_template
|
551
|
+
stub_existent_data_stream?
|
552
|
+
stub_data_stream
|
553
|
+
stub_elastic_info
|
554
|
+
conf = config_element(
|
555
|
+
'ROOT', '', {
|
556
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
557
|
+
'data_stream_name' => 'foo',
|
558
|
+
'data_stream_ilm_name' => "foo_ilm_policy",
|
559
|
+
})
|
560
|
+
assert_equal "foo", driver(conf).instance.data_stream_name
|
561
|
+
assert_equal "foo_ilm_policy", driver(conf).instance.data_stream_ilm_name
|
562
|
+
assert_equal "foo_template", driver(conf).instance.data_stream_template_name
|
563
|
+
end
|
564
|
+
|
565
|
+
def test_ilm_unset
|
566
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
567
|
+
|
568
|
+
stub_ilm_policy
|
569
|
+
stub_index_template
|
570
|
+
stub_existent_data_stream?
|
216
571
|
stub_data_stream
|
572
|
+
stub_elastic_info
|
217
573
|
conf = config_element(
|
218
574
|
'ROOT', '', {
|
219
575
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
220
|
-
'data_stream_name' => 'foo'
|
576
|
+
'data_stream_name' => 'foo',
|
577
|
+
'data_stream_template_name' => "foo_tpl"
|
221
578
|
})
|
222
579
|
assert_equal "foo", driver(conf).instance.data_stream_name
|
580
|
+
assert_equal "foo_tpl", driver(conf).instance.data_stream_template_name
|
581
|
+
end
|
582
|
+
|
583
|
+
def test_template_and_ilm_unset
|
584
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
585
|
+
|
586
|
+
stub_ilm_policy
|
587
|
+
stub_index_template
|
588
|
+
stub_existent_data_stream?
|
589
|
+
stub_data_stream
|
590
|
+
stub_elastic_info
|
591
|
+
conf = config_element(
|
592
|
+
'ROOT', '', {
|
593
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
594
|
+
'data_stream_name' => 'foo',
|
595
|
+
})
|
596
|
+
assert_equal "foo", driver(conf).instance.data_stream_name
|
597
|
+
assert_equal "foo_template", driver(conf).instance.data_stream_template_name
|
598
|
+
assert_equal "foo_policy", driver(conf).instance.data_stream_ilm_name
|
223
599
|
end
|
224
600
|
|
225
601
|
def test_placeholder
|
226
602
|
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
227
603
|
|
228
|
-
|
229
|
-
|
230
|
-
|
604
|
+
dsname = "foo_test"
|
605
|
+
ilmname = "foo_ilm_test"
|
606
|
+
tplname = "foo_tpl_test"
|
607
|
+
stub_default(dsname, ilmname, tplname)
|
608
|
+
stub_bulk_feed(dsname, ilmname, tplname)
|
609
|
+
conf = config_element(
|
610
|
+
'ROOT', '', {
|
611
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
612
|
+
'data_stream_name' => 'foo_${tag}',
|
613
|
+
'data_stream_ilm_name' => "foo_ilm_${tag}",
|
614
|
+
'data_stream_template_name' => "foo_tpl_${tag}"
|
615
|
+
})
|
616
|
+
driver(conf).run(default_tag: 'test') do
|
617
|
+
driver.feed(sample_record)
|
618
|
+
end
|
619
|
+
assert_equal 1, @bulk_records.length
|
620
|
+
end
|
621
|
+
|
622
|
+
def test_placeholder_params_unset
|
623
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
624
|
+
|
625
|
+
dsname = "foo_test"
|
626
|
+
ilmname = "foo_test_policy"
|
627
|
+
tplname = "foo_test_template"
|
628
|
+
stub_default(dsname, ilmname, tplname)
|
629
|
+
stub_bulk_feed(dsname, ilmname, tplname)
|
231
630
|
conf = config_element(
|
232
631
|
'ROOT', '', {
|
233
632
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
234
|
-
'data_stream_name' => 'foo_${tag}'
|
633
|
+
'data_stream_name' => 'foo_${tag}',
|
235
634
|
})
|
236
635
|
driver(conf).run(default_tag: 'test') do
|
237
636
|
driver.feed(sample_record)
|
238
637
|
end
|
239
|
-
assert_equal 1, @bulk_records
|
638
|
+
assert_equal 1, @bulk_records.length
|
240
639
|
end
|
241
640
|
|
641
|
+
|
242
642
|
def test_time_placeholder
|
243
643
|
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
244
644
|
|
245
645
|
time = Time.now
|
246
|
-
|
247
|
-
|
248
|
-
|
646
|
+
dsname = "foo_#{time.strftime("%Y%m%d")}"
|
647
|
+
ilmname = "foo_ilm_#{time.strftime("%Y%m%d")}"
|
648
|
+
tplname = "foo_tpl_#{time.strftime("%Y%m%d")}"
|
649
|
+
stub_default(dsname, ilmname, tplname)
|
650
|
+
stub_bulk_feed(dsname, ilmname, tplname)
|
249
651
|
conf = config_element(
|
250
652
|
'ROOT', '', {
|
251
653
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
252
|
-
'data_stream_name' => 'foo_%Y%m%d'
|
654
|
+
'data_stream_name' => 'foo_%Y%m%d',
|
655
|
+
'data_stream_ilm_name' => 'foo_ilm_%Y%m%d',
|
656
|
+
'data_stream_template_name' => 'foo_tpl_%Y%m%d'
|
253
657
|
}, [config_element('buffer', 'time', {
|
254
658
|
'timekey' => '1d'
|
255
659
|
}, [])]
|
@@ -257,7 +661,7 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
257
661
|
driver(conf).run(default_tag: 'test') do
|
258
662
|
driver.feed(sample_record)
|
259
663
|
end
|
260
|
-
assert_equal 1, @bulk_records
|
664
|
+
assert_equal 1, @bulk_records.length
|
261
665
|
end
|
262
666
|
|
263
667
|
def test_custom_record_placeholder
|
@@ -265,14 +669,18 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
265
669
|
|
266
670
|
keys = ["bar", "baz"]
|
267
671
|
keys.each do |key|
|
268
|
-
|
269
|
-
|
270
|
-
|
672
|
+
dsname = "foo_#{key}"
|
673
|
+
ilmname = "foo_ilm_#{key}"
|
674
|
+
tplname = "foo_tpl_#{key}"
|
675
|
+
stub_default(dsname, ilmname, tplname)
|
676
|
+
stub_bulk_feed(dsname, ilmname, tplname)
|
271
677
|
end
|
272
678
|
conf = config_element(
|
273
679
|
'ROOT', '', {
|
274
680
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
275
|
-
'data_stream_name' => 'foo_${key1}'
|
681
|
+
'data_stream_name' => 'foo_${key1}',
|
682
|
+
'data_stream_ilm_name' => 'foo_ilm_${key1}',
|
683
|
+
'data_stream_template_name' => 'foo_tpl_${key1}'
|
276
684
|
}, [config_element('buffer', 'tag,key1', {
|
277
685
|
'timekey' => '1d'
|
278
686
|
}, [])]
|
@@ -283,7 +691,7 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
283
691
|
driver.feed(record)
|
284
692
|
end
|
285
693
|
end
|
286
|
-
assert_equal keys.count, @bulk_records
|
694
|
+
assert_equal keys.count, @bulk_records.length
|
287
695
|
end
|
288
696
|
|
289
697
|
def test_bulk_insert_feed
|
@@ -294,12 +702,14 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
294
702
|
conf = config_element(
|
295
703
|
'ROOT', '', {
|
296
704
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
297
|
-
'data_stream_name' => 'foo'
|
705
|
+
'data_stream_name' => 'foo',
|
706
|
+
'data_stream_ilm_name' => 'foo_ilm_policy',
|
707
|
+
'data_stream_template_name' => 'foo_tpl'
|
298
708
|
})
|
299
709
|
driver(conf).run(default_tag: 'test') do
|
300
710
|
driver.feed(sample_record)
|
301
711
|
end
|
302
|
-
assert_equal 1, @bulk_records
|
712
|
+
assert_equal 1, @bulk_records.length
|
303
713
|
end
|
304
714
|
|
305
715
|
def test_template_retry_install_fails
|
@@ -309,14 +719,16 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
309
719
|
template_file = File.join(cwd, 'test_index_template.json')
|
310
720
|
|
311
721
|
config = %{
|
312
|
-
host
|
313
|
-
port
|
314
|
-
scheme
|
315
|
-
data_stream_name
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
722
|
+
host logs.google.com
|
723
|
+
port 778
|
724
|
+
scheme https
|
725
|
+
data_stream_name foo
|
726
|
+
data_stream_ilm_name foo_ilm_policy
|
727
|
+
data_stream_template_name foo_tpl
|
728
|
+
user john
|
729
|
+
password doe
|
730
|
+
template_name logstash
|
731
|
+
template_file #{template_file}
|
320
732
|
max_retry_putting_template 3
|
321
733
|
}
|
322
734
|
|
@@ -327,6 +739,7 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
327
739
|
connection_resets += 1
|
328
740
|
raise Faraday::ConnectionFailed, "Test message"
|
329
741
|
end
|
742
|
+
stub_elastic_info("https://logs.google.com:778/")
|
330
743
|
|
331
744
|
assert_raise(Fluent::Plugin::ElasticsearchError::RetryableOperationExhaustedFailure) do
|
332
745
|
driver(config)
|
@@ -334,4 +747,191 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
334
747
|
|
335
748
|
assert_equal(4, connection_resets)
|
336
749
|
end
|
750
|
+
|
751
|
+
def test_doesnt_update_ilm_policy_if_overwrite_unset
|
752
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
753
|
+
|
754
|
+
config = %{
|
755
|
+
data_stream_name foo
|
756
|
+
data_stream_ilm_name foo_ilm_policy
|
757
|
+
data_stream_ilm_policy {"policy":{"phases":{"hot":{"actions":{"rollover":{"max_age":"15d"}}}}}}
|
758
|
+
}
|
759
|
+
|
760
|
+
stub_elastic_info
|
761
|
+
stub_index_template
|
762
|
+
stub_existent_data_stream?
|
763
|
+
stub_existent_ilm?
|
764
|
+
stub_data_stream
|
765
|
+
|
766
|
+
stub_request(:put, "http://localhost:9200/#{ilm_endpoint}/policy/foo_ilm_policy").
|
767
|
+
to_return(:status => 200, :body => "", :headers => {})
|
768
|
+
|
769
|
+
assert_nothing_raised {
|
770
|
+
driver(config)
|
771
|
+
}
|
772
|
+
assert_requested(:put, "http://localhost:9200/#{ilm_endpoint}/policy/foo_ilm_policy", times: 0)
|
773
|
+
end
|
774
|
+
|
775
|
+
def test_updates_ilm_policy_if_overwrite_set
|
776
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
777
|
+
|
778
|
+
config = %{
|
779
|
+
data_stream_name foo
|
780
|
+
data_stream_ilm_name foo_ilm_policy
|
781
|
+
data_stream_ilm_policy {"policy":{"phases":{"hot":{"actions":{"rollover":{"max_age":"15d"}}}}}}
|
782
|
+
data_stream_ilm_policy_overwrite true
|
783
|
+
}
|
784
|
+
|
785
|
+
stub_elastic_info
|
786
|
+
stub_index_template
|
787
|
+
stub_existent_data_stream?
|
788
|
+
stub_existent_ilm?
|
789
|
+
stub_data_stream
|
790
|
+
|
791
|
+
stub_request(:put, "http://localhost:9200/#{ilm_endpoint}/policy/foo_ilm_policy").
|
792
|
+
to_return(:status => 200, :body => "", :headers => {})
|
793
|
+
|
794
|
+
assert_nothing_raised {
|
795
|
+
driver(config)
|
796
|
+
}
|
797
|
+
|
798
|
+
assert_requested(:put, "http://localhost:9200/#{ilm_endpoint}/policy/foo_ilm_policy", times: 1)
|
799
|
+
assert_requested(:put, "http://localhost:9200/#{ilm_endpoint}/policy/foo_ilm_policy",
|
800
|
+
body: '{"policy":{"phases":{"hot":{"actions":{"rollover":{"max_age":"15d"}}}}}}',
|
801
|
+
times: 1)
|
802
|
+
end
|
803
|
+
|
804
|
+
def test_creates_custom_ilm_policy_if_none_exists
|
805
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
806
|
+
|
807
|
+
config = %{
|
808
|
+
data_stream_name foo
|
809
|
+
data_stream_ilm_name foo_ilm_policy
|
810
|
+
data_stream_ilm_policy {"policy":{"phases":{"hot":{"actions":{"rollover":{"max_age":"15d"}}}}}}
|
811
|
+
}
|
812
|
+
|
813
|
+
stub_elastic_info
|
814
|
+
stub_index_template("foo_template")
|
815
|
+
stub_data_stream
|
816
|
+
stub_nonexistent_data_stream?
|
817
|
+
stub_nonexistent_ilm?
|
818
|
+
stub_nonexistent_template?("foo_template")
|
819
|
+
|
820
|
+
stub_request(:put, "http://localhost:9200/#{ilm_endpoint}/policy/foo_ilm_policy").
|
821
|
+
to_return(:status => 200, :body => "", :headers => {})
|
822
|
+
|
823
|
+
assert_nothing_raised {
|
824
|
+
driver(config)
|
825
|
+
}
|
826
|
+
|
827
|
+
assert_requested(:put, "http://localhost:9200/#{ilm_endpoint}/policy/foo_ilm_policy", times: 1)
|
828
|
+
assert_requested(:put, "http://localhost:9200/#{ilm_endpoint}/policy/foo_ilm_policy",
|
829
|
+
body: '{"policy":{"phases":{"hot":{"actions":{"rollover":{"max_age":"15d"}}}}}}',
|
830
|
+
times: 1)
|
831
|
+
end
|
832
|
+
|
833
|
+
def test_doesnt_add_tag_key_when_not_configured
|
834
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
835
|
+
|
836
|
+
config = %{
|
837
|
+
data_stream_name foo
|
838
|
+
data_stream_template_name foo_tpl
|
839
|
+
data_stream_ilm_name foo_ilm_policy
|
840
|
+
}
|
841
|
+
|
842
|
+
stub_default
|
843
|
+
stub_bulk_feed
|
844
|
+
driver(config)
|
845
|
+
driver.run(default_tag: 'mytag') do
|
846
|
+
driver.feed(sample_record)
|
847
|
+
end
|
848
|
+
|
849
|
+
assert_equal(1, @bulk_records.length)
|
850
|
+
assert_false(@bulk_records[0].has_key?('tag'))
|
851
|
+
end
|
852
|
+
|
853
|
+
|
854
|
+
def test_adds_tag_key_when_configured
|
855
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
856
|
+
|
857
|
+
config = %{
|
858
|
+
data_stream_name foo
|
859
|
+
data_stream_template_name foo_tpl
|
860
|
+
data_stream_ilm_name foo_ilm_policy
|
861
|
+
include_tag_key true
|
862
|
+
}
|
863
|
+
|
864
|
+
stub_default
|
865
|
+
stub_bulk_feed
|
866
|
+
driver(config)
|
867
|
+
driver.run(default_tag: 'mytag') do
|
868
|
+
driver.feed(sample_record)
|
869
|
+
end
|
870
|
+
|
871
|
+
assert_equal(1, @bulk_records.length)
|
872
|
+
assert(@bulk_records[0].has_key?('tag'))
|
873
|
+
assert_equal('mytag', @bulk_records[0]['tag'])
|
874
|
+
end
|
875
|
+
|
876
|
+
def test_adds_custom_tag_key_when_configured
|
877
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
878
|
+
|
879
|
+
config = %{
|
880
|
+
data_stream_name foo
|
881
|
+
data_stream_template_name foo_tpl
|
882
|
+
data_stream_ilm_name foo_ilm_policy
|
883
|
+
include_tag_key true
|
884
|
+
tag_key custom_tag_key
|
885
|
+
}
|
886
|
+
|
887
|
+
stub_default
|
888
|
+
stub_bulk_feed
|
889
|
+
driver(config)
|
890
|
+
driver.run(default_tag: 'mytag') do
|
891
|
+
driver.feed(sample_record)
|
892
|
+
end
|
893
|
+
|
894
|
+
assert_equal(1, @bulk_records.length)
|
895
|
+
assert(@bulk_records[0].has_key?('custom_tag_key'))
|
896
|
+
assert_equal('mytag', @bulk_records[0]['custom_tag_key'])
|
897
|
+
end
|
898
|
+
|
899
|
+
def test_use_record_timestamp_if_present
|
900
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
901
|
+
|
902
|
+
stub_default
|
903
|
+
stub_bulk_feed
|
904
|
+
conf = config_element(
|
905
|
+
'ROOT', '', {
|
906
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
907
|
+
'data_stream_name' => 'foo',
|
908
|
+
'data_stream_ilm_name' => 'foo_ilm_policy',
|
909
|
+
'data_stream_template_name' => 'foo_tpl'
|
910
|
+
})
|
911
|
+
driver(conf).run(default_tag: 'test') do
|
912
|
+
driver.feed(sample_record)
|
913
|
+
end
|
914
|
+
assert_equal 1, @bulk_records.length
|
915
|
+
assert(@bulk_records[0].has_key?('@timestamp'))
|
916
|
+
assert_equal SAMPLE_RECORD_TIMESTAMP, @bulk_records[0]['@timestamp']
|
917
|
+
end
|
918
|
+
|
919
|
+
def test_add_timestamp_if_not_present_in_record
|
920
|
+
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
921
|
+
|
922
|
+
stub_default
|
923
|
+
stub_bulk_feed
|
924
|
+
conf = config_element(
|
925
|
+
'ROOT', '', {
|
926
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
927
|
+
'data_stream_name' => 'foo',
|
928
|
+
'data_stream_ilm_name' => 'foo_ilm_policy',
|
929
|
+
'data_stream_template_name' => 'foo_tpl'
|
930
|
+
})
|
931
|
+
driver(conf).run(default_tag: 'test') do
|
932
|
+
driver.feed(sample_record_no_timestamp)
|
933
|
+
end
|
934
|
+
assert_equal 1, @bulk_records.length
|
935
|
+
assert(@bulk_records[0].has_key?('@timestamp'))
|
936
|
+
end
|
337
937
|
end
|