logstash-output-elasticsearch 0.2.8-java → 0.2.9-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,51 @@
1
+ require_relative "../../../spec/es_spec_helper"
2
+
3
+ describe "SSL option" do
4
+ ["node", "transport"].each do |protocol|
5
+ context "with protocol => #{protocol}" do
6
+ subject do
7
+ require "logstash/outputs/elasticsearch"
8
+ settings = {
9
+ "protocol" => protocol,
10
+ "node_name" => "logstash",
11
+ "cluster" => "elasticsearch",
12
+ "host" => "node01",
13
+ "ssl" => true
14
+ }
15
+ next LogStash::Outputs::ElasticSearch.new(settings)
16
+ end
17
+
18
+ it "should fail in register" do
19
+ expect {subject.register}.to raise_error
20
+ end
21
+ end
22
+ end
23
+
24
+ context "when using http protocol" do
25
+ protocol = "http"
26
+ context "when using ssl without cert verification" do
27
+ subject do
28
+ require "logstash/outputs/elasticsearch"
29
+ settings = {
30
+ "protocol" => protocol,
31
+ "host" => "node01",
32
+ "ssl" => true,
33
+ "ssl_certificate_verification" => false
34
+ }
35
+ next LogStash::Outputs::ElasticSearch.new(settings)
36
+ end
37
+
38
+ it "should pass the flag to the ES client" do
39
+ expect(::Elasticsearch::Client).to receive(:new) do |args|
40
+ expect(args[:ssl]).to eq(:verify => false)
41
+ end
42
+ subject.register
43
+ end
44
+
45
+ it "print a warning" do
46
+ expect(subject.logger).to receive(:warn)
47
+ subject.register
48
+ end
49
+ end
50
+ end
51
+ end
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: 0.2.8
4
+ version: 0.2.9
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-12 00:00:00.000000000 Z
11
+ date: 2015-06-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -154,6 +154,20 @@ dependencies:
154
154
  version: '0'
155
155
  prerelease: false
156
156
  type: :development
157
+ - !ruby/object:Gem::Dependency
158
+ name: longshoreman
159
+ version_requirements: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirement: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - '>='
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ prerelease: false
170
+ type: :development
157
171
  description: Output events to elasticsearch
158
172
  email: info@elastic.co
159
173
  executables: []
@@ -165,6 +179,7 @@ files:
165
179
  - CONTRIBUTORS
166
180
  - Gemfile
167
181
  - LICENSE
182
+ - NOTICE.TXT
168
183
  - README.md
169
184
  - Rakefile
170
185
  - lib/logstash-output-elasticsearch_jars.rb
@@ -172,8 +187,17 @@ files:
172
187
  - lib/logstash/outputs/elasticsearch/elasticsearch-template.json
173
188
  - lib/logstash/outputs/elasticsearch/protocol.rb
174
189
  - logstash-output-elasticsearch.gemspec
175
- - spec/outputs/elasticsearch/protocol_spec.rb
176
- - spec/outputs/elasticsearch_spec.rb
190
+ - spec/es_spec_helper.rb
191
+ - spec/integration/outputs/elasticsearch/node_spec.rb
192
+ - spec/integration/outputs/index_spec.rb
193
+ - spec/integration/outputs/retry_spec.rb
194
+ - spec/integration/outputs/routing_spec.rb
195
+ - spec/integration/outputs/secure_spec.rb
196
+ - spec/integration/outputs/templates_spec.rb
197
+ - spec/integration/outputs/transport_create_spec.rb
198
+ - spec/unit/outputs/elasticsearch/protocol_spec.rb
199
+ - spec/unit/outputs/elasticsearch_spec.rb
200
+ - spec/unit/outputs/elasticsearch_ssl_spec.rb
177
201
  - vendor/jar-dependencies/runtime-jars/antlr-runtime-3.5.jar
178
202
  - vendor/jar-dependencies/runtime-jars/asm-4.1.jar
179
203
  - vendor/jar-dependencies/runtime-jars/asm-commons-4.1.jar
@@ -218,5 +242,14 @@ signing_key:
218
242
  specification_version: 4
219
243
  summary: Logstash Output to Elasticsearch
220
244
  test_files:
