logstash-input-lumberjack 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/NOTICE.TXT +5 -0
- data/lib/logstash/circuit_breaker.rb +96 -0
- data/lib/logstash/inputs/lumberjack.rb +56 -20
- data/lib/logstash/sized_queue_timeout.rb +58 -0
- data/logstash-input-lumberjack.gemspec +3 -1
- data/spec/inputs/lumberjack_spec.rb +0 -55
- data/spec/logstash/circuit_breaker_spec.rb +60 -0
- data/spec/logstash/size_queue_timeout_spec.rb +100 -0
- data/spec/spec_helper.rb +1 -0
- metadata +37 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a24179f3e3ca8a3092c1d692875ea2a88edfa557
|
4
|
+
data.tar.gz: 46e2bde92697647cb0b26e66484124e7e4ae6c11
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c21484a7108a55aabe51d75d8877ddc749c1abfe30a033096ec662fa020f46335ffb8a66cba3de79a20b85d24f31f4b7dc51435544263d0f7bdd815ee96387c2
|
7
|
+
data.tar.gz: cc0df5cd9059650ebf13c4d18956ff2953535e8683ea2ecb167d2592a7bdd43eab06353ac4d77e03133ff3106b2ba2f5996f53d7825e0c78756c5c371e90d88f
|
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,4 @@
|
|
1
|
+
# 0.1.10
|
2
|
+
- Deprecating the `max_clients` option
|
3
|
+
- Use a circuit breaker to start refusing new connection when the queue is blocked for too long.
|
4
|
+
- Add an internal `SizeQueue` with a timeout to drop blocked connections. (https://github.com/logstash-plugins/logstash-input-lumberjack/pull/12)
|
data/NOTICE.TXT
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require "thread"
|
2
|
+
require "cabin"
|
3
|
+
|
4
|
+
module LogStash
|
5
|
+
# Largely inspired by Martin's fowler circuit breaker
|
6
|
+
class CircuitBreaker
|
7
|
+
class OpenBreaker < StandardError; end
|
8
|
+
|
9
|
+
# Error threshold before opening the breaker,
|
10
|
+
# if the breaker is open it wont execute the code.
|
11
|
+
DEFAULT_ERROR_THRESHOLD = 5
|
12
|
+
|
13
|
+
# Recover time after the breaker is open to start
|
14
|
+
# executing the method again.
|
15
|
+
DEFAULT_TIME_BEFORE_RETRY = 30
|
16
|
+
|
17
|
+
# Exceptions catched by the circuit breaker,
|
18
|
+
# too much errors and the breaker will trip.
|
19
|
+
DEFAULT_EXCEPTION_RESCUED = [StandardError]
|
20
|
+
|
21
|
+
def initialize(name, options = {}, &block)
|
22
|
+
@exceptions = Array(options.fetch(:exceptions, [StandardError]))
|
23
|
+
@error_threshold = options.fetch(:error_threshold, DEFAULT_ERROR_THRESHOLD)
|
24
|
+
@time_before_retry = options.fetch(:time_before_retry, DEFAULT_TIME_BEFORE_RETRY)
|
25
|
+
@block = block
|
26
|
+
@name = name
|
27
|
+
@mutex = Mutex.new
|
28
|
+
reset
|
29
|
+
end
|
30
|
+
|
31
|
+
def execute(args = nil)
|
32
|
+
case state
|
33
|
+
when :open
|
34
|
+
logger.warn("CircuitBreaker::Open", :name => @name)
|
35
|
+
raise OpenBreaker, "for #{@name}"
|
36
|
+
when :close, :half_open
|
37
|
+
if block_given?
|
38
|
+
yield args
|
39
|
+
else
|
40
|
+
@block.call(args)
|
41
|
+
end
|
42
|
+
|
43
|
+
if state == :half_open
|
44
|
+
logger.warn("CircuitBreaker::Close", :name => @name)
|
45
|
+
reset
|
46
|
+
end
|
47
|
+
end
|
48
|
+
rescue *@exceptions => e
|
49
|
+
logger.warn("CircuitBreaker::rescuing exceptions", :name => @name, :exception => e.class)
|
50
|
+
increment_errors(e)
|
51
|
+
end
|
52
|
+
|
53
|
+
def closed?
|
54
|
+
state == :close || state == :half_open
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
def logger
|
59
|
+
@logger ||= Cabin::Channel.get(LogStash)
|
60
|
+
end
|
61
|
+
|
62
|
+
def reset
|
63
|
+
@mutex.synchronize do
|
64
|
+
@errors_count = 0
|
65
|
+
@last_failure_time = nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def increment_errors(exception)
|
70
|
+
@mutex.synchronize do
|
71
|
+
@errors_count += 1
|
72
|
+
@last_failure_time = Time.now
|
73
|
+
|
74
|
+
logger.debug("CircuitBreaker increment errors",
|
75
|
+
:errors_count => @errors_count,
|
76
|
+
:error_threshold => @error_threshold,
|
77
|
+
:exception => exception.class,
|
78
|
+
:message => exception.message) if logger.debug?
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def state
|
83
|
+
@mutex.synchronize do
|
84
|
+
if @errors_count >= @error_threshold
|
85
|
+
if Time.now - @last_failure_time > @time_before_retry
|
86
|
+
:half_open
|
87
|
+
else
|
88
|
+
:open
|
89
|
+
end
|
90
|
+
else
|
91
|
+
:close
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -29,18 +29,23 @@ class LogStash::Inputs::Lumberjack < LogStash::Inputs::Base
|
|
29
29
|
# SSL key passphrase to use.
|
30
30
|
config :ssl_key_passphrase, :validate => :password
|
31
31
|
|
32
|
-
#
|
33
|
-
#
|
34
|
-
# connection. This
|
35
|
-
|
32
|
+
# The lumberjack input using a fixed thread pool to do the actual work and
|
33
|
+
# will accept a number of client in a queue, before starting to refuse new
|
34
|
+
# connection. This solve an issue when logstash-forwarder clients are
|
35
|
+
# trying to connect to logstash which have a blocked pipeline and will
|
36
|
+
# make logstash crash with an out of memory exception.
|
37
|
+
config :max_clients, :validate => :number, :default => 1000
|
36
38
|
|
37
39
|
# TODO(sissel): Add CA to authenticate clients with.
|
38
40
|
|
39
|
-
|
41
|
+
BUFFERED_QUEUE_SIZE = 20
|
42
|
+
RECONNECT_BACKOFF_SLEEP = 0.5
|
43
|
+
|
40
44
|
def register
|
41
45
|
require "lumberjack/server"
|
42
|
-
require "concurrent"
|
43
46
|
require "concurrent/executors"
|
47
|
+
require "logstash/circuit_breaker"
|
48
|
+
require "logstash/sized_queue_timeout"
|
44
49
|
|
45
50
|
@logger.info("Starting lumberjack input listener", :address => "#{@host}:#{@port}")
|
46
51
|
@lumberjack = Lumberjack::Server.new(:address => @host, :port => @port,
|
@@ -48,6 +53,7 @@ class LogStash::Inputs::Lumberjack < LogStash::Inputs::Base
|
|
48
53
|
:ssl_key_passphrase => @ssl_key_passphrase)
|
49
54
|
|
50
55
|
# Limit the number of thread that can be created by the
|
56
|
+
# Limit the number of thread that can be created by the
|
51
57
|
# lumberjack output, if the queue is full the input will
|
52
58
|
# start rejecting new connection and raise an exception
|
53
59
|
@threadpool = Concurrent::ThreadPoolExecutor.new(
|
@@ -56,37 +62,59 @@ class LogStash::Inputs::Lumberjack < LogStash::Inputs::Base
|
|
56
62
|
:max_queue => 1, # in concurrent-ruby, bounded queue need to be at least 1.
|
57
63
|
fallback_policy: :abort
|
58
64
|
)
|
65
|
+
@threadpool = Concurrent::CachedThreadPool.new(:idletime => 15)
|
66
|
+
|
67
|
+
# in 1.5 the main SizeQueue doesnt have the concept of timeout
|
68
|
+
# We are using a small plugin buffer to move events to the internal queue
|
69
|
+
@buffered_queue = LogStash::SizedQueueTimeout.new(BUFFERED_QUEUE_SIZE)
|
70
|
+
|
71
|
+
@circuit_breaker = LogStash::CircuitBreaker.new("Lumberjack input",
|
72
|
+
:exceptions => [LogStash::SizedQueueTimeout::TimeoutError])
|
73
|
+
|
59
74
|
end # def register
|
60
75
|
|
61
76
|
def run(output_queue)
|
77
|
+
start_buffer_broker(output_queue)
|
78
|
+
|
62
79
|
while true do
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
80
|
+
begin
|
81
|
+
# Wrapping the accept call into a CircuitBreaker
|
82
|
+
if @circuit_breaker.closed?
|
83
|
+
connection = @lumberjack.accept # Blocking call that creates a new connection
|
84
|
+
|
85
|
+
invoke(connection, codec.clone) do |_codec, line, fields|
|
86
|
+
_codec.decode(line) do |event|
|
87
|
+
decorate(event)
|
88
|
+
fields.each { |k,v| event[k] = v; v.force_encoding(Encoding::UTF_8) }
|
89
|
+
|
90
|
+
@circuit_breaker.execute { @buffered_queue << event }
|
91
|
+
end
|
69
92
|
end
|
93
|
+
else
|
94
|
+
@logger.warn("Lumberjack input: the pipeline is blocked, temporary refusing new connection.")
|
95
|
+
sleep(RECONNECT_BACKOFF_SLEEP)
|
70
96
|
end
|
97
|
+
# When too many errors happen inside the circuit breaker it will throw
|
98
|
+
# this exception and start refusing connection, we need to catch it but
|
99
|
+
# it's safe to ignore.
|
100
|
+
rescue LogStash::CircuitBreaker::OpenBreaker => e
|
71
101
|
end
|
72
102
|
end
|
103
|
+
rescue LogStash::ShutdownSignal
|
104
|
+
@logger.info("Lumberjack input: received ShutdownSignal")
|
73
105
|
rescue => e
|
74
|
-
@logger.error("
|
106
|
+
@logger.error("Lumberjack input: unhandled exception", :exception => e, :backtrace => e.backtrace)
|
107
|
+
ensure
|
75
108
|
shutdown(output_queue)
|
76
109
|
end # def run
|
77
110
|
|
78
111
|
private
|
79
112
|
def accept(&block)
|
80
113
|
connection = @lumberjack.accept # Blocking call that creates a new connection
|
81
|
-
|
82
|
-
if @threadpool.length < @threadpool.max_length
|
83
|
-
block.call(connection, @codec.clone)
|
84
|
-
else
|
85
|
-
@logger.warn("Lumberjack input, maximum connection exceeded, new connection are rejected.", :max_clients => @max_clients)
|
86
|
-
connection.close
|
87
|
-
end
|
114
|
+
block.call(connection, @codec.clone)
|
88
115
|
end
|
89
116
|
|
117
|
+
private
|
90
118
|
def invoke(connection, codec, &block)
|
91
119
|
@threadpool.post do
|
92
120
|
begin
|
@@ -98,4 +126,12 @@ class LogStash::Inputs::Lumberjack < LogStash::Inputs::Base
|
|
98
126
|
end
|
99
127
|
end
|
100
128
|
end
|
129
|
+
|
130
|
+
def start_buffer_broker(output_queue)
|
131
|
+
@threadpool.post do
|
132
|
+
while true
|
133
|
+
output_queue << @buffered_queue.pop_no_timeout
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
101
137
|
end # class LogStash::Inputs::Lumberjack
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "concurrent/atomic/condition"
|
2
|
+
require "thread"
|
3
|
+
|
4
|
+
module LogStash
|
5
|
+
# Minimal subset implement of a SizedQueue supporting
|
6
|
+
# a timeout option on the lock.
|
7
|
+
#
|
8
|
+
# This will be part of the main Logstash's sized queue
|
9
|
+
class SizedQueueTimeout
|
10
|
+
class TimeoutError < StandardError; end
|
11
|
+
|
12
|
+
DEFAULT_TIMEOUT = 2 # in seconds
|
13
|
+
|
14
|
+
def initialize(max_size, options = {})
|
15
|
+
@condition_in = Concurrent::Condition.new
|
16
|
+
@condition_out = Concurrent::Condition.new
|
17
|
+
|
18
|
+
@max_size = max_size
|
19
|
+
@queue = []
|
20
|
+
@mutex = Mutex.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def push(obj, timeout = DEFAULT_TIMEOUT)
|
24
|
+
@mutex.synchronize do
|
25
|
+
while full? # wake up check
|
26
|
+
result = @condition_out.wait(@mutex, timeout)
|
27
|
+
raise TimeoutError if result.timed_out?
|
28
|
+
end
|
29
|
+
|
30
|
+
@queue << obj
|
31
|
+
@condition_in.signal
|
32
|
+
|
33
|
+
return obj
|
34
|
+
end
|
35
|
+
end
|
36
|
+
alias_method :<<, :push
|
37
|
+
|
38
|
+
def size
|
39
|
+
@mutex.synchronize { @queue.size }
|
40
|
+
end
|
41
|
+
|
42
|
+
def pop_no_timeout
|
43
|
+
@mutex.synchronize do
|
44
|
+
@condition_in.wait(@mutex) while @queue.empty? # Wake up check
|
45
|
+
|
46
|
+
obj = @queue.shift
|
47
|
+
@condition_out.signal
|
48
|
+
|
49
|
+
return obj
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
def full?
|
55
|
+
@queue.size == @max_size
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-input-lumberjack'
|
4
|
-
s.version = '0.1.
|
4
|
+
s.version = '0.1.10'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Receive events using the lumberjack protocol."
|
7
7
|
s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
|
@@ -29,5 +29,7 @@ Gem::Specification.new do |s|
|
|
29
29
|
s.add_development_dependency 'logstash-devutils'
|
30
30
|
s.add_development_dependency 'stud'
|
31
31
|
s.add_development_dependency 'logstash-codec-multiline'
|
32
|
+
s.add_development_dependency "flores"
|
33
|
+
s.add_development_dependency "stud"
|
32
34
|
end
|
33
35
|
|
@@ -6,7 +6,6 @@ require "logstash/codecs/plain"
|
|
6
6
|
require "logstash/codecs/multiline"
|
7
7
|
require "logstash/event"
|
8
8
|
require "lumberjack/client"
|
9
|
-
require_relative "../support/logstash_test"
|
10
9
|
|
11
10
|
describe LogStash::Inputs::Lumberjack do
|
12
11
|
let(:connection) { double("connection") }
|
@@ -47,58 +46,4 @@ describe LogStash::Inputs::Lumberjack do
|
|
47
46
|
end
|
48
47
|
end
|
49
48
|
end
|
50
|
-
|
51
|
-
context "when we have the maximum clients connected" do
|
52
|
-
let(:max_clients) { 1 }
|
53
|
-
let(:window_size) { 1 }
|
54
|
-
let(:config) do
|
55
|
-
{
|
56
|
-
"port" => port,
|
57
|
-
"ssl_certificate" => certificate.ssl_cert,
|
58
|
-
"ssl_key" => certificate.ssl_key,
|
59
|
-
"type" => "testing",
|
60
|
-
"max_clients" => max_clients
|
61
|
-
}
|
62
|
-
end
|
63
|
-
|
64
|
-
let(:client_options) do
|
65
|
-
{
|
66
|
-
:port => port,
|
67
|
-
:address => "127.0.0.1",
|
68
|
-
:ssl_certificate => certificate.ssl_cert,
|
69
|
-
:window_size => window_size
|
70
|
-
}
|
71
|
-
end
|
72
|
-
|
73
|
-
before do
|
74
|
-
lumberjack.register
|
75
|
-
|
76
|
-
@server = Thread.new do
|
77
|
-
lumberjack.run(queue)
|
78
|
-
end
|
79
|
-
|
80
|
-
sleep(0.1) # wait for the server to correctly accept messages
|
81
|
-
end
|
82
|
-
|
83
|
-
after do
|
84
|
-
@server.raise(LogStash::ShutdownSignal)
|
85
|
-
@server.join
|
86
|
-
end
|
87
|
-
|
88
|
-
it "stops accepting new connection" do
|
89
|
-
client1 = Lumberjack::Socket.new(client_options)
|
90
|
-
|
91
|
-
# Since the connection is stopped on the other side and OS X and
|
92
|
-
# linux doesn't behave the same. The client could raise a IOError
|
93
|
-
# or an SSLError. On OSX I had to try to send some data to trip
|
94
|
-
# the error.
|
95
|
-
expect {
|
96
|
-
client2 = Lumberjack::Socket.new(client_options)
|
97
|
-
|
98
|
-
(window_size + 1).times do
|
99
|
-
client2.write_hash({"line" => "message"})
|
100
|
-
end
|
101
|
-
}.to raise_error
|
102
|
-
end
|
103
|
-
end
|
104
49
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "logstash/circuit_breaker"
|
3
|
+
|
4
|
+
class DummyErrorTest < StandardError; end
|
5
|
+
|
6
|
+
describe LogStash::CircuitBreaker do
|
7
|
+
let(:error_threshold) { 1 }
|
8
|
+
let(:options) do
|
9
|
+
{
|
10
|
+
:exceptions => [DummyErrorTest],
|
11
|
+
:error_threshold => error_threshold
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
subject { LogStash::CircuitBreaker.new("testing", options) }
|
16
|
+
|
17
|
+
|
18
|
+
it "closed by default" do
|
19
|
+
expect(subject.closed?).to eq(true)
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when having too many errors" do
|
23
|
+
let(:future_time) { Time.now + 3600 }
|
24
|
+
before do
|
25
|
+
subject.execute do
|
26
|
+
raise DummyErrorTest
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "raised an exception if we have too many errors" do
|
31
|
+
expect {
|
32
|
+
subject.execute do
|
33
|
+
raise DummyErrorTest
|
34
|
+
end
|
35
|
+
}.to raise_error(LogStash::CircuitBreaker::OpenBreaker)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "sets the breaker to open" do
|
39
|
+
expect(subject.closed?).to eq(false)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "resets the breaker after the time before retry" do
|
43
|
+
expect(Time).to receive(:now).at_least(1).and_return(future_time)
|
44
|
+
expect(subject.closed?).to eq(true)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "doesnt run the command" do
|
48
|
+
runned = false
|
49
|
+
|
50
|
+
begin
|
51
|
+
subject.execute do
|
52
|
+
runned = true
|
53
|
+
end
|
54
|
+
rescue LogStash::CircuitBreaker::OpenBreaker
|
55
|
+
end
|
56
|
+
|
57
|
+
expect(runned).to eq(false)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "logstash/sized_queue_timeout"
|
3
|
+
require "flores/random"
|
4
|
+
require "stud/try"
|
5
|
+
|
6
|
+
describe "LogStash::SizedQueueTimeout" do
|
7
|
+
let(:max_size) { Flores::Random.integer(2..100) }
|
8
|
+
let(:element) { Flores::Random.text(0..100) }
|
9
|
+
|
10
|
+
subject { LogStash::SizedQueueTimeout.new(max_size) }
|
11
|
+
|
12
|
+
it "adds element to the queue" do
|
13
|
+
subject << element
|
14
|
+
expect(subject.size).to eq(1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "allow to pop element from the queue" do
|
18
|
+
subject << element
|
19
|
+
subject << "awesome"
|
20
|
+
|
21
|
+
expect(subject.pop_no_timeout).to eq(element)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when the queue is full" do
|
25
|
+
before do
|
26
|
+
max_size.times { subject << element }
|
27
|
+
end
|
28
|
+
|
29
|
+
it "block with a timeout" do
|
30
|
+
expect {
|
31
|
+
subject << element
|
32
|
+
}.to raise_error(LogStash::SizedQueueTimeout::TimeoutError)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "unblock when we pop" do
|
36
|
+
blocked = Thread.new do
|
37
|
+
subject << element
|
38
|
+
end
|
39
|
+
sleep(0.1) until blocked.stop?
|
40
|
+
|
41
|
+
expect(blocked.status).to eq("sleep")
|
42
|
+
|
43
|
+
th = Thread.new do
|
44
|
+
subject.pop_no_timeout
|
45
|
+
end
|
46
|
+
sleep(0.1) until th.stop?
|
47
|
+
|
48
|
+
expect(blocked.status).to eq(false)
|
49
|
+
|
50
|
+
blocked.join
|
51
|
+
th.join
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when the queue is empty" do
|
56
|
+
it "block on pop" do
|
57
|
+
blocked = Thread.new do
|
58
|
+
subject.pop_no_timeout
|
59
|
+
end
|
60
|
+
sleep(0.1) until blocked.stop?
|
61
|
+
|
62
|
+
expect(blocked.status).to eq("sleep")
|
63
|
+
|
64
|
+
th = Thread.new do
|
65
|
+
subject << element
|
66
|
+
end
|
67
|
+
sleep(0.1) until th.stop?
|
68
|
+
|
69
|
+
expect(blocked.status).to eq(false)
|
70
|
+
th.join
|
71
|
+
blocked.join
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when the queue is occupied but not full" do
|
76
|
+
before :each do
|
77
|
+
Flores::Random.iterations(0..max_size) { subject << "hurray" }
|
78
|
+
end
|
79
|
+
|
80
|
+
it "doesnt block on pop" do
|
81
|
+
th = Thread.new do
|
82
|
+
subject.pop_no_timeout
|
83
|
+
end
|
84
|
+
sleep(0.1) until th.stop?
|
85
|
+
|
86
|
+
expect(th.status).to eq(false)
|
87
|
+
th.join
|
88
|
+
end
|
89
|
+
|
90
|
+
it "doesnt block on push" do
|
91
|
+
th = Thread.new do
|
92
|
+
subject << element
|
93
|
+
end
|
94
|
+
sleep(0.1) until th.stop?
|
95
|
+
|
96
|
+
expect(th.status).to eq(false)
|
97
|
+
th.join
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-lumberjack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logstash-core
|
@@ -114,6 +114,34 @@ dependencies:
|
|
114
114
|
version: '0'
|
115
115
|
prerelease: false
|
116
116
|
type: :development
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: flores
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - '>='
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirement: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
prerelease: false
|
130
|
+
type: :development
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: stud
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
requirement: !ruby/object:Gem::Requirement
|
139
|
+
requirements:
|
140
|
+
- - '>='
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: '0'
|
143
|
+
prerelease: false
|
144
|
+
type: :development
|
117
145
|
description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
|
118
146
|
email: info@elastic.co
|
119
147
|
executables: []
|
@@ -125,11 +153,16 @@ files:
|
|
125
153
|
- CONTRIBUTORS
|
126
154
|
- Gemfile
|
127
155
|
- LICENSE
|
156
|
+
- NOTICE.TXT
|
128
157
|
- README.md
|
129
158
|
- Rakefile
|
159
|
+
- lib/logstash/circuit_breaker.rb
|
130
160
|
- lib/logstash/inputs/lumberjack.rb
|
161
|
+
- lib/logstash/sized_queue_timeout.rb
|
131
162
|
- logstash-input-lumberjack.gemspec
|
132
163
|
- spec/inputs/lumberjack_spec.rb
|
164
|
+
- spec/logstash/circuit_breaker_spec.rb
|
165
|
+
- spec/logstash/size_queue_timeout_spec.rb
|
133
166
|
- spec/spec_helper.rb
|
134
167
|
- spec/support/logstash_test.rb
|
135
168
|
homepage: http://www.elastic.co/guide/en/logstash/current/index.html
|
@@ -160,5 +193,7 @@ specification_version: 4
|
|
160
193
|
summary: Receive events using the lumberjack protocol.
|
161
194
|
test_files:
|
162
195
|
- spec/inputs/lumberjack_spec.rb
|
196
|
+
- spec/logstash/circuit_breaker_spec.rb
|
197
|
+
- spec/logstash/size_queue_timeout_spec.rb
|
163
198
|
- spec/spec_helper.rb
|
164
199
|
- spec/support/logstash_test.rb
|