logstash-output-elasticsearch 3.0.2-java → 4.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -3
  3. data/Gemfile +1 -1
  4. data/lib/logstash/outputs/elasticsearch/common.rb +90 -58
  5. data/lib/logstash/outputs/elasticsearch/common_configs.rb +12 -32
  6. data/lib/logstash/outputs/elasticsearch/http_client/manticore_adapter.rb +63 -0
  7. data/lib/logstash/outputs/elasticsearch/http_client/pool.rb +378 -0
  8. data/lib/logstash/outputs/elasticsearch/http_client.rb +70 -64
  9. data/lib/logstash/outputs/elasticsearch/http_client_builder.rb +15 -4
  10. data/lib/logstash/outputs/elasticsearch/template_manager.rb +1 -1
  11. data/lib/logstash/outputs/elasticsearch.rb +27 -4
  12. data/logstash-output-elasticsearch.gemspec +3 -5
  13. data/spec/es_spec_helper.rb +1 -0
  14. data/spec/fixtures/5x_node_resp.json +2 -0
  15. data/spec/integration/outputs/create_spec.rb +2 -5
  16. data/spec/integration/outputs/index_spec.rb +1 -1
  17. data/spec/integration/outputs/parent_spec.rb +1 -3
  18. data/spec/integration/outputs/pipeline_spec.rb +1 -2
  19. data/spec/integration/outputs/retry_spec.rb +51 -49
  20. data/spec/integration/outputs/routing_spec.rb +1 -1
  21. data/spec/integration/outputs/secure_spec.rb +4 -8
  22. data/spec/integration/outputs/templates_spec.rb +12 -8
  23. data/spec/integration/outputs/update_spec.rb +13 -27
  24. data/spec/unit/outputs/elasticsearch/http_client/manticore_adapter_spec.rb +25 -0
  25. data/spec/unit/outputs/elasticsearch/http_client/pool_spec.rb +142 -0
  26. data/spec/unit/outputs/elasticsearch/http_client_spec.rb +8 -22
  27. data/spec/unit/outputs/elasticsearch_proxy_spec.rb +5 -6
  28. data/spec/unit/outputs/elasticsearch_spec.rb +33 -30
  29. data/spec/unit/outputs/elasticsearch_ssl_spec.rb +10 -6
  30. metadata +72 -87
  31. data/lib/logstash/outputs/elasticsearch/buffer.rb +0 -124
  32. data/spec/unit/buffer_spec.rb +0 -118
