fluent-plugin-elasticsearch-sm 1.4.1

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.
@@ -0,0 +1,537 @@
1
+ require 'helper'
2
+ require 'date'
3
+
4
+ class ElasticsearchOutputDynamic < Test::Unit::TestCase
5
+ attr_accessor :index_cmds, :index_command_counts
6
+
7
+ def setup
8
+ Fluent::Test.setup
9
+ require 'fluent/plugin/out_elasticsearch_dynamic'
10
+ @driver = nil
11
+ end
12
+
13
+ def driver(tag='test', conf='')
14
+ @driver ||= Fluent::Test::BufferedOutputTestDriver.new(Fluent::ElasticsearchOutputDynamic, tag).configure(conf)
15
+ end
16
+
17
+ def sample_record
18
+ {'age' => 26, 'request_id' => '42', 'parent_id' => 'parent', 'routing_id' => 'routing'}
19
+ end
20
+
21
+ def stub_elastic_ping(url="http://localhost:9200")
22
+ stub_request(:head, url).to_return(:status => 200, :body => "", :headers => {})
23
+ end
24
+
25
+ def stub_elastic(url="http://localhost:9200/_bulk")
26
+ stub_request(:post, url).with do |req|
27
+ @index_cmds = req.body.split("\n").map {|r| JSON.parse(r) }
28
+ end
29
+ end
30
+
31
+ def stub_elastic_unavailable(url="http://localhost:9200/_bulk")
32
+ stub_request(:post, url).to_return(:status => [503, "Service Unavailable"])
33
+ end
34
+
35
+ def stub_elastic_with_store_index_command_counts(url="http://localhost:9200/_bulk")
36
+ if @index_command_counts == nil
37
+ @index_command_counts = {}
38
+ @index_command_counts.default = 0
39
+ end
40
+
41
+ stub_request(:post, url).with do |req|
42
+ index_cmds = req.body.split("\n").map {|r| JSON.parse(r) }
43
+ @index_command_counts[url] += index_cmds.size
44
+ end
45
+ end
46
+
47
+ def test_configure
48
+ config = %{
49
+ host logs.google.com
50
+ port 777
51
+ scheme https
52
+ path /es/
53
+ user john
54
+ password doe
55
+ }
56
+ instance = driver('test', config).instance
57
+
58
+ assert_equal 'logs.google.com', instance.host
59
+ assert_equal "777", instance.port
60
+ assert_equal 'https', instance.scheme
61
+ assert_equal '/es/', instance.path
62
+ assert_equal 'john', instance.user
63
+ assert_equal 'doe', instance.password
64
+ end
65
+
66
+ def test_legacy_hosts_list
67
+ config = %{
68
+ hosts host1:50,host2:100,host3
69
+ scheme https
70
+ path /es/
71
+ port 123
72
+ }
73
+ instance = driver('test', config).instance
74
+
75
+ assert_equal 3, instance.get_connection_options(nil)[:hosts].length
76
+ host1, host2, host3 = instance.get_connection_options(nil)[:hosts]
77
+
78
+ assert_equal 'host1', host1[:host]
79
+ assert_equal 50, host1[:port]
80
+ assert_equal 'https', host1[:scheme]
81
+ assert_equal '/es/', host2[:path]
82
+ assert_equal 'host3', host3[:host]
83
+ assert_equal 123, host3[:port]
84
+ assert_equal 'https', host3[:scheme]
85
+ assert_equal '/es/', host3[:path]
86
+ end
87
+
88
+ def test_hosts_list
89
+ config = %{
90
+ hosts https://john:password@host1:443/elastic/,http://host2
91
+ path /default_path
92
+ user default_user
93
+ password default_password
94
+ }
95
+ instance = driver('test', config).instance
96
+
97
+ assert_equal 2, instance.get_connection_options(nil)[:hosts].length
98
+ host1, host2 = instance.get_connection_options(nil)[:hosts]
99
+
100
+ assert_equal 'host1', host1[:host]
101
+ assert_equal 443, host1[:port]
102
+ assert_equal 'https', host1[:scheme]
103
+ assert_equal 'john', host1[:user]
104
+ assert_equal 'password', host1[:password]
105
+ assert_equal '/elastic/', host1[:path]
106
+
107
+ assert_equal 'host2', host2[:host]
108
+ assert_equal 'http', host2[:scheme]
109
+ assert_equal 'default_user', host2[:user]
110
+ assert_equal 'default_password', host2[:password]
111
+ assert_equal '/default_path', host2[:path]
112
+ end
113
+
114
+ def test_single_host_params_and_defaults
115
+ config = %{
116
+ host logs.google.com
117
+ user john
118
+ password doe
119
+ }
120
+ instance = driver('test', config).instance
121
+
122
+ assert_equal 1, instance.get_connection_options(nil)[:hosts].length
123
+ host1 = instance.get_connection_options(nil)[:hosts][0]
124
+
125
+ assert_equal 'logs.google.com', host1[:host]
126
+ assert_equal 9200, host1[:port]
127
+ assert_equal 'http', host1[:scheme]
128
+ assert_equal 'john', host1[:user]
129
+ assert_equal 'doe', host1[:password]
130
+ assert_equal nil, host1[:path]
131
+ end
132
+
133
+ def test_writes_to_default_index
134
+ stub_elastic_ping
135
+ stub_elastic
136
+ driver.emit(sample_record)
137
+ driver.run
138
+ assert_equal('fluentd', index_cmds.first['index']['_index'])
139
+ end
140
+
141
+ def test_writes_to_default_type
142
+ stub_elastic_ping
143
+ stub_elastic
144
+ driver.emit(sample_record)
145
+ driver.run
146
+ assert_equal('fluentd', index_cmds.first['index']['_type'])
147
+ end
148
+
149
+ def test_writes_to_speficied_index
150
+ driver.configure("index_name myindex\n")
151
+ stub_elastic_ping
152
+ stub_elastic
153
+ driver.emit(sample_record)
154
+ driver.run
155
+ assert_equal('myindex', index_cmds.first['index']['_index'])
156
+ end
157
+
158
+ def test_writes_to_speficied_type
159
+ driver.configure("type_name mytype\n")
160
+ stub_elastic_ping
161
+ stub_elastic
162
+ driver.emit(sample_record)
163
+ driver.run
164
+ assert_equal('mytype', index_cmds.first['index']['_type'])
165
+ end
166
+
167
+ def test_writes_to_speficied_host
168
+ driver.configure("host 192.168.33.50\n")
169
+ stub_elastic_ping("http://192.168.33.50:9200")
170
+ elastic_request = stub_elastic("http://192.168.33.50:9200/_bulk")
171
+ driver.emit(sample_record)
172
+ driver.run
173
+ assert_requested(elastic_request)
174
+ end
175
+
176
+ def test_writes_to_speficied_port
177
+ driver.configure("port 9201\n")
178
+ stub_elastic_ping("http://localhost:9201")
179
+ elastic_request = stub_elastic("http://localhost:9201/_bulk")
180
+ driver.emit(sample_record)
181
+ driver.run
182
+ assert_requested(elastic_request)
183
+ end
184
+
185
+ def test_writes_to_multi_hosts
186
+ hosts = [['192.168.33.50', 9201], ['192.168.33.51', 9201], ['192.168.33.52', 9201]]
187
+ hosts_string = hosts.map {|x| "#{x[0]}:#{x[1]}"}.compact.join(',')
188
+
189
+ driver.configure("hosts #{hosts_string}")
190
+
191
+ hosts.each do |host_info|
192
+ host, port = host_info
193
+ stub_elastic_ping("http://#{host}:#{port}")
194
+ stub_elastic_with_store_index_command_counts("http://#{host}:#{port}/_bulk")
195
+ end
196
+
197
+ 1000.times do
198
+ driver.emit(sample_record.merge('age'=>rand(100)))
199
+ end
200
+
201
+ driver.run
202
+
203
+ # @note: we cannot make multi chunks with options (flush_interval, buffer_chunk_limit)
204
+ # it's Fluentd test driver's constraint
205
+ # so @index_command_counts.size is always 1
206
+
207
+ assert(@index_command_counts.size > 0, "not working with hosts options")
208
+
209
+ total = 0
210
+ @index_command_counts.each do |url, count|
211
+ total += count
212
+ end
213
+ assert_equal(2000, total)
214
+ end
215
+
216
+ def test_makes_bulk_request
217
+ stub_elastic_ping
218
+ stub_elastic
219
+ driver.emit(sample_record)
220
+ driver.emit(sample_record.merge('age' => 27))
221
+ driver.run
222
+ assert_equal(4, index_cmds.count)
223
+ end
224
+
225
+ def test_all_records_are_preserved_in_bulk
226
+ stub_elastic_ping
227
+ stub_elastic
228
+ driver.emit(sample_record)
229
+ driver.emit(sample_record.merge('age' => 27))
230
+ driver.run
231
+ assert_equal(26, index_cmds[1]['age'])
232
+ assert_equal(27, index_cmds[3]['age'])
233
+ end
234
+
235
+ def test_writes_to_logstash_index
236
+ driver.configure("logstash_format true\n")
237
+ time = Time.parse Date.today.to_s
238
+ logstash_index = "logstash-#{time.getutc.strftime("%Y.%m.%d")}"
239
+ stub_elastic_ping
240
+ stub_elastic
241
+ driver.emit(sample_record, time)
242
+ driver.run
243
+ assert_equal(logstash_index, index_cmds.first['index']['_index'])
244
+ end
245
+
246
+ def test_writes_to_logstash_utc_index
247
+ driver.configure("logstash_format true
248
+ utc_index false")
249
+ time = Time.parse Date.today.to_s
250
+ utc_index = "logstash-#{time.strftime("%Y.%m.%d")}"
251
+ stub_elastic_ping
252
+ stub_elastic
253
+ driver.emit(sample_record, time)
254
+ driver.run
255
+ assert_equal(utc_index, index_cmds.first['index']['_index'])
256
+ end
257
+
258
+ def test_writes_to_logstash_index_with_specified_prefix
259
+ driver.configure("logstash_format true
260
+ logstash_prefix myprefix")
261
+ time = Time.parse Date.today.to_s
262
+ logstash_index = "myprefix-#{time.getutc.strftime("%Y.%m.%d")}"
263
+ stub_elastic_ping
264
+ stub_elastic
265
+ driver.emit(sample_record, time)
266
+ driver.run
267
+ assert_equal(logstash_index, index_cmds.first['index']['_index'])
268
+ end
269
+
270
+ def test_writes_to_logstash_index_with_specified_dateformat
271
+ driver.configure("logstash_format true
272
+ logstash_dateformat %Y.%m")
273
+ time = Time.parse Date.today.to_s
274
+ logstash_index = "logstash-#{time.getutc.strftime("%Y.%m")}"
275
+ stub_elastic_ping
276
+ stub_elastic
277
+ driver.emit(sample_record, time)
278
+ driver.run
279
+ assert_equal(logstash_index, index_cmds.first['index']['_index'])
280
+ end
281
+
282
+ def test_writes_to_logstash_index_with_specified_prefix_and_dateformat
283
+ driver.configure("logstash_format true
284
+ logstash_prefix myprefix
285
+ logstash_dateformat %Y.%m")
286
+ time = Time.parse Date.today.to_s
287
+ logstash_index = "myprefix-#{time.getutc.strftime("%Y.%m")}"
288
+ stub_elastic_ping
289
+ stub_elastic
290
+ driver.emit(sample_record, time)
291
+ driver.run
292
+ assert_equal(logstash_index, index_cmds.first['index']['_index'])
293
+ end
294
+
295
+ def test_doesnt_add_logstash_timestamp_by_default
296
+ stub_elastic_ping
297
+ stub_elastic
298
+ driver.emit(sample_record)
299
+ driver.run
300
+ assert_nil(index_cmds[1]['@timestamp'])
301
+ end
302
+
303
+ def test_adds_logstash_timestamp_when_configured
304
+ driver.configure("logstash_format true\n")
305
+ stub_elastic_ping
306
+ stub_elastic
307
+ ts = DateTime.now.to_s
308
+ driver.emit(sample_record)
309
+ driver.run
310
+ assert(index_cmds[1].has_key? '@timestamp')
311
+ assert_equal(index_cmds[1]['@timestamp'], ts)
312
+ end
313
+
314
+ def test_uses_custom_timestamp_when_included_in_record
315
+ driver.configure("logstash_format true\n")
316
+ stub_elastic_ping
317
+ stub_elastic
318
+ ts = DateTime.new(2001,2,3).to_s
319
+ driver.emit(sample_record.merge!('@timestamp' => ts))
320
+ driver.run
321
+ assert(index_cmds[1].has_key? '@timestamp')
322
+ assert_equal(index_cmds[1]['@timestamp'], ts)
323
+ end
324
+
325
+ def test_uses_custom_time_key
326
+ driver.configure("logstash_format true
327
+ time_key vtm\n")
328
+ stub_elastic_ping
329
+ stub_elastic
330
+ ts = DateTime.new(2001,2,3).to_s
331
+ driver.emit(sample_record.merge!('vtm' => ts))
332
+ driver.run
333
+ assert(index_cmds[1].has_key? '@timestamp')
334
+ assert_equal(index_cmds[1]['@timestamp'], ts)
335
+ end
336
+
337
+ def test_uses_custom_time_key_exclude_timestamp
338
+ driver.configure("logstash_format true
339
+ time_key vtm
340
+ time_key_exclude_timestamp true\n")
341
+ stub_elastic_ping
342
+ stub_elastic
343
+ ts = DateTime.new(2001,2,3).to_s
344
+ driver.emit(sample_record.merge!('vtm' => ts))
345
+ driver.run
346
+ assert(!index_cmds[1].key?('@timestamp'), '@timestamp should be missing')
347
+ end
348
+
349
+ def test_doesnt_add_tag_key_by_default
350
+ stub_elastic_ping
351
+ stub_elastic
352
+ driver.emit(sample_record)
353
+ driver.run
354
+ assert_nil(index_cmds[1]['tag'])
355
+ end
356
+
357
+ def test_adds_tag_key_when_configured
358
+ driver('mytag').configure("include_tag_key true\n")
359
+ stub_elastic_ping
360
+ stub_elastic
361
+ driver.emit(sample_record)
362
+ driver.run
363
+ assert(index_cmds[1].has_key?('tag'))
364
+ assert_equal(index_cmds[1]['tag'], 'mytag')
365
+ end
366
+
367
+ def test_adds_id_key_when_configured
368
+ driver.configure("id_key request_id\n")
369
+ stub_elastic_ping
370
+ stub_elastic
371
+ driver.emit(sample_record)
372
+ driver.run
373
+ assert_equal(index_cmds[0]['index']['_id'], '42')
374
+ end
375
+
376
+ def test_doesnt_add_id_key_if_missing_when_configured
377
+ driver.configure("id_key another_request_id\n")
378
+ stub_elastic_ping
379
+ stub_elastic
380
+ driver.emit(sample_record)
381
+ driver.run
382
+ assert(!index_cmds[0]['index'].has_key?('_id'))
383
+ end
384
+
385
+ def test_adds_id_key_when_not_configured
386
+ stub_elastic_ping
387
+ stub_elastic
388
+ driver.emit(sample_record)
389
+ driver.run
390
+ assert(!index_cmds[0]['index'].has_key?('_id'))
391
+ end
392
+
393
+ def test_adds_parent_key_when_configured
394
+ driver.configure("parent_key parent_id\n")
395
+ stub_elastic_ping
396
+ stub_elastic
397
+ driver.emit(sample_record)
398
+ driver.run
399
+ assert_equal(index_cmds[0]['index']['_parent'], 'parent')
400
+ end
401
+
402
+ def test_doesnt_add_parent_key_if_missing_when_configured
403
+ driver.configure("parent_key another_parent_id\n")
404
+ stub_elastic_ping
405
+ stub_elastic
406
+ driver.emit(sample_record)
407
+ driver.run
408
+ assert(!index_cmds[0]['index'].has_key?('_parent'))
409
+ end
410
+
411
+ def test_adds_parent_key_when_not_configured
412
+ stub_elastic_ping
413
+ stub_elastic
414
+ driver.emit(sample_record)
415
+ driver.run
416
+ assert(!index_cmds[0]['index'].has_key?('_parent'))
417
+ end
418
+
419
+ def test_adds_routing_key_when_configured
420
+ driver.configure("routing_key routing_id\n")
421
+ stub_elastic_ping
422
+ stub_elastic
423
+ driver.emit(sample_record)
424
+ driver.run
425
+ assert_equal(index_cmds[0]['index']['_routing'], 'routing')
426
+ end
427
+
428
+ def test_doesnt_add_routing_key_if_missing_when_configured
429
+ driver.configure("routing_key another_routing_id\n")
430
+ stub_elastic_ping
431
+ stub_elastic
432
+ driver.emit(sample_record)
433
+ driver.run
434
+ assert(!index_cmds[0]['index'].has_key?('_routing'))
435
+ end
436
+
437
+ def test_adds_routing_key_when_not_configured
438
+ stub_elastic_ping
439
+ stub_elastic
440
+ driver.emit(sample_record)
441
+ driver.run
442
+ assert(!index_cmds[0]['index'].has_key?('_routing'))
443
+ end
444
+ def test_request_error
445
+ stub_elastic_ping
446
+ stub_elastic_unavailable
447
+ driver.emit(sample_record)
448
+ assert_raise(Elasticsearch::Transport::Transport::Errors::ServiceUnavailable) {
449
+ driver.run
450
+ }
451
+ end
452
+
453
+ def test_garbage_record_error
454
+ stub_elastic_ping
455
+ stub_elastic
456
+ driver.emit("some garbage string")
457
+ driver.run
458
+ end
459
+
460
+ def test_connection_failed_retry
461
+ connection_resets = 0
462
+
463
+ stub_elastic_ping(url="http://localhost:9200").with do |req|
464
+ connection_resets += 1
465
+ end
466
+
467
+ stub_request(:post, "http://localhost:9200/_bulk").with do |req|
468
+ raise Faraday::ConnectionFailed, "Test message"
469
+ end
470
+
471
+ driver.emit(sample_record)
472
+
473
+ assert_raise(Fluent::ElasticsearchOutput::ConnectionFailure) {
474
+ driver.run
475
+ }
476
+ assert_equal(connection_resets, 3)
477
+ end
478
+
479
+ def test_update_should_not_write_if_theres_no_id
480
+ driver.configure("write_operation update\n")
481
+ stub_elastic_ping
482
+ stub_elastic
483
+ driver.emit(sample_record)
484
+ driver.run
485
+ assert_nil(index_cmds)
486
+ end
487
+
488
+ def test_upsert_should_not_write_if_theres_no_id
489
+ driver.configure("write_operation upsert\n")
490
+ stub_elastic_ping
491
+ stub_elastic
492
+ driver.emit(sample_record)
493
+ driver.run
494
+ assert_nil(index_cmds)
495
+ end
496
+
497
+ def test_create_should_not_write_if_theres_no_id
498
+ driver.configure("write_operation create\n")
499
+ stub_elastic_ping
500
+ stub_elastic
501
+ driver.emit(sample_record)
502
+ driver.run
503
+ assert_nil(index_cmds)
504
+ end
505
+
506
+ def test_update_should_write_update_op_and_doc_as_upsert_is_false
507
+ driver.configure("write_operation update
508
+ id_key request_id")
509
+ stub_elastic_ping
510
+ stub_elastic
511
+ driver.emit(sample_record)
512
+ driver.run
513
+ assert(index_cmds[0].has_key?("update"))
514
+ assert(!index_cmds[1]["doc_as_upsert"])
515
+ end
516
+
517
+ def test_upsert_should_write_update_op_and_doc_as_upsert_is_true
518
+ driver.configure("write_operation upsert
519
+ id_key request_id")
520
+ stub_elastic_ping
521
+ stub_elastic
522
+ driver.emit(sample_record)
523
+ driver.run
524
+ assert(index_cmds[0].has_key?("update"))
525
+ assert(index_cmds[1]["doc_as_upsert"])
526
+ end
527
+
528
+ def test_create_should_write_create_op
529
+ driver.configure("write_operation create
530
+ id_key request_id")
531
+ stub_elastic_ping
532
+ stub_elastic
533
+ driver.emit(sample_record)
534
+ driver.run
535
+ assert(index_cmds[0].has_key?("create"))
536
+ end
537
+ end