logstash-input-bunny 0.1.11 → 0.1.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/logstash/inputs/bunny.rb +139 -148
- data/logstash-input-bunny.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5c4dbbe89ddbb17aeacca3faecf3647eecced04
|
4
|
+
data.tar.gz: 645754ffc7b545fd97188364d5e556e1fd0474c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f64cf8c7e46897dee3c0245452045deb1589f1bd7d08e9e1f21ab8c78848177ccb6876d67a32cf99c342f787f04b66fa7e8bc71f275392285d27fd6a7e454bc4
|
7
|
+
data.tar.gz: b2371829cd2ea89ea4d5e8c9e51f40414bf1cac3dca0ed7bcaf96b658a29715e35b51ced95b581fd2a74b2b9d72854c53cac3804378408309441b5eca8437740
|
@@ -13,222 +13,213 @@ require "logstash/inputs/rabbitmq/bunny"
|
|
13
13
|
#
|
14
14
|
# * Bunny - <https://github.com/ruby-amqp/bunny>
|
15
15
|
class LogStash::Inputs::Bunny < LogStash::Inputs::Threadable
|
16
|
-
|
17
16
|
config_name "bunny"
|
18
17
|
|
19
18
|
#
|
20
19
|
# Connection
|
21
20
|
#
|
22
21
|
|
23
|
-
|
24
|
-
config :
|
25
|
-
|
26
|
-
|
27
|
-
config :
|
28
|
-
|
29
|
-
# RabbitMQ username
|
30
|
-
config :user, :validate => :string, :default => "guest"
|
31
|
-
|
32
|
-
# RabbitMQ password
|
33
|
-
config :password, :validate => :password, :default => "guest"
|
22
|
+
config :host, validate: :string, required: true
|
23
|
+
config :port, validate: :number, default: 5672
|
24
|
+
config :user, validate: :string, default: "guest"
|
25
|
+
config :password, validate: :password, default: "guest"
|
26
|
+
config :vhost, validate: :string, default: "/"
|
34
27
|
|
35
|
-
|
36
|
-
config :
|
28
|
+
config :ssl, validate: :boolean, :default => false
|
29
|
+
config :ssl_cert, validate: :string
|
30
|
+
config :ssl_key, validate: :string
|
31
|
+
config :ssl_ca_cert, validate: :string
|
32
|
+
config :verify_peer, validate: :boolean, default: false
|
37
33
|
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
config :ssl_key, :validate => :string
|
42
|
-
config :ssl_ca_cert, :validate => :string
|
43
|
-
|
44
|
-
# Validate SSL certificate
|
45
|
-
config :verify_ssl, :validate => :boolean, :default => false
|
46
|
-
config :verify_peer, :validate => :boolean, :default => false
|
34
|
+
#
|
35
|
+
# Queue & Consumer
|
36
|
+
#
|
47
37
|
|
48
|
-
#
|
49
|
-
|
38
|
+
#
|
39
|
+
# The Bunny plugin's approach differs from Logstash's RabbitMQ plugin in that
|
40
|
+
# we require an exchange so that we can create & bind multiple queues based
|
41
|
+
# on routing keys.
|
42
|
+
#
|
43
|
+
# In addition, rather than accepting a single string for the queue, we now
|
44
|
+
# accept a hash of queue > routing_key pairs.
|
45
|
+
#
|
50
46
|
|
47
|
+
config :exchange, validate: :string, required: true
|
48
|
+
config :queues, validate: :hash, required: true
|
51
49
|
|
50
|
+
config :prefetch, validate: :number, default: 20
|
51
|
+
config :ack, validate: :boolean, default: true
|
52
52
|
|
53
53
|
#
|
54
|
-
# Queue
|
54
|
+
# Queue Durability / Persistence
|
55
55
|
#
|
56
56
|
|
57
|
-
#
|
58
|
-
config :
|
57
|
+
# Create durable queues so that they survive broker restarts
|
58
|
+
config :durable, validate: :boolean, default: false
|
59
59
|
|
60
|
-
#
|
61
|
-
config :
|
62
|
-
|
63
|
-
# Should the queue be deleted on the broker when the last consumer
|
64
|
-
# disconnects? Set this option to `false` if you want the queue to remain
|
65
|
-
# on the broker, queueing up messages until a consumer comes along to
|
66
|
-
# consume them.
|
67
|
-
config :auto_delete, :validate => :boolean, :default => false
|
60
|
+
# Delete queues once the last consumer disconnects.
|
61
|
+
config :auto_delete, validate: :boolean, default: false
|
68
62
|
|
69
63
|
# Is the queue exclusive? Exclusive queues can only be used by the connection
|
70
64
|
# that declared them and will be deleted when it is closed (e.g. due to a Logstash
|
71
65
|
# restart).
|
72
|
-
config :exclusive,
|
73
|
-
|
74
|
-
# Extra queue arguments as an array.
|
75
|
-
# To make a RabbitMQ queue mirrored, use: `{"x-ha-policy" => "all"}`
|
76
|
-
config :arguments, :validate => :array, :default => {}
|
66
|
+
config :exclusive, validate: :boolean, default: false
|
77
67
|
|
78
|
-
#
|
79
|
-
config :
|
68
|
+
# Passive queue creation? Useful for checking queue existance without modifying server state
|
69
|
+
config :passive, validate: :boolean, default: false
|
80
70
|
|
81
|
-
#
|
82
|
-
|
71
|
+
#
|
72
|
+
# Initialization
|
73
|
+
#
|
83
74
|
|
84
|
-
|
85
|
-
|
75
|
+
def initialize(params)
|
76
|
+
params["codec"] = "json" if !params["codec"]
|
77
|
+
super
|
78
|
+
end
|
86
79
|
|
80
|
+
def input_tag
|
81
|
+
"#{@vhost}/#{@exchange}"
|
82
|
+
end
|
87
83
|
|
84
|
+
def message(severity, message, data={})
|
85
|
+
message = "Bunny[#{input_tag}] #{message}"
|
86
|
+
@logger.send(severity, message, data)
|
87
|
+
end
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
#
|
89
|
+
def register
|
90
|
+
require "bunny"
|
92
91
|
|
93
|
-
|
94
|
-
#
|
95
|
-
# The name of the exchange to bind the queue to.
|
96
|
-
config :exchange, :validate => :string
|
92
|
+
message(:info, "registering input", host: @host)
|
97
93
|
|
98
|
-
|
99
|
-
|
100
|
-
# The routing key to use when binding a queue to the exchange.
|
101
|
-
# This is only relevant for direct or topic exchanges.
|
102
|
-
#
|
103
|
-
# * Routing keys are ignored on fanout exchanges.
|
104
|
-
# * Wildcards are not valid on direct exchanges.
|
105
|
-
config :key, :validate => :string, :default => "logstash"
|
94
|
+
@vhost ||= Bunny::DEFAULT_HOST
|
95
|
+
@port ||= AMQ::Protocol::DEFAULT_PORT
|
106
96
|
|
97
|
+
@settings = {
|
98
|
+
vhost: @vhost,
|
99
|
+
host: @host,
|
100
|
+
port: @port,
|
101
|
+
user: @user,
|
102
|
+
pass: @password.value,
|
103
|
+
tls: @ssl,
|
104
|
+
automatically_recover: false
|
105
|
+
}
|
107
106
|
|
108
|
-
|
109
|
-
|
107
|
+
if @ssl
|
108
|
+
@settings[:verify_peer] = @verify_peer
|
109
|
+
end
|
110
110
|
|
111
|
-
|
111
|
+
if @ssl and @ssl_cert
|
112
|
+
@settings[:tls_cert] = @ssl_cert
|
113
|
+
@settings[:tls_key] = @ssl_key
|
114
|
+
@settings[:tls_ca_certificates] = [@ssl_ca_cert] if @ssl_ca_cert
|
115
|
+
end
|
112
116
|
end
|
113
117
|
|
114
|
-
include ::LogStash::Inputs::RabbitMQ::BunnyImpl
|
115
|
-
|
116
118
|
def run(output_queue)
|
117
119
|
@output_queue = output_queue
|
120
|
+
delay = Bunny::Session::DEFAULT_NETWORK_RECOVERY_INTERVAL * 2
|
118
121
|
|
119
122
|
begin
|
120
123
|
setup
|
121
124
|
consume
|
122
|
-
rescue Bunny::NetworkFailure, Bunny::ConnectionClosedError,
|
123
|
-
Bunny::ConnectionLevelException, Bunny::TCPConnectionFailed
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
@logger.error("RabbitMQ[#{input_name}] connection error: #{e.message}. Will attempt to reconnect in #{n} seconds...")
|
132
|
-
|
133
|
-
sleep n
|
134
|
-
retry
|
135
|
-
|
136
|
-
rescue OpenSSL::SSL::SSLError => e
|
137
|
-
n = Bunny::Session::DEFAULT_NETWORK_RECOVERY_INTERVAL * 2
|
125
|
+
rescue Bunny::NetworkFailure, Bunny::ConnectionClosedError,
|
126
|
+
Bunny::ConnectionLevelException, Bunny::TCPConnectionFailed,
|
127
|
+
OpenSSL::SSL::SSLError => e
|
128
|
+
|
129
|
+
@consumers.each do |name, consumer|
|
130
|
+
error = "connection error: #{e.message}. Retrying in #{delay} seconds."
|
131
|
+
message(:error, error)
|
132
|
+
consumer.channel.maybe_kill_consumer_work_pool!
|
133
|
+
end
|
138
134
|
|
139
|
-
|
140
|
-
sleep n
|
135
|
+
sleep delay
|
141
136
|
retry
|
142
137
|
|
143
138
|
rescue LogStash::ShutdownSignal
|
144
|
-
|
145
|
-
|
146
|
-
rescue Exception => e
|
147
|
-
@logger.error("RabbitMQ[#{input_name}] unhandled exception: #{e.inspect}")
|
148
|
-
@logger.error(e.backtrace)
|
149
|
-
end
|
150
|
-
end
|
139
|
+
release
|
151
140
|
|
152
|
-
|
153
|
-
|
141
|
+
rescue Exception => e
|
142
|
+
message(:error, "unhandled exception: #{e.inspect}", backtrace: e.backtrace)
|
154
143
|
|
155
|
-
if @ssl and @ssl_cert
|
156
|
-
@settings[:tls_cert] = @ssl_cert
|
157
|
-
@settings[:tls_key] = @ssl_key
|
158
|
-
@settings[:tls_ca_certificates] = [@ssl_ca_cert] if @ssl_ca_cert
|
159
|
-
@settings[:verify_peer] = @verify_peer
|
160
144
|
end
|
161
145
|
end
|
162
146
|
|
163
147
|
def teardown
|
164
|
-
|
165
|
-
@ch.close if @ch && @ch.open?
|
166
|
-
@conn.close if @conn && @conn.open?
|
148
|
+
release
|
167
149
|
finished
|
168
150
|
end
|
169
151
|
|
170
|
-
protected
|
171
|
-
|
172
|
-
def consumer_id
|
173
|
-
@consumer_id ||= "#{`hostname -s`.strip}-#{Thread.current.object_id}"
|
174
|
-
end
|
175
|
-
|
176
|
-
def input_name
|
177
|
-
@exchange.nil? or @key.nil? ? queue : "#{@exchange}:#{@key}"
|
178
|
-
end
|
179
|
-
|
180
152
|
def setup
|
181
153
|
return if terminating?
|
182
154
|
|
155
|
+
#
|
156
|
+
# With multiple threads, Logstash/Jruby/Bunny combo seems to fail ssl
|
157
|
+
# handshake on the first 1-2 connection attempts when restarting Logstash.
|
158
|
+
#
|
159
|
+
# optionally, look at : settings[:connect_timeout]
|
160
|
+
#
|
183
161
|
begin
|
184
|
-
|
185
|
-
|
186
|
-
@
|
187
|
-
@
|
188
|
-
@conn.start
|
162
|
+
connection_attempt ||= 1
|
163
|
+
message(:debug, "connecting")
|
164
|
+
@connection = Bunny.new(@settings)
|
165
|
+
@connection.start
|
189
166
|
rescue OpenSSL::SSL::SSLError
|
190
|
-
|
191
|
-
|
192
|
-
|
167
|
+
message(:warn, "ssl handshake failed, retrying",
|
168
|
+
attempt: connection_attempt)
|
169
|
+
connection_attempt += 1
|
170
|
+
retry unless connection_attempt > 3
|
193
171
|
end
|
194
172
|
|
195
|
-
@
|
196
|
-
@
|
197
|
-
|
198
|
-
|
173
|
+
@consumers = {}
|
174
|
+
@queues.each do |queue_name, routing_key|
|
175
|
+
consumer = "#{queue_name}#{routing_key}"
|
176
|
+
message(:debug, "creating consumer #{consumer}")
|
177
|
+
|
178
|
+
channel = @connection.create_channel.tap do |channel|
|
179
|
+
channel.prefetch(@prefetch)
|
180
|
+
end
|
181
|
+
|
182
|
+
queue = channel.queue(@queue,
|
183
|
+
durable: @durable,
|
184
|
+
auto_delete: @auto_delete,
|
185
|
+
exclusive: @exclusive,
|
186
|
+
passive: @passive)
|
187
|
+
|
188
|
+
queue.bind(@exchange, routing_key: routing_key)
|
199
189
|
|
200
|
-
|
201
|
-
|
202
|
-
:durable => @durable,
|
203
|
-
:auto_delete => @auto_delete,
|
204
|
-
:exclusive => @exclusive,
|
205
|
-
:passive => @passive,
|
206
|
-
:arguments => @arguments)
|
207
|
-
|
208
|
-
# exchange binding is optional for the input
|
209
|
-
if @exchange
|
210
|
-
@q.bind(@exchange, :routing_key => @key)
|
190
|
+
@consumers[consumer] = Bunny::Consumer.
|
191
|
+
new(channel, queue, nil, !@ack, @exclusive)
|
211
192
|
end
|
212
193
|
end
|
213
194
|
|
214
|
-
def
|
215
|
-
@
|
195
|
+
def release
|
196
|
+
@consumers.each do |name, consumer|
|
197
|
+
consumer.cancel
|
198
|
+
consumer.channel.close if consumer.channel and consumer.channel.open?
|
199
|
+
end
|
200
|
+
@consumers = []
|
216
201
|
|
217
|
-
|
218
|
-
|
202
|
+
@connection.close if @connection and @connection.open?
|
203
|
+
end
|
219
204
|
|
220
|
-
|
221
|
-
@
|
222
|
-
|
223
|
-
|
224
|
-
|
205
|
+
def consume
|
206
|
+
@consumers.each do |name, consumer|
|
207
|
+
message(:info, "consuming events from #{name}")
|
208
|
+
|
209
|
+
consumer.on_delivery do |delivery_info, properties, data|
|
210
|
+
@codec.decode(data) do |event|
|
211
|
+
decorate(event)
|
212
|
+
event["bunny"] ||= {}
|
213
|
+
event["bunny"]["key"] = delivery_info.routing_key
|
214
|
+
event["bunny"]["queue"] = consumer.queue_name
|
215
|
+
@output_queue << event
|
216
|
+
end
|
217
|
+
|
218
|
+
consumer.channel.acknowledge(delivery_info.delivery_tag) if @ack
|
225
219
|
end
|
226
220
|
|
227
|
-
|
221
|
+
consumer.queue.subscribe_with(consumer, block: true)
|
228
222
|
end
|
229
|
-
|
230
|
-
@q.subscribe_with(@consumer, block: true)
|
231
223
|
end
|
232
|
-
|
233
224
|
end # class LogStash::Inputs::RabbitMQ
|
234
225
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-input-bunny'
|
4
|
-
s.version = '0.1.
|
4
|
+
s.version = '0.1.12'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "Pull events from a RabbitMQ exchange."
|
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"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-input-bunny
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Serafini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logstash-core
|