logstash-input-redis_cluster 1.0.0
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 +7 -0
- data/CHANGELOG.md +89 -0
- data/CONTRIBUTORS +22 -0
- data/Gemfile +10 -0
- data/LICENSE +202 -0
- data/NOTICE.TXT +5 -0
- data/README.md +99 -0
- data/docs/index.asciidoc +175 -0
- data/lib/logstash/inputs/redis_cluster.rb +395 -0
- data/logstash-input-redis_cluster.gemspec +31 -0
- data/spec/inputs/redis_cluster_spec.rb +478 -0
- metadata +139 -0
@@ -0,0 +1,478 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'logstash/devutils/rspec/shared_examples'
|
3
|
+
require "logstash/devutils/rspec/spec_helper"
|
4
|
+
require 'logstash/inputs/redis_cluster'
|
5
|
+
require 'securerandom'
|
6
|
+
|
7
|
+
def populate(key, event_count)
|
8
|
+
require "logstash/event"
|
9
|
+
require "redis"
|
10
|
+
require "stud/try"
|
11
|
+
redis = RedisClient.cluster(nodes: [
|
12
|
+
"redis://host.docker.internal:7000",
|
13
|
+
"redis://host.docker.internal:7001",
|
14
|
+
"redis://host.docker.internal:7002"
|
15
|
+
], fixed_hostname: "host.docker.internal").new_client
|
16
|
+
event_count.times do |value|
|
17
|
+
event = LogStash::Event.new("sequence" => value)
|
18
|
+
Stud.try(10.times) do
|
19
|
+
redis.rpush(key, event.to_json)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def process(conf, event_count)
|
25
|
+
events = input(conf) do |_, queue|
|
26
|
+
sleep 0.1 until queue.size >= event_count
|
27
|
+
queue.size.times.map { queue.pop }
|
28
|
+
end
|
29
|
+
# due multiple workers we get events out-of-order in the output
|
30
|
+
events.sort! { |a, b| a.get('sequence') <=> b.get('sequence') }
|
31
|
+
expect(events[0].get('sequence')).to eq(0)
|
32
|
+
expect(events[100].get('sequence')).to eq(100)
|
33
|
+
expect(events[1000].get('sequence')).to eq(1000)
|
34
|
+
end
|
35
|
+
|
36
|
+
# integration tests ---------------------
|
37
|
+
|
38
|
+
describe LogStash::Inputs::RedisCluster do
|
39
|
+
|
40
|
+
it_behaves_like "an interruptible input plugin" do
|
41
|
+
key = SecureRandom.hex
|
42
|
+
let(:config) { {
|
43
|
+
"type" => "blah",
|
44
|
+
"fixed_hostname" => "host.docker.internal",
|
45
|
+
"nodes" => [
|
46
|
+
"redis://host.docker.internal:7000",
|
47
|
+
"redis://host.docker.internal:7001",
|
48
|
+
"redis://host.docker.internal:7002"
|
49
|
+
],
|
50
|
+
"key" => "#{key}",
|
51
|
+
"data_type" => "list",
|
52
|
+
}
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
context "should read events from a list" do
|
57
|
+
key = SecureRandom.hex
|
58
|
+
event_count = 1000 + rand(50)
|
59
|
+
let(:config) { {
|
60
|
+
"type" => "blah",
|
61
|
+
"fixed_hostname" => "host.docker.internal",
|
62
|
+
"nodes" => [
|
63
|
+
"redis://host.docker.internal:7000",
|
64
|
+
"redis://host.docker.internal:7001",
|
65
|
+
"redis://host.docker.internal:7002"
|
66
|
+
],
|
67
|
+
"key" => "#{key}",
|
68
|
+
"data_type" => "list",
|
69
|
+
"batch_count" => 1
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
populate(key, event_count)
|
74
|
+
# process(conf, event_count)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should read events from a list using batch_count (default 125)" do
|
78
|
+
key = SecureRandom.hex
|
79
|
+
event_count = 1000 + rand(50)
|
80
|
+
conf = <<-CONFIG
|
81
|
+
input {
|
82
|
+
redis_cluster {
|
83
|
+
type => "blah"
|
84
|
+
fixed_hostname => "host.docker.internal"
|
85
|
+
nodes => [
|
86
|
+
"redis://host.docker.internal:7000",
|
87
|
+
"redis://host.docker.internal:7001",
|
88
|
+
"redis://host.docker.internal:7002"
|
89
|
+
]
|
90
|
+
key => "#{key}"
|
91
|
+
data_type => "list"
|
92
|
+
}
|
93
|
+
}
|
94
|
+
CONFIG
|
95
|
+
|
96
|
+
populate(key, event_count)
|
97
|
+
# process(conf, event_count)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# describe LogStash::Inputs::Redis do
|
102
|
+
# let(:queue) { Queue.new }
|
103
|
+
|
104
|
+
# let(:data_type) { 'list' }
|
105
|
+
# let(:batch_count) { 1 }
|
106
|
+
# let(:config) { {'key' => 'foo', 'data_type' => data_type, 'batch_count' => batch_count} }
|
107
|
+
# let(:quit_calls) { [:quit] }
|
108
|
+
|
109
|
+
# subject do
|
110
|
+
# LogStash::Inputs::Redis.new(config)
|
111
|
+
# end
|
112
|
+
|
113
|
+
# context 'construction' do
|
114
|
+
# it 'registers the input' do
|
115
|
+
# expect { subject.register }.not_to raise_error
|
116
|
+
# end
|
117
|
+
# end
|
118
|
+
|
119
|
+
# context 'renamed redis commands' do
|
120
|
+
# let(:config) do
|
121
|
+
# {
|
122
|
+
# 'key' => 'foo',
|
123
|
+
# 'data_type' => data_type,
|
124
|
+
# 'command_map' => {
|
125
|
+
# 'blpop' => 'testblpop',
|
126
|
+
# 'evalsha' => 'testevalsha',
|
127
|
+
# 'lrange' => 'testlrange',
|
128
|
+
# 'ltrim' => 'testltrim',
|
129
|
+
# 'script' => 'testscript',
|
130
|
+
# 'subscribe' => 'testsubscribe',
|
131
|
+
# 'psubscribe' => 'testpsubscribe',
|
132
|
+
# },
|
133
|
+
# 'batch_count' => 2
|
134
|
+
# }
|
135
|
+
# end
|
136
|
+
|
137
|
+
# it 'sets the renamed commands in the command map' do
|
138
|
+
# allow_any_instance_of( Redis::Client ).to receive(:call) do |_, command|
|
139
|
+
# expect(command[0]).to eql :script
|
140
|
+
# expect(command[1]).to eql 'load'
|
141
|
+
# end
|
142
|
+
|
143
|
+
# subject.register
|
144
|
+
# redis = subject.send :connect
|
145
|
+
|
146
|
+
# command_map = redis._client.command_map
|
147
|
+
|
148
|
+
# expect(command_map[:blpop]).to eq config['command_map']['blpop'].to_sym
|
149
|
+
# expect(command_map[:evalsha]).to eq config['command_map']['evalsha'].to_sym
|
150
|
+
# expect(command_map[:lrange]).to eq config['command_map']['lrange'].to_sym
|
151
|
+
# expect(command_map[:ltrim]).to eq config['command_map']['ltrim'].to_sym
|
152
|
+
# expect(command_map[:script]).to eq config['command_map']['script'].to_sym
|
153
|
+
# expect(command_map[:subscribe]).to eq config['command_map']['subscribe'].to_sym
|
154
|
+
# expect(command_map[:psubscribe]).to eq config['command_map']['psubscribe'].to_sym
|
155
|
+
# end
|
156
|
+
|
157
|
+
# it 'loads the batch script with the renamed command' do
|
158
|
+
# expect_any_instance_of( Redis::Client ).to receive(:call) do |_, command|
|
159
|
+
# expect(command[0]).to eql :script
|
160
|
+
# expect(command[1]).to eql 'load'
|
161
|
+
|
162
|
+
# script = command[2]
|
163
|
+
# expect(script).to include "redis.call('#{config['command_map']['lrange']}', KEYS[1], 0, batchsize)"
|
164
|
+
# expect(script).to include "redis.call('#{config['command_map']['ltrim']}', KEYS[1], batchsize + 1, -1)"
|
165
|
+
# end
|
166
|
+
|
167
|
+
# subject.register
|
168
|
+
# subject.send :connect
|
169
|
+
# end
|
170
|
+
# end
|
171
|
+
|
172
|
+
# context 'runtime for list data_type' do
|
173
|
+
|
174
|
+
# before do
|
175
|
+
# subject.register
|
176
|
+
# allow_any_instance_of( Redis::Client ).to receive(:connected?).and_return true
|
177
|
+
# allow_any_instance_of( Redis::Client ).to receive(:disconnect)
|
178
|
+
# allow_any_instance_of( Redis ).to receive(:quit)
|
179
|
+
# end
|
180
|
+
|
181
|
+
# after do
|
182
|
+
# subject.stop
|
183
|
+
# end
|
184
|
+
|
185
|
+
# context 'close when redis is unset' do
|
186
|
+
|
187
|
+
# it 'does not attempt to quit' do
|
188
|
+
# expect_any_instance_of( Redis::Client ).to_not receive(:call)
|
189
|
+
# expect_any_instance_of( Redis::Client ).to_not receive(:disconnect)
|
190
|
+
|
191
|
+
# expect { subject.do_stop }.not_to raise_error
|
192
|
+
# end
|
193
|
+
# end
|
194
|
+
|
195
|
+
# it 'calling the run method, adds events to the queue' do
|
196
|
+
# allow_any_instance_of( Redis::Client ).to receive(:call_with_timeout) do |_, command, timeout, &block|
|
197
|
+
# expect(command[0]).to eql :blpop
|
198
|
+
# expect(command[1]).to eql ['foo', 0]
|
199
|
+
# end.and_return ['foo', "{\"foo1\":\"bar\""], nil
|
200
|
+
|
201
|
+
# tt = Thread.new do
|
202
|
+
# sleep 0.25
|
203
|
+
# subject.do_stop
|
204
|
+
# end
|
205
|
+
|
206
|
+
# subject.run(queue)
|
207
|
+
|
208
|
+
# tt.join
|
209
|
+
|
210
|
+
# expect( queue.size ).to be > 0
|
211
|
+
# end
|
212
|
+
|
213
|
+
# it 'keeps running when a connection error occurs' do
|
214
|
+
# raised = false
|
215
|
+
# allow_any_instance_of( Redis::Client ).to receive(:call_with_timeout) do |_, command, timeout, &block|
|
216
|
+
# expect(command[0]).to eql :blpop
|
217
|
+
# unless raised
|
218
|
+
# raised = true
|
219
|
+
# raise Redis::CannotConnectError.new('test')
|
220
|
+
# end
|
221
|
+
# ['foo', "{\"after\":\"raise\"}"]
|
222
|
+
# end
|
223
|
+
|
224
|
+
# expect(subject.logger).to receive(:warn).with('Redis connection error',
|
225
|
+
# hash_including(:message=>"test", :exception=>Redis::CannotConnectError)
|
226
|
+
# ).and_call_original
|
227
|
+
|
228
|
+
# tt = Thread.new do
|
229
|
+
# sleep 2.0 # allow for retry (sleep) after handle_error
|
230
|
+
# subject.do_stop
|
231
|
+
# end
|
232
|
+
|
233
|
+
# subject.run(queue)
|
234
|
+
|
235
|
+
# tt.join
|
236
|
+
|
237
|
+
# try(3) { expect( queue.size ).to be > 0 }
|
238
|
+
# end
|
239
|
+
|
240
|
+
# context 'error handling' do
|
241
|
+
|
242
|
+
# let(:config) do
|
243
|
+
# super().merge 'batch_count' => 2
|
244
|
+
# end
|
245
|
+
|
246
|
+
# it 'keeps running when a (non-Redis) io error occurs' do
|
247
|
+
# raised = false
|
248
|
+
# allow(subject).to receive(:connect).and_return redis = double('redis')
|
249
|
+
# allow(redis).to receive(:blpop).and_return nil
|
250
|
+
# expect(redis).to receive(:evalsha) do
|
251
|
+
# unless raised
|
252
|
+
# raised = true
|
253
|
+
# raise IOError.new('closed stream')
|
254
|
+
# end
|
255
|
+
# []
|
256
|
+
# end.at_least(1)
|
257
|
+
# redis
|
258
|
+
# allow(subject).to receive(:stop)
|
259
|
+
|
260
|
+
# expect(subject.logger).to receive(:error).with('Unexpected error',
|
261
|
+
# hash_including(:message=>'closed stream', :exception=>IOError)
|
262
|
+
# ).and_call_original
|
263
|
+
|
264
|
+
# tt = Thread.new do
|
265
|
+
# sleep 2.0 # allow for retry (sleep) after handle_error
|
266
|
+
# subject.do_stop
|
267
|
+
# end
|
268
|
+
|
269
|
+
# subject.run(queue)
|
270
|
+
|
271
|
+
# tt.join
|
272
|
+
# end
|
273
|
+
|
274
|
+
# end
|
275
|
+
|
276
|
+
# context "when the batch size is greater than 1" do
|
277
|
+
# let(:batch_count) { 10 }
|
278
|
+
|
279
|
+
# it 'calling the run method, adds events to the queue' do
|
280
|
+
# allow_any_instance_of( Redis ).to receive(:script)
|
281
|
+
# allow_any_instance_of( Redis::Client ).to receive(:call) do |_, command|
|
282
|
+
# expect(command[0]).to eql :evalsha
|
283
|
+
# end.and_return ['{"a": 1}', '{"b":'], []
|
284
|
+
|
285
|
+
# tt = Thread.new do
|
286
|
+
# sleep 0.25
|
287
|
+
# subject.do_stop
|
288
|
+
# end
|
289
|
+
|
290
|
+
# subject.run(queue)
|
291
|
+
|
292
|
+
# tt.join
|
293
|
+
|
294
|
+
# expect( queue.size ).to be > 0
|
295
|
+
# end
|
296
|
+
# end
|
297
|
+
|
298
|
+
# context "when there is no data" do
|
299
|
+
# let(:batch_count) { 10 }
|
300
|
+
# let(:rates) { [] }
|
301
|
+
|
302
|
+
# it 'will throttle the loop' do
|
303
|
+
# allow_any_instance_of( Redis ).to receive(:script)
|
304
|
+
# allow_any_instance_of( Redis::Client ).to receive(:call) do |_, command|
|
305
|
+
# expect(command[0]).to eql :evalsha
|
306
|
+
# rates.unshift Time.now.to_f
|
307
|
+
# end.and_return []
|
308
|
+
|
309
|
+
# tt = Thread.new do
|
310
|
+
# sleep 0.25
|
311
|
+
# subject.do_stop
|
312
|
+
# end
|
313
|
+
|
314
|
+
# subject.run(queue)
|
315
|
+
|
316
|
+
# tt.join
|
317
|
+
|
318
|
+
# inters = []
|
319
|
+
# rates.each_cons(2) do |x, y|
|
320
|
+
# inters << x - y
|
321
|
+
# end
|
322
|
+
|
323
|
+
# expect( queue.size ).to eq(0)
|
324
|
+
# inters.each do |delta|
|
325
|
+
# expect(delta).to be_within(0.01).of(LogStash::Inputs::Redis::BATCH_EMPTY_SLEEP)
|
326
|
+
# end
|
327
|
+
# end
|
328
|
+
# end
|
329
|
+
|
330
|
+
# it 'multiple close calls, calls to redis once' do
|
331
|
+
# allow_any_instance_of( Redis::Client ).to receive(:connected?).and_return true, false
|
332
|
+
# # allow_any_instance_of( Redis::Client ).to receive(:disconnect)
|
333
|
+
# quit_calls.each do |call|
|
334
|
+
# allow_any_instance_of( Redis ).to receive(call).at_most(:once)
|
335
|
+
# end
|
336
|
+
|
337
|
+
# subject.do_stop
|
338
|
+
# expect { subject.do_stop }.not_to raise_error
|
339
|
+
# subject.do_stop
|
340
|
+
# end
|
341
|
+
# end
|
342
|
+
|
343
|
+
# context 'for the subscribe data_types' do
|
344
|
+
|
345
|
+
# before { subject.register }
|
346
|
+
|
347
|
+
# def run_it_thread(inst)
|
348
|
+
# Thread.new(inst) do |subj|
|
349
|
+
# subj.run(queue)
|
350
|
+
# end
|
351
|
+
# end
|
352
|
+
|
353
|
+
# def publish_thread(new_redis, prefix)
|
354
|
+
# Thread.new(new_redis, prefix) do |r, p|
|
355
|
+
# sleep 0.1
|
356
|
+
# 2.times do |i|
|
357
|
+
# r.publish('foo', "#{p}#{i.next}")
|
358
|
+
# end
|
359
|
+
# end
|
360
|
+
# end
|
361
|
+
|
362
|
+
# def close_thread(inst, rt)
|
363
|
+
# Thread.new(inst, rt) do |subj, runner|
|
364
|
+
# # block for the messages
|
365
|
+
# e1 = queue.pop
|
366
|
+
# e2 = queue.pop
|
367
|
+
# # put em back for the tests
|
368
|
+
# queue.push(e1)
|
369
|
+
# queue.push(e2)
|
370
|
+
# runner.raise(LogStash::ShutdownSignal)
|
371
|
+
# subj.close
|
372
|
+
# end
|
373
|
+
# end
|
374
|
+
|
375
|
+
# before(:example, type: :mocked) do
|
376
|
+
# subject.register
|
377
|
+
# allow_any_instance_of( Redis::Client ).to receive(:connected?).and_return true, false
|
378
|
+
# quit_calls.each do |call|
|
379
|
+
# allow_any_instance_of( Redis ).to receive(call).at_most(:once)
|
380
|
+
# end
|
381
|
+
# end
|
382
|
+
|
383
|
+
# context 'runtime for channel data_type' do
|
384
|
+
# let(:data_type) { 'channel' }
|
385
|
+
# let(:quit_calls) { [:unsubscribe, :connection] }
|
386
|
+
|
387
|
+
# before { subject.register }
|
388
|
+
|
389
|
+
# context 'mocked redis' do
|
390
|
+
# it 'multiple stop calls, calls to redis once', type: :mocked do
|
391
|
+
# subject.do_stop
|
392
|
+
# expect { subject.do_stop }.not_to raise_error
|
393
|
+
# subject.do_stop
|
394
|
+
# end
|
395
|
+
# end
|
396
|
+
|
397
|
+
# context 'real redis', :redis => true do
|
398
|
+
# it 'calling the run method, adds events to the queue' do
|
399
|
+
# #simulate the input thread
|
400
|
+
# rt = run_it_thread(subject)
|
401
|
+
# #simulate the other system thread
|
402
|
+
# publish_thread(subject.send(:new_redis_instance), 'c').join
|
403
|
+
# #simulate the pipeline thread
|
404
|
+
# close_thread(subject, rt).join
|
405
|
+
|
406
|
+
# expect(queue.size).to eq(2)
|
407
|
+
# end
|
408
|
+
# it 'events had redis_channel' do
|
409
|
+
# #simulate the input thread
|
410
|
+
# rt = run_it_thread(subject)
|
411
|
+
# #simulate the other system thread
|
412
|
+
# publish_thread(subject.send(:new_redis_instance), 'c').join
|
413
|
+
# #simulate the pipeline thread
|
414
|
+
# close_thread(subject, rt).join
|
415
|
+
# e1 = queue.pop
|
416
|
+
# e2 = queue.pop
|
417
|
+
# expect(e1.get('[@metadata][redis_channel]')).to eq('foo')
|
418
|
+
# expect(e2.get('[@metadata][redis_channel]')).to eq('foo')
|
419
|
+
# end
|
420
|
+
# end
|
421
|
+
# end
|
422
|
+
|
423
|
+
# context 'runtime for pattern_channel data_type' do
|
424
|
+
# let(:data_type) { 'pattern_channel' }
|
425
|
+
# let(:quit_calls) { [:punsubscribe, :connection] }
|
426
|
+
|
427
|
+
# context 'mocked redis' do
|
428
|
+
# it 'multiple stop calls, calls to redis once', type: :mocked do
|
429
|
+
# subject.do_stop
|
430
|
+
# expect { subject.do_stop }.not_to raise_error
|
431
|
+
# subject.do_stop
|
432
|
+
# end
|
433
|
+
# end
|
434
|
+
|
435
|
+
# context 'real redis', :redis => true do
|
436
|
+
# it 'calling the run method, adds events to the queue' do
|
437
|
+
# #simulate the input thread
|
438
|
+
# rt = run_it_thread(subject)
|
439
|
+
# #simulate the other system thread
|
440
|
+
# publish_thread(subject.send(:new_redis_instance), 'pc').join
|
441
|
+
# #simulate the pipeline thread
|
442
|
+
# close_thread(subject, rt).join
|
443
|
+
|
444
|
+
# expect(queue.size).to eq(2)
|
445
|
+
# end
|
446
|
+
|
447
|
+
# it 'events had redis_channel' do
|
448
|
+
# #simulate the input thread
|
449
|
+
# rt = run_it_thread(subject)
|
450
|
+
# #simulate the other system thread
|
451
|
+
# publish_thread(subject.send(:new_redis_instance), 'pc').join
|
452
|
+
# #simulate the pipeline thread
|
453
|
+
# close_thread(subject, rt).join
|
454
|
+
# e1 = queue.pop
|
455
|
+
# e2 = queue.pop
|
456
|
+
# expect(e1.get('[@metadata][redis_channel]')).to eq('foo')
|
457
|
+
# expect(e2.get('[@metadata][redis_channel]')).to eq('foo')
|
458
|
+
# end
|
459
|
+
# end
|
460
|
+
# end
|
461
|
+
# end
|
462
|
+
|
463
|
+
# context "when using data type" do
|
464
|
+
|
465
|
+
# ["list", "channel", "pattern_channel"].each do |data_type|
|
466
|
+
# context data_type do
|
467
|
+
# # TODO pending
|
468
|
+
# # redis-rb ends up in a read wait loop since we do not use subscribe_with_timeout
|
469
|
+
# next unless data_type == 'list'
|
470
|
+
|
471
|
+
# it_behaves_like "an interruptible input plugin", :redis => true do
|
472
|
+
# let(:config) { { 'key' => 'foo', 'data_type' => data_type } }
|
473
|
+
# end
|
474
|
+
# end
|
475
|
+
# end
|
476
|
+
|
477
|
+
# end
|
478
|
+
# end
|
metadata
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: logstash-input-redis_cluster
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Elastic
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ">="
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '1.60'
|
19
|
+
- - "<="
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '2.99'
|
22
|
+
name: logstash-core-plugin-api
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.60'
|
30
|
+
- - "<="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '2.99'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
name: logstash-codec-json
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 4.0.1
|
53
|
+
- - "<"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '5'
|
56
|
+
name: redis
|
57
|
+
type: :runtime
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 4.0.1
|
64
|
+
- - "<"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '5'
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 0.0.16
|
73
|
+
name: logstash-devutils
|
74
|
+
type: :development
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: 0.0.16
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
name: redis-cluster-client
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
description: This gem is a Logstash plugin required to be installed on top of the
|
96
|
+
Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
|
97
|
+
gem is not a stand-alone program
|
98
|
+
email: info@elastic.co
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- CHANGELOG.md
|
104
|
+
- CONTRIBUTORS
|
105
|
+
- Gemfile
|
106
|
+
- LICENSE
|
107
|
+
- NOTICE.TXT
|
108
|
+
- README.md
|
109
|
+
- docs/index.asciidoc
|
110
|
+
- lib/logstash/inputs/redis_cluster.rb
|
111
|
+
- logstash-input-redis_cluster.gemspec
|
112
|
+
- spec/inputs/redis_cluster_spec.rb
|
113
|
+
homepage: http://www.elastic.co/guide/en/logstash/current/index.html
|
114
|
+
licenses:
|
115
|
+
- Apache License (2.0)
|
116
|
+
metadata:
|
117
|
+
logstash_plugin: 'true'
|
118
|
+
logstash_group: input
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ">="
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
requirements: []
|
134
|
+
rubygems_version: 3.3.26
|
135
|
+
signing_key:
|
136
|
+
specification_version: 4
|
137
|
+
summary: Reads events from a Redis instance
|
138
|
+
test_files:
|
139
|
+
- spec/inputs/redis_cluster_spec.rb
|