@@ -1,124 +0,0 @@
1
- require 'concurrent'
2
- java_import java.util.concurrent.locks.ReentrantLock
3
-
4
- module LogStash; module Outputs; class ElasticSearch
5
- class Buffer
6
- def initialize(logger, max_size, flush_interval, &block)
7
- @logger = logger
8
- # You need to aquire this for anything modifying state generally
9
- @operations_mutex = Mutex.new
10
- @operations_lock = java.util.concurrent.locks.ReentrantLock.new
11
-
12
- @stopping = Concurrent::AtomicBoolean.new(false)
13
- @max_size = max_size
14
- @submit_proc = block
15
-
16
- @buffer = []
17
-
18
- @last_flush = Time.now
19
- @flush_interval = flush_interval
20
- @flush_thread = spawn_interval_flusher
21
- end
22
-
23
- def push(item)
24
- synchronize do |buffer|
25
- push_unsafe(item)
26
- end
27
- end
28
- alias_method :<<, :push
29
-
30
- # Push multiple items onto the buffer in a single operation
31
- def push_multi(items)
32
- raise ArgumentError, "push multi takes an array!, not an #{items.class}!" unless items.is_a?(Array)
33
- synchronize do |buffer|
34
- items.each {|item| push_unsafe(item) }
35
- end
36
- end
37
-
38
- def flush
39
- synchronize { flush_unsafe }
40
- end
41
-
42
- def stop(do_flush=true,wait_complete=true)
43
- return if stopping?
44
- @stopping.make_true
45
-
46
- # No need to acquire a lock in this case
47
- return if !do_flush && !wait_complete
48
-
49
- synchronize do
50
- flush_unsafe if do_flush
51
- @flush_thread.join if wait_complete
52
- end
53
- end
54
-
55
- def contents
56
- synchronize {|buffer| buffer}
57
- end
58
-
59
- # For externally operating on the buffer contents
60
- # this takes a block and will yield the internal buffer and executes
61
- # the block in a synchronized block from the internal mutex
62
- def synchronize
63
- @operations_mutex.synchronize { yield(@buffer) }
64
- end
65
-
66
- # These methods are private for various reasons, chief among them threadsafety!
67
- # Many require the @operations_mutex to be locked to be safe
68
- private
69
-
70
- def push_unsafe(item)
71
- @buffer << item
72
- if @buffer.size >= @max_size
73
- flush_unsafe
74
- end
75
- end
76
-
77
- def spawn_interval_flusher
78
- Thread.new do
79
- loop do
80
- sleep 0.2
81
- break if stopping?
82
- synchronize { interval_flush }
83
- end
84
- end
85
- end
86
-
87
- def interval_flush
88
- if last_flush_seconds_ago >= @flush_interval
89
- begin
90
- @logger.debug? && @logger.debug("Flushing buffer at interval",
91
- :instance => self.inspect,
92
- :interval => @flush_interval)
93
- flush_unsafe
94
- rescue StandardError => e
95
- @logger.warn("Error flushing buffer at interval!",
96
- :instance => self.inspect,
97
- :message => e.message,
98
- :class => e.class.name,
99
- :backtrace => e.backtrace
100
- )
101
- rescue Exception => e
102
- @logger.warn("Exception flushing buffer at interval!", :error => e.message, :class => e.class.name)
103
- end
104
- end
105
- end
106
-
107
- def flush_unsafe
108
- if @buffer.size > 0
109
- @submit_proc.call(@buffer)
110
- @buffer.clear
111
- end
112
-
113
- @last_flush = Time.now # This must always be set to ensure correct timer behavior
114
- end
115
-
116
- def last_flush_seconds_ago
117
- Time.now - @last_flush
118
- end
119
-
120
- def stopping?
121
- @stopping.true?
122
- end
123
- end
124
- end end end
@@ -1,118 +0,0 @@
1
- require "logstash/outputs/elasticsearch"
2
- require "logstash/outputs/elasticsearch/buffer"
3
-
4
- describe LogStash::Outputs::ElasticSearch::Buffer do
5
- class OperationTarget # Used to track buffer flushesn
6
- attr_reader :buffer, :buffer_history, :receive_count
7
- def initialize
8
- @buffer = nil
9
- @buffer_history = []
10
- @receive_count = 0
11
- end
12
-
13
- def receive(buffer)
14
- @receive_count += 1
15
- @buffer_history << buffer.clone
16
- @buffer = buffer
17
- end
18
- end
19
-
20
- let(:logger) { Cabin::Channel.get }
21
- let(:max_size) { 10 }
22
- let(:flush_interval) { 2 }
23
- # Used to track flush count
24
- let(:operation_target) { OperationTarget.new() }
25
- let(:operation) { proc {|buffer| operation_target.receive(buffer) } }
26
- subject(:buffer){ LogStash::Outputs::ElasticSearch::Buffer.new(logger, max_size, flush_interval, &operation) }
27
-
28
- after(:each) do
29
- buffer.stop(do_flush=false)
30
- end
31
-
32
- it "should initialize cleanly" do
33
- expect(buffer).to be_a(LogStash::Outputs::ElasticSearch::Buffer)
34
- end
35
-
36
- shared_examples("a buffer with two items inside") do
37
- it "should add a pushed item to the buffer" do
38
- buffer.synchronize do |data|
39
- expect(data).to include(item1)
40
- expect(data).to include(item2)
41
- end
42
- end
43
-
44
- describe "interval flushing" do
45
- before do
46
- sleep flush_interval + 1
47
- end
48
-
49
- it "should flush the buffer after the interval has passed" do
50
- expect(operation_target.receive_count).to eql(1)
51
- end
52
-
53
- it "should clear the buffer after a successful flush" do
54
- expect(operation_target.buffer).to eql([])
55
- end
56
- end
57
-
58
- describe "interval flushing a stopped buffer" do
59
- before do
60
- buffer.stop(do_flush=false)
61
- sleep flush_interval + 1
62
- end
63
-
64
- it "should not flush if the buffer is stopped" do
65
- expect(operation_target.receive_count).to eql(0)
66
- end
67
- end
68
- end
69
-
70
- describe "with a buffer push" do
71
- let(:item1) { "foo" }
72
- let(:item2) { "bar" }
73
-
74
- describe "a buffer with two items pushed to it separately" do
75
- before do
76
- buffer << item1
77
- buffer << item2
78
- end
79
-
80
- include_examples("a buffer with two items inside")
81
- end
82
-
83
- describe "a buffer with two items pushed to it in one operation" do
84
- before do
85
- buffer.push_multi([item1, item2])
86
- end
87
-
88
- include_examples("a buffer with two items inside")
89
- end
90
- end
91
-
92
- describe "with an empty buffer" do
93
- it "should not perform an operation if the buffer is empty" do
94
- buffer.flush
95
- expect(operation_target.receive_count).to eql(0)
96
- end
97
- end
98
-
99
- describe "flushing with an operation that raises an error" do
100
- class TestError < StandardError; end
101
- let(:operation) { proc {|buffer| raise TestError, "A test" } }
102
- let(:item) { double("item") }
103
-
104
- before do
105
- buffer << item
106
- end
107
-
108
- it "should raise an exception" do
109
- expect { buffer.flush }.to raise_error(TestError)
110
- end
111
-
112
- it "should not clear the buffer" do
113
- expect do
114
- buffer.flush rescue TestError
115
- end.not_to change(buffer, :contents)
116
- end
117
- end
118
- end