221
- - spec/outputs/elasticsearch/protocol_spec.rb
222
- - spec/outputs/elasticsearch_spec.rb
245
+ - spec/es_spec_helper.rb
246
+ - spec/integration/outputs/elasticsearch/node_spec.rb
247
+ - spec/integration/outputs/index_spec.rb
248
+ - spec/integration/outputs/retry_spec.rb
249
+ - spec/integration/outputs/routing_spec.rb
250
+ - spec/integration/outputs/secure_spec.rb
251
+ - spec/integration/outputs/templates_spec.rb
252
+ - spec/integration/outputs/transport_create_spec.rb
253
+ - spec/unit/outputs/elasticsearch/protocol_spec.rb
254
+ - spec/unit/outputs/elasticsearch_spec.rb
255
+ - spec/unit/outputs/elasticsearch_ssl_spec.rb
@@ -1,1059 +0,0 @@
1
- require "logstash/devutils/rspec/spec_helper"
2
- require "ftw"
3
- require "logstash/plugin"
4
- require "logstash/json"
5
- require "stud/try"
6
-
7
- describe "outputs/elasticsearch" do
8
-
9
- context "registration" do
10
-
11
- it "should register" do
12
- output = LogStash::Plugin.lookup("output", "elasticsearch").new("embedded" => "false", "protocol" => "transport", "manage_template" => "false")
13
-
14
- # register will try to load jars and raise if it cannot find jars
15
- expect {output.register}.to_not raise_error
16
- end
17
-
18
- it "should fail to register when protocol => http, action => create_unless_exists" do
19
- output = LogStash::Plugin.lookup("output", "elasticsearch").new("protocol" => "http", "action" => "create_unless_exists")
20
-
21
- expect {output.register}.to raise_error
22
- end
23
- end
24
-
25
- describe "ship lots of events w/ default index_type", :elasticsearch => true do
26
- # Generate a random index name
27
- index = 10.times.collect { rand(10).to_s }.join("")
28
- type = 10.times.collect { rand(10).to_s }.join("")
29
-
30
- # Write about 10000 events. Add jitter to increase likeliness of finding
31
- # boundary-related bugs.
32
- event_count = 10000 + rand(500)
33
- flush_size = rand(200) + 1
34
-
35
- config <<-CONFIG
36
- input {
37
- generator {
38
- message => "hello world"
39
- count => #{event_count}
40
- type => "#{type}"
41
- }
42
- }
43
- output {
44
- elasticsearch {
45
- host => "127.0.0.1"
46
- index => "#{index}"
47
- flush_size => #{flush_size}
48
- }
49
- }
50
- CONFIG
51
-
52
- agent do
53
- # Try a few times to check if we have the correct number of events stored
54
- # in ES.
55
- #
56
- # We try multiple times to allow final agent flushes as well as allowing
57
- # elasticsearch to finish processing everything.
58
- ftw = FTW::Agent.new
59
- ftw.post!("http://localhost:9200/#{index}/_refresh")
60
-
61
- # Wait until all events are available.
62
- Stud::try(10.times) do
63
- data = ""
64
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*")
65
- response.read_body { |chunk| data << chunk }
66
- result = LogStash::Json.load(data)
67
- count = result["count"]
68
- insist { count } == event_count
69
- end
70
-
71
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_search?q=*&size=1000")
72
- data = ""
73
- response.read_body { |chunk| data << chunk }
74
- result = LogStash::Json.load(data)
75
- result["hits"]["hits"].each do |doc|
76
- # With no 'index_type' set, the document type should be the type
77
- # set on the input
78
- insist { doc["_type"] } == type
79
- insist { doc["_index"] } == index
80
- insist { doc["_source"]["message"] } == "hello world"
81
- end
82
- end
83
- end
84
-
85
- describe "ship lots of events w/ default index_type and fixed routing key using http protocol", :elasticsearch => true do
86
- # Generate a random index name
87
- index = 10.times.collect { rand(10).to_s }.join("")
88
- type = 10.times.collect { rand(10).to_s }.join("")
89
-
90
- # Write 900 events so that we can verify these have been routed correctly.
91
- event_count = 900
92
- flush_size = rand(200) + 1
93
-
94
- config <<-CONFIG
95
- input {
96
- generator {
97
- message => "hello world"
98
- count => #{event_count}
99
- type => "#{type}"
100
- }
101
- }
102
- output {
103
- elasticsearch {
104
- host => "127.0.0.1"
105
- index => "#{index}"
106
- flush_size => #{flush_size}
107
- routing => "test"
108
- protocol => "http"
109
- }
110
- }
111
- CONFIG
112
-
113
- agent do
114
- # Try a few times to check if we have the correct number of events stored
115
- # in ES.
116
- #
117
- # We try multiple times to allow final agent flushes as well as allowing
118
- # elasticsearch to finish processing everything.
119
- ftw = FTW::Agent.new
120
- ftw.post!("http://localhost:9200/#{index}/_refresh")
121
-
122
- # Wait until all events are available.
123
- Stud::try(10.times) do
124
- data = ""
125
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*")
126
- response.read_body { |chunk| data << chunk }
127
- result = LogStash::Json.load(data)
128
- count = result["count"]
129
- insist { count } == event_count
130
- end
131
-
132
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*&routing=test")
133
- data = ""
134
- response.read_body { |chunk| data << chunk }
135
- result = LogStash::Json.load(data)
136
- count = result["count"]
137
- insist { count } == event_count
138
- end
139
- end
140
-
141
- describe "ship lots of events w/ default index_type and dynamic routing key using http protocol", :elasticsearch => true do
142
- # Generate a random index name
143
- index = 10.times.collect { rand(10).to_s }.join("")
144
- type = 10.times.collect { rand(10).to_s }.join("")
145
-
146
- # Write 900 events so that we can verify these have been routed correctly.
147
- event_count = 900
148
- flush_size = rand(200) + 1
149
-
150
- config <<-CONFIG
151
- input {
152
- generator {
153
- message => "test"
154
- count => #{event_count}
155
- type => "#{type}"
156
- }
157
- }
158
- output {
159
- elasticsearch {
160
- host => "127.0.0.1"
161
- index => "#{index}"
162
- flush_size => #{flush_size}
163
- routing => "%{message}"
164
- protocol => "http"
165
- }
166
- }
167
- CONFIG
168
-
169
- agent do
170
- # Try a few times to check if we have the correct number of events stored
171
- # in ES.
172
- #
173
- # We try multiple times to allow final agent flushes as well as allowing
174
- # elasticsearch to finish processing everything.
175
- ftw = FTW::Agent.new
176
- ftw.post!("http://localhost:9200/#{index}/_refresh")
177
-
178
- # Wait until all events are available.
179
- Stud::try(10.times) do
180
- data = ""
181
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*")
182
- response.read_body { |chunk| data << chunk }
183
- result = LogStash::Json.load(data)
184
- count = result["count"]
185
- insist { count } == event_count
186
- end
187
-
188
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*&routing=test")
189
- data = ""
190
- response.read_body { |chunk| data << chunk }
191
- result = LogStash::Json.load(data)
192
- count = result["count"]
193
- insist { count } == event_count
194
- end
195
- end
196
-
197
- describe "ship lots of events w/ default index_type and fixed routing key using transport protocol", :elasticsearch => true do
198
- # Generate a random index name
199
- index = 10.times.collect { rand(10).to_s }.join("")
200
- type = 10.times.collect { rand(10).to_s }.join("")
201
-
202
- # Write 900 events so that we can verify these have been routed correctly.
203
- event_count = 900
204
- flush_size = rand(200) + 1
205
-
206
- config <<-CONFIG
207
- input {
208
- generator {
209
- message => "hello world"
210
- count => #{event_count}
211
- type => "#{type}"
212
- }
213
- }
214
- output {
215
- elasticsearch {
216
- host => "127.0.0.1"
217
- index => "#{index}"
218
- flush_size => #{flush_size}
219
- routing => "test"
220
- protocol => "transport"
221
- }
222
- }
223
- CONFIG
224
-
225
- agent do
226
- # Try a few times to check if we have the correct number of events stored
227
- # in ES.
228
- #
229
- # We try multiple times to allow final agent flushes as well as allowing
230
- # elasticsearch to finish processing everything.
231
- ftw = FTW::Agent.new
232
- ftw.post!("http://localhost:9200/#{index}/_refresh")
233
-
234
- # Wait until all events are available.
235
- Stud::try(10.times) do
236
- data = ""
237
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*")
238
- response.read_body { |chunk| data << chunk }
239
- result = LogStash::Json.load(data)
240
- count = result["count"]
241
- insist { count } == event_count
242
- end
243
-
244
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*&routing=test")
245
- data = ""
246
- response.read_body { |chunk| data << chunk }
247
- result = LogStash::Json.load(data)
248
- count = result["count"]
249
- insist { count } == event_count
250
- end
251
- end
252
-
253
- describe "ship lots of events w/ default index_type and fixed routing key using node protocol", :elasticsearch => true do
254
- # Generate a random index name
255
- index = 10.times.collect { rand(10).to_s }.join("")
256
- type = 10.times.collect { rand(10).to_s }.join("")
257
-
258
- # Write 900 events so that we can verify these have been routed correctly.
259
- event_count = 900
260
- flush_size = rand(200) + 1
261
-
262
- config <<-CONFIG
263
- input {
264
- generator {
265
- message => "hello world"
266
- count => #{event_count}
267
- type => "#{type}"
268
- }
269
- }
270
- output {
271
- elasticsearch {
272
- host => "127.0.0.1"
273
- index => "#{index}"
274
- flush_size => #{flush_size}
275
- routing => "test"
276
- protocol => "node"
277
- }
278
- }
279
- CONFIG
280
-
281
- agent do
282
- # Try a few times to check if we have the correct number of events stored
283
- # in ES.
284
- #
285
- # We try multiple times to allow final agent flushes as well as allowing
286
- # elasticsearch to finish processing everything.
287
- ftw = FTW::Agent.new
288
- ftw.post!("http://localhost:9200/#{index}/_refresh")
289
-
290
- # Wait until all events are available.
291
- Stud::try(10.times) do
292
- data = ""
293
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*")
294
- response.read_body { |chunk| data << chunk }
295
- result = LogStash::Json.load(data)
296
- count = result["count"]
297
- insist { count } == event_count
298
- end
299
-
300
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*&routing=test")
301
- data = ""
302
- response.read_body { |chunk| data << chunk }
303
- result = LogStash::Json.load(data)
304
- count = result["count"]
305
- insist { count } == event_count
306
- end
307
- end
308
-
309
- describe "node client create actions", :elasticsearch => true do
310
- require "logstash/outputs/elasticsearch"
311
- require "elasticsearch"
312
- let(:es) { Elasticsearch::Client.new }
313
-
314
- def get_es_output(action, id = nil)
315
- settings = {
316
- "manage_template" => true,
317
- "index" => "logstash-create",
318
- "template_overwrite" => true,
319
- "protocol" => "node",
320
- "host" => "localhost",
321
- "action" => action
322
- }
323
- settings['document_id'] = id unless id.nil?
324
- LogStash::Outputs::ElasticSearch.new(settings)
325
- end
326
-
327
- before :each do
328
- # Delete all templates first.
329
- # Clean ES of data before we start.
330
- es.indices.delete_template(:name => "*")
331
- # This can fail if there are no indexes, ignore failure.
332
- es.indices.delete(:index => "*") rescue nil
333
- end
334
-
335
- context "when action => create" do
336
- it "should create new documents with or without id" do
337
- subject = get_es_output("create", "id123")
338
- subject.register
339
- subject.receive(LogStash::Event.new("message" => "sample message here"))
340
- subject.buffer_flush(:final => true)
341
- es.indices.refresh
342
- # Wait or fail until everything's indexed.
343
- Stud::try(3.times) do
344
- r = es.search
345
- insist { r["hits"]["total"] } == 1
346
- end
347
- end
348
-
349
- it "should create new documents without id" do
350
- subject = get_es_output("create")
351
- subject.register
352
- subject.receive(LogStash::Event.new("message" => "sample message here"))
353
- subject.buffer_flush(:final => true)
354
- es.indices.refresh
355
- # Wait or fail until everything's indexed.
356
- Stud::try(3.times) do
357
- r = es.search
358
- insist { r["hits"]["total"] } == 1
359
- end
360
- end
361
- end
362
-
363
- context "when action => create_unless_exists" do
364
- it "should create new documents when specific id is specified" do
365
- subject = get_es_output("create_unless_exists", "id123")
366
- subject.register
367
- subject.receive(LogStash::Event.new("message" => "sample message here"))
368
- subject.buffer_flush(:final => true)
369
- es.indices.refresh
370
- # Wait or fail until everything's indexed.
371
- Stud::try(3.times) do
372
- r = es.search
373
- insist { r["hits"]["total"] } == 1
374
- end
375
- end
376
-
377
- it "should fail to create a document when no id is specified" do
378
- event = LogStash::Event.new("somevalue" => 100, "@timestamp" => "2014-11-17T20:37:17.223Z", "@metadata" => {"retry_count" => 0})
379
- action = ["create_unless_exists", {:_id=>nil, :_index=>"logstash-2014.11.17", :_type=>"logs"}, event]
380
- subject = get_es_output(action[0])
381
- subject.register
382
- expect { subject.flush([action]) }.to raise_error
383
- end
384
-
385
- it "should unsuccesfully submit two records with the same document id" do
386
- subject = get_es_output("create_unless_exists", "id123")
387
- subject.register
388
- subject.receive(LogStash::Event.new("message" => "sample message here"))
389
- subject.receive(LogStash::Event.new("message" => "sample message here")) # 400 status failure (same id)
390
- subject.buffer_flush(:final => true)
391
- es.indices.refresh
392
- # Wait or fail until everything's indexed.
393
- Stud::try(3.times) do
394
- r = es.search
395
- insist { r["hits"]["total"] } == 1
396
- end
397
- end
398
- end
399
- end
400
-
401
- describe "testing index_type", :elasticsearch => true do
402
- describe "no type value" do
403
- # Generate a random index name
404
- index = 10.times.collect { rand(10).to_s }.join("")
405
- event_count = 100 + rand(100)
406
- flush_size = rand(200) + 1
407
-
408
- config <<-CONFIG
409
- input {
410
- generator {
411
- message => "hello world"
412
- count => #{event_count}
413
- }
414
- }
415
- output {
416
- elasticsearch {
417
- host => "127.0.0.1"
418
- index => "#{index}"
419
- flush_size => #{flush_size}
420
- }
421
- }
422
- CONFIG
423
-
424
- agent do
425
- ftw = FTW::Agent.new
426
- ftw.post!("http://localhost:9200/#{index}/_refresh")
427
-
428
- # Wait until all events are available.
429
- Stud::try(10.times) do
430
- data = ""
431
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*")
432
- response.read_body { |chunk| data << chunk }
433
- result = LogStash::Json.load(data)
434
- count = result["count"]
435
- insist { count } == event_count
436
- end
437
-
438
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_search?q=*&size=1000")
439
- data = ""
440
- response.read_body { |chunk| data << chunk }
441
- result = LogStash::Json.load(data)
442
- result["hits"]["hits"].each do |doc|
443
- insist { doc["_type"] } == "logs"
444
- end
445
- end
446
- end
447
-
448
- describe "default event type value" do
449
- # Generate a random index name
450
- index = 10.times.collect { rand(10).to_s }.join("")
451
- event_count = 100 + rand(100)
452
- flush_size = rand(200) + 1
453
-
454
- config <<-CONFIG
455
- input {
456
- generator {
457
- message => "hello world"
458
- count => #{event_count}
459
- type => "generated"
460
- }
461
- }
462
- output {
463
- elasticsearch {
464
- host => "127.0.0.1"
465
- index => "#{index}"
466
- flush_size => #{flush_size}
467
- }
468
- }
469
- CONFIG
470
-
471
- agent do
472
- ftw = FTW::Agent.new
473
- ftw.post!("http://localhost:9200/#{index}/_refresh")
474
-
475
- # Wait until all events are available.
476
- Stud::try(10.times) do
477
- data = ""
478
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*")
479
- response.read_body { |chunk| data << chunk }
480
- result = LogStash::Json.load(data)
481
- count = result["count"]
482
- insist { count } == event_count
483
- end
484
-
485
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_search?q=*&size=1000")
486
- data = ""
487
- response.read_body { |chunk| data << chunk }
488
- result = LogStash::Json.load(data)
489
- result["hits"]["hits"].each do |doc|
490
- insist { doc["_type"] } == "generated"
491
- end
492
- end
493
- end
494
- end
495
-
496
- describe "action => ...", :elasticsearch => true do
497
- index_name = 10.times.collect { rand(10).to_s }.join("")
498
-
499
- config <<-CONFIG
500
- input {
501
- generator {
502
- message => "hello world"
503
- count => 100
504
- }
505
- }
506
- output {
507
- elasticsearch {
508
- host => "127.0.0.1"
509
- index => "#{index_name}"
510
- }
511
- }
512
- CONFIG
513
-
514
-
515
- agent do
516
- ftw = FTW::Agent.new
517
- ftw.post!("http://localhost:9200/#{index_name}/_refresh")
518
-
519
- # Wait until all events are available.
520
- Stud::try(10.times) do
521
- data = ""
522
- response = ftw.get!("http://127.0.0.1:9200/#{index_name}/_count?q=*")
523
- response.read_body { |chunk| data << chunk }
524
- result = LogStash::Json.load(data)
525
- count = result["count"]
526
- insist { count } == 100
527
- end
528
-
529
- response = ftw.get!("http://127.0.0.1:9200/#{index_name}/_search?q=*&size=1000")
530
- data = ""
531
- response.read_body { |chunk| data << chunk }
532
- result = LogStash::Json.load(data)
533
- result["hits"]["hits"].each do |doc|
534
- insist { doc["_type"] } == "logs"
535
- end
536
- end
537
-
538
- describe "default event type value", :elasticsearch => true do
539
- # Generate a random index name
540
- index = 10.times.collect { rand(10).to_s }.join("")
541
- event_count = 100 + rand(100)
542
- flush_size = rand(200) + 1
543
-
544
- config <<-CONFIG
545
- input {
546
- generator {
547
- message => "hello world"
548
- count => #{event_count}
549
- type => "generated"
550
- }
551
- }
552
- output {
553
- elasticsearch {
554
- host => "127.0.0.1"
555
- index => "#{index}"
556
- flush_size => #{flush_size}
557
- }
558
- }
559
- CONFIG
560
-
561
- agent do
562
- ftw = FTW::Agent.new
563
- ftw.post!("http://localhost:9200/#{index}/_refresh")
564
-
565
- # Wait until all events are available.
566
- Stud::try(10.times) do
567
- data = ""
568
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_count?q=*")
569
- response.read_body { |chunk| data << chunk }
570
- result = LogStash::Json.load(data)
571
- count = result["count"]
572
- insist { count } == event_count
573
- end
574
-
575
- response = ftw.get!("http://127.0.0.1:9200/#{index}/_search?q=*&size=1000")
576
- data = ""
577
- response.read_body { |chunk| data << chunk }
578
- result = LogStash::Json.load(data)
579
- result["hits"]["hits"].each do |doc|
580
- insist { doc["_type"] } == "generated"
581
- end
582
- end
583
- end
584
- end
585
-
586
- describe "index template expected behavior", :elasticsearch => true do
587
- ["node", "transport", "http"].each do |protocol|
588
- context "with protocol => #{protocol}" do
589
- subject do
590
- require "logstash/outputs/elasticsearch"
591
- settings = {
592
- "manage_template" => true,
593
- "template_overwrite" => true,
594
- "protocol" => protocol,
595
- "host" => "localhost"
596
- }
597
- next LogStash::Outputs::ElasticSearch.new(settings)
598
- end
599
-
600
- before :each do
601
- # Delete all templates first.
602
- require "elasticsearch"
603
-
604
- # Clean ES of data before we start.
605
- @es = Elasticsearch::Client.new
606
- @es.indices.delete_template(:name => "*")
607
-
608
- # This can fail if there are no indexes, ignore failure.
609
- @es.indices.delete(:index => "*") rescue nil
610
-
611
- subject.register
612
-
613
- subject.receive(LogStash::Event.new("message" => "sample message here"))
614
- subject.receive(LogStash::Event.new("somevalue" => 100))
615
- subject.receive(LogStash::Event.new("somevalue" => 10))
616
- subject.receive(LogStash::Event.new("somevalue" => 1))
617
- subject.receive(LogStash::Event.new("country" => "us"))
618
- subject.receive(LogStash::Event.new("country" => "at"))
619
- subject.receive(LogStash::Event.new("geoip" => { "location" => [ 0.0, 0.0 ] }))
620
- subject.buffer_flush(:final => true)
621
- @es.indices.refresh
622
-
623
- # Wait or fail until everything's indexed.
624
- Stud::try(20.times) do
625
- r = @es.search
626
- insist { r["hits"]["total"] } == 7
627
- end
628
- end
629
-
630
- it "permits phrase searching on string fields" do
631
- results = @es.search(:q => "message:\"sample message\"")
632
- insist { results["hits"]["total"] } == 1
633
- insist { results["hits"]["hits"][0]["_source"]["message"] } == "sample message here"
634
- end
635
-
636
- it "numbers dynamically map to a numeric type and permit range queries" do
637
- results = @es.search(:q => "somevalue:[5 TO 105]")
638
- insist { results["hits"]["total"] } == 2
639
-
640
- values = results["hits"]["hits"].collect { |r| r["_source"]["somevalue"] }
641
- insist { values }.include?(10)
642
- insist { values }.include?(100)
643
- reject { values }.include?(1)
644
- end
645
-
646
- it "does not create .raw field for the message field" do
647
- results = @es.search(:q => "message.raw:\"sample message here\"")
648
- insist { results["hits"]["total"] } == 0
649
- end
650
-
651
- it "creates .raw field from any string field which is not_analyzed" do
652
- results = @es.search(:q => "country.raw:\"us\"")
653
- insist { results["hits"]["total"] } == 1
654
- insist { results["hits"]["hits"][0]["_source"]["country"] } == "us"
655
-
656
- # partial or terms should not work.
657
- results = @es.search(:q => "country.raw:\"u\"")
658
- insist { results["hits"]["total"] } == 0
659
- end
660
-
661
- it "make [geoip][location] a geo_point" do
662
- results = @es.search(:body => { "filter" => { "geo_distance" => { "distance" => "1000km", "geoip.location" => { "lat" => 0.5, "lon" => 0.5 } } } })
663
- insist { results["hits"]["total"] } == 1
664
- insist { results["hits"]["hits"][0]["_source"]["geoip"]["location"] } == [ 0.0, 0.0 ]
665
- end
666
-
667
- it "should index stopwords like 'at' " do
668
- results = @es.search(:body => { "facets" => { "t" => { "terms" => { "field" => "country" } } } })["facets"]["t"]
669
- terms = results["terms"].collect { |t| t["term"] }
670
-
671
- insist { terms }.include?("us")
672
-
673
- # 'at' is a stopword, make sure stopwords are not ignored.
674
- insist { terms }.include?("at")
675
- end
676
- end
677
- end
678
- end
679
-
680
- describe "failures in bulk class expected behavior", :elasticsearch => true do
681
- let(:template) { '{"template" : "not important, will be updated by :index"}' }
682
- let(:event1) { LogStash::Event.new("somevalue" => 100, "@timestamp" => "2014-11-17T20:37:17.223Z", "@metadata" => {"retry_count" => 0}) }
683
- let(:action1) { ["index", {:_id=>nil, :_routing=>nil, :_index=>"logstash-2014.11.17", :_type=>"logs"}, event1] }
684
- let(:event2) { LogStash::Event.new("geoip" => { "location" => [ 0.0, 0.0] }, "@timestamp" => "2014-11-17T20:37:17.223Z", "@metadata" => {"retry_count" => 0}) }
685
- let(:action2) { ["index", {:_id=>nil, :_routing=>nil, :_index=>"logstash-2014.11.17", :_type=>"logs"}, event2] }
686
- let(:invalid_event) { LogStash::Event.new("geoip" => { "location" => "notlatlon" }, "@timestamp" => "2014-11-17T20:37:17.223Z") }
687
- let(:max_retries) { 3 }
688
-
689
- def mock_actions_with_response(*resp)
690
- LogStash::Outputs::Elasticsearch::Protocols::HTTPClient
691
- .any_instance.stub(:bulk).and_return(*resp)
692
- LogStash::Outputs::Elasticsearch::Protocols::NodeClient
693
- .any_instance.stub(:bulk).and_return(*resp)
694
- end
695
-
696
- ["node", "transport", "http"].each do |protocol|
697
- context "with protocol => #{protocol}" do
698
- subject do
699
- require "logstash/outputs/elasticsearch"
700
- settings = {
701
- "manage_template" => true,
702
- "index" => "logstash-2014.11.17",
703
- "template_overwrite" => true,
704
- "protocol" => protocol,
705
- "host" => "localhost",
706
- "retry_max_items" => 10,
707
- "retry_max_interval" => 1,
708
- "max_retries" => max_retries
709
- }
710
- next LogStash::Outputs::ElasticSearch.new(settings)
711
- end
712
-
713
- before :each do
714
- # Delete all templates first.
715
- require "elasticsearch"
716
-
717
- # Clean ES of data before we start.
718
- @es = Elasticsearch::Client.new
719
- @es.indices.delete_template(:name => "*")
720
- @es.indices.delete(:index => "*")
721
- @es.indices.refresh
722
- end
723
-
724
- it "should return no errors if all bulk actions are successful" do
725
- mock_actions_with_response({"errors" => false})
726
- expect(subject).to receive(:submit).with([action1, action2]).once.and_call_original
727
- subject.register
728
- subject.receive(event1)
729
- subject.receive(event2)
730
- subject.buffer_flush(:final => true)
731
- sleep(2)
732
- end
733
-
734
- it "should raise exception and be retried by stud::buffer" do
735
- call_count = 0
736
- expect(subject).to receive(:submit).with([action1]).exactly(3).times do
737
- if (call_count += 1) <= 2
738
- raise "error first two times"
739
- else
740
- {"errors" => false}
741
- end
742
- end
743
- subject.register
744
- subject.receive(event1)
745
- subject.teardown
746
- end
747
-
748
- it "should retry actions with response status of 503" do
749
- mock_actions_with_response({"errors" => true, "statuses" => [200, 200, 503, 503]},
750
- {"errors" => true, "statuses" => [200, 503]},
751
- {"errors" => false})
752
- expect(subject).to receive(:submit).with([action1, action1, action1, action2]).ordered.once.and_call_original
753
- expect(subject).to receive(:submit).with([action1, action2]).ordered.once.and_call_original
754
- expect(subject).to receive(:submit).with([action2]).ordered.once.and_call_original
755
-
756
- subject.register
757
- subject.receive(event1)
758
- subject.receive(event1)
759
- subject.receive(event1)
760
- subject.receive(event2)
761
- subject.buffer_flush(:final => true)
762
- sleep(3)
763
- end
764
-
765
- it "should retry actions with response status of 429" do
766
- mock_actions_with_response({"errors" => true, "statuses" => [429]},
767
- {"errors" => false})
768
- expect(subject).to receive(:submit).with([action1]).twice.and_call_original
769
- subject.register
770
- subject.receive(event1)
771
- subject.buffer_flush(:final => true)
772
- sleep(3)
773
- end
774
-
775
- it "should retry an event until max_retries reached" do
776
- mock_actions_with_response({"errors" => true, "statuses" => [429]},
777
- {"errors" => true, "statuses" => [429]},
778
- {"errors" => true, "statuses" => [429]},
779
- {"errors" => true, "statuses" => [429]},
780
- {"errors" => true, "statuses" => [429]},
781
- {"errors" => true, "statuses" => [429]})
782
- expect(subject).to receive(:submit).with([action1]).exactly(max_retries).times.and_call_original
783
- subject.register
784
- subject.receive(event1)
785
- subject.buffer_flush(:final => true)
786
- sleep(3)
787
- end
788
-
789
- it "non-retryable errors like mapping errors (400) should be dropped and not be retried (unfortunetly)" do
790
- subject.register
791
- subject.receive(invalid_event)
792
- expect(subject).not_to receive(:retry_push)
793
- subject.teardown
794
-
795
- @es.indices.refresh
796
- sleep(5)
797
- Stud::try(10.times) do
798
- r = @es.search
799
- insist { r["hits"]["total"] } == 0
800
- end
801
- end
802
-
803
- it "successful requests should not be appended to retry queue" do
804
- subject.register
805
- subject.receive(event1)
806
- expect(subject).not_to receive(:retry_push)
807
- subject.teardown
808
-
809
- @es.indices.refresh
810
- sleep(5)
811
- Stud::try(10.times) do
812
- r = @es.search
813
- insist { r["hits"]["total"] } == 1
814
- end
815
- end
816
- end
817
- end
818
- end
819
-
820
- describe "elasticsearch protocol", :elasticsearch => true do
821
- # ElasticSearch related jars
822
- #LogStash::Environment.load_elasticsearch_jars!
823
- # Load elasticsearch protocol
824
- require "logstash/outputs/elasticsearch/protocol"
825
-
826
- describe "elasticsearch node client" do
827
- # Test ElasticSearch Node Client
828
- # Reference: http://www.elasticsearch.org/guide/reference/modules/discovery/zen/
829
-
830
- it "should support hosts in both string and array" do
831
- # Because we defined *hosts* method in NodeClient as private,
832
- # we use *obj.send :method,[args...]* to call method *hosts*
833
- client = LogStash::Outputs::Elasticsearch::Protocols::NodeClient.new
834
-
835
- # Node client should support host in string
836
- # Case 1: default :host in string
837
- insist { client.send :hosts, :host => "host",:port => 9300 } == "host:9300"
838
- # Case 2: :port =~ /^\d+_\d+$/
839
- insist { client.send :hosts, :host => "host",:port => "9300-9302"} == "host:9300,host:9301,host:9302"
840
- # Case 3: :host =~ /^.+:.+$/
841
- insist { client.send :hosts, :host => "host:9303",:port => 9300 } == "host:9303"
842
- # Case 4: :host =~ /^.+:.+$/ and :port =~ /^\d+_\d+$/
843
- insist { client.send :hosts, :host => "host:9303",:port => "9300-9302"} == "host:9303"
844
-
845
- # Node client should support host in array
846
- # Case 5: :host in array with single item
847
- insist { client.send :hosts, :host => ["host"],:port => 9300 } == ("host:9300")
848
- # Case 6: :host in array with more than one items
849
- insist { client.send :hosts, :host => ["host1","host2"],:port => 9300 } == "host1:9300,host2:9300"
850
- # Case 7: :host in array with more than one items and :port =~ /^\d+_\d+$/
851
- insist { client.send :hosts, :host => ["host1","host2"],:port => "9300-9302" } == "host1:9300,host1:9301,host1:9302,host2:9300,host2:9301,host2:9302"
852
- # Case 8: :host in array with more than one items and some :host =~ /^.+:.+$/
853
- insist { client.send :hosts, :host => ["host1","host2:9303"],:port => 9300 } == "host1:9300,host2:9303"
854
- # Case 9: :host in array with more than one items, :port =~ /^\d+_\d+$/ and some :host =~ /^.+:.+$/
855
- insist { client.send :hosts, :host => ["host1","host2:9303"],:port => "9300-9302" } == "host1:9300,host1:9301,host1:9302,host2:9303"
856
- end
857
- end
858
- end
859
-
860
- describe "Authentication option" do
861
- ["node", "transport"].each do |protocol|
862
- context "with protocol => #{protocol}" do
863
- subject do
864
- require "logstash/outputs/elasticsearch"
865
- settings = {
866
- "protocol" => protocol,
867
- "node_name" => "logstash",
868
- "cluster" => "elasticsearch",
869
- "host" => "node01",
870
- "user" => "test",
871
- "password" => "test"
872
- }
873
- next LogStash::Outputs::ElasticSearch.new(settings)
874
- end
875
-
876
- it "should fail in register" do
877
- expect {subject.register}.to raise_error
878
- end
879
- end
880
- end
881
- end
882
-
883
- describe "SSL option" do
884
- ["node", "transport"].each do |protocol|
885
- context "with protocol => #{protocol}" do
886
- subject do
887
- require "logstash/outputs/elasticsearch"
888
- settings = {
889
- "protocol" => protocol,
890
- "node_name" => "logstash",
891
- "cluster" => "elasticsearch",
892
- "host" => "node01",
893
- "ssl" => true
894
- }
895
- next LogStash::Outputs::ElasticSearch.new(settings)
896
- end
897
-
898
- it "should fail in register" do
899
- expect {subject.register}.to raise_error
900
- end
901
- end
902
- end
903
-
904
- context "when using http protocol" do
905
- protocol = "http"
906
- context "when using ssl without cert verification" do
907
- subject do
908
- require "logstash/outputs/elasticsearch"
909
- settings = {
910
- "protocol" => protocol,
911
- "host" => "node01",
912
- "ssl" => true,
913
- "ssl_certificate_verification" => false
914
- }
915
- next LogStash::Outputs::ElasticSearch.new(settings)
916
- end
917
-
918
- it "should pass the flag to the ES client" do
919
- expect(::Elasticsearch::Client).to receive(:new) do |args|
920
- expect(args[:ssl]).to eq(:verify => false)
921
- end
922
- subject.register
923
- end
924
-
925
- it "print a warning" do
926
- expect(subject.logger).to receive(:warn)
927
- subject.register
928
- end
929
- end
930
- end
931
- end
932
-
933
- describe "send messages to ElasticSearch using HTTPS", :elasticsearch_secure => true do
934
- subject do
935
- require "logstash/outputs/elasticsearch"
936
- settings = {
937
- "protocol" => "http",
938
- "node_name" => "logstash",
939
- "cluster" => "elasticsearch",
940
- "host" => "node01",
941
- "user" => "user",
942
- "password" => "changeme",
943
- "ssl" => true,
944
- "cacert" => "/tmp/ca/certs/cacert.pem",
945
- # or
946
- #"truststore" => "/tmp/ca/truststore.jks",
947
- #"truststore_password" => "testeteste"
948
- }
949
- next LogStash::Outputs::ElasticSearch.new(settings)
950
- end
951
-
952
- before :each do
953
- subject.register
954
- end
955
-
956
- it "sends events to ES" do
957
- expect {
958
- subject.receive(LogStash::Event.new("message" => "sample message here"))
959
- subject.buffer_flush(:final => true)
960
- }.to_not raise_error
961
- end
962
- end
963
-
964
- describe "connect using HTTP Authentication", :elasticsearch_secure => true do
965
- subject do
966
- require "logstash/outputs/elasticsearch"
967
- settings = {
968
- "protocol" => "http",
969
- "cluster" => "elasticsearch",
970
- "host" => "node01",
971
- "user" => "user",
972
- "password" => "changeme",
973
- }
974
- next LogStash::Outputs::ElasticSearch.new(settings)
975
- end
976
-
977
- before :each do
978
- subject.register
979
- end
980
-
981
- it "sends events to ES" do
982
- expect {
983
- subject.receive(LogStash::Event.new("message" => "sample message here"))
984
- subject.buffer_flush(:final => true)
985
- }.to_not raise_error
986
- end
987
- end
988
-
989
- describe "transport protocol" do
990
-
991
- context "host not configured" do
992
- subject do
993
- require "logstash/outputs/elasticsearch"
994
- settings = {
995
- "protocol" => "transport",
996
- "node_name" => "mynode"
997
- }
998
- next LogStash::Outputs::ElasticSearch.new(settings)
999
- end
1000
-
1001
- it "should set host to localhost" do
1002
- expect(LogStash::Outputs::Elasticsearch::Protocols::TransportClient).to receive(:new).with({
1003
- :host => "localhost",
1004
- :port => "9300-9305",
1005
- :protocol => "transport",
1006
- :client_settings => {
1007
- "client.transport.sniff" => false,
1008
- "node.name" => "mynode"
1009
- }
1010
- })
1011
- subject.register
1012
- end
1013
- end
1014
-
1015
- context "sniffing => true" do
1016
-
1017
- subject do
1018
- require "logstash/outputs/elasticsearch"
1019
- settings = {
1020
- "host" => "node01",
1021
- "protocol" => "transport",
1022
- "sniffing" => true
1023
- }
1024
- next LogStash::Outputs::ElasticSearch.new(settings)
1025
- end
1026
-
1027
- it "should set the sniffing property to true" do
1028
- expect_any_instance_of(LogStash::Outputs::Elasticsearch::Protocols::TransportClient).to receive(:client).and_return(nil)
1029
- subject.register
1030
- client = subject.instance_eval("@current_client")
1031
- settings = client.instance_eval("@settings")
1032
-
1033
- expect(settings.build.getAsMap["client.transport.sniff"]).to eq("true")
1034
- end
1035
- end
1036
-
1037
- context "sniffing => false" do
1038
-
1039
- subject do
1040
- require "logstash/outputs/elasticsearch"
1041
- settings = {
1042
- "host" => "node01",
1043
- "protocol" => "transport",
1044
- "sniffing" => false
1045
- }
1046
- next LogStash::Outputs::ElasticSearch.new(settings)
1047
- end
1048
-
1049
- it "should set the sniffing property to true" do
1050
- expect_any_instance_of(LogStash::Outputs::Elasticsearch::Protocols::TransportClient).to receive(:client).and_return(nil)
1051
- subject.register
1052
- client = subject.instance_eval("@current_client")
1053
- settings = client.instance_eval("@settings")
1054
-
1055
- expect(settings.build.getAsMap["client.transport.sniff"]).to eq("false")
1056
- end
1057
- end
1058
- end
1059
- end