logstash-output-redis 2.0.2 → 2.0.4
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/README.md +3 -0
- data/lib/logstash/outputs/redis.rb +35 -30
- data/logstash-output-redis.gemspec +5 -2
- data/spec/outputs/redis_spec.rb +44 -97
- metadata +57 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a529cca11d4cde933249b32c7e76ae676d9b755b
|
4
|
+
data.tar.gz: 2ec4475ed8cb05a5c68e989a8e87b44394fa9016
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fe3cfc505241664aa8e9eaf267090145c9cf0ec51e3099e0aa0c1e983513e53b4a6955d342a5209f0dd09f316eb050454b638f43101cfd815f366ce0bd33808
|
7
|
+
data.tar.gz: 39c5ec408749415ecedc7a3edb7f5f5be74aa2df9878d7323eb652dd90754f2a9ec1cdf6e7c6614234668f1540b9653472279e38df093d6892b4028236c76ec7
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# 2.0.4
|
2
|
+
- Depend on logstash-core-plugin-api instead of logstash-core, removing the need to mass update plugins on major releases of logstash
|
3
|
+
# 2.0.3
|
4
|
+
- New dependency requirements for logstash-core for the 5.0 release
|
1
5
|
## 2.0.0
|
2
6
|
- Plugins were updated to follow the new shutdown semantic, this mainly allows Logstash to instruct input plugins to terminate gracefully,
|
3
7
|
instead of using Thread.raise on the plugins' threads. Ref: https://github.com/elastic/logstash/pull/3895
|
data/README.md
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# Logstash Plugin
|
2
2
|
|
3
|
+
[](http://build-eu-00.elastic.co/view/LS%20Plugins/view/LS%20Outputs/job/logstash-plugin-output-redis-unit/)
|
5
|
+
|
3
6
|
This is a plugin for [Logstash](https://github.com/elastic/logstash).
|
4
7
|
|
5
8
|
It is fully free and fully open source. The license is Apache 2.0, meaning you are pretty much free to use it however you want in whatever way.
|
@@ -18,6 +18,8 @@ class LogStash::Outputs::Redis < LogStash::Outputs::Base
|
|
18
18
|
|
19
19
|
config_name "redis"
|
20
20
|
|
21
|
+
default :codec, "json"
|
22
|
+
|
21
23
|
# Name is used for logging in case there are multiple instances.
|
22
24
|
# TODO: delete
|
23
25
|
config :name, :validate => :string, :default => 'default',
|
@@ -137,46 +139,22 @@ class LogStash::Outputs::Redis < LogStash::Outputs::Base
|
|
137
139
|
@host_idx = 0
|
138
140
|
|
139
141
|
@congestion_check_times = Hash.new { |h,k| h[k] = Time.now.to_i - @congestion_interval }
|
142
|
+
|
143
|
+
@codec.on_event(&method(:send_to_redis))
|
140
144
|
end # def register
|
141
145
|
|
142
146
|
def receive(event)
|
143
147
|
|
144
148
|
|
145
|
-
if @batch and @data_type == 'list' # Don't use batched method for pubsub.
|
146
|
-
# Stud::Buffer
|
147
|
-
buffer_receive(event.to_json, event.sprintf(@key))
|
148
|
-
return
|
149
|
-
end
|
150
|
-
|
151
|
-
key = event.sprintf(@key)
|
152
149
|
# TODO(sissel): We really should not drop an event, but historically
|
153
150
|
# we have dropped events that fail to be converted to json.
|
154
151
|
# TODO(sissel): Find a way to continue passing events through even
|
155
152
|
# if they fail to convert properly.
|
156
153
|
begin
|
157
|
-
|
158
|
-
rescue
|
159
|
-
|
160
|
-
|
161
|
-
:event => event.inspect)
|
162
|
-
return
|
163
|
-
end
|
164
|
-
|
165
|
-
begin
|
166
|
-
@redis ||= connect
|
167
|
-
if @data_type == 'list'
|
168
|
-
congestion_check(key)
|
169
|
-
@redis.rpush(key, payload)
|
170
|
-
else
|
171
|
-
@redis.publish(key, payload)
|
172
|
-
end
|
173
|
-
rescue => e
|
174
|
-
@logger.warn("Failed to send event to Redis", :event => event,
|
175
|
-
:identity => identity, :exception => e,
|
176
|
-
:backtrace => e.backtrace)
|
177
|
-
sleep @reconnect_interval
|
178
|
-
@redis = nil
|
179
|
-
retry
|
154
|
+
@codec.encode(event)
|
155
|
+
rescue StandardError => e
|
156
|
+
@logger.warn("Error encoding event", :exception => e,
|
157
|
+
:event => event)
|
180
158
|
end
|
181
159
|
end # def receive
|
182
160
|
|
@@ -248,4 +226,31 @@ class LogStash::Outputs::Redis < LogStash::Outputs::Base
|
|
248
226
|
@name || "redis://#{@password}@#{@current_host}:#{@current_port}/#{@db} #{@data_type}:#{@key}"
|
249
227
|
end
|
250
228
|
|
229
|
+
def send_to_redis(event, payload)
|
230
|
+
# How can I do this sort of thing with codecs?
|
231
|
+
key = event.sprintf(@key)
|
232
|
+
|
233
|
+
if @batch and @data_type == 'list' # Don't use batched method for pubsub.
|
234
|
+
# Stud::Buffer
|
235
|
+
buffer_receive(payload, key)
|
236
|
+
next
|
237
|
+
end
|
238
|
+
|
239
|
+
begin
|
240
|
+
@redis ||= connect
|
241
|
+
if @data_type == 'list'
|
242
|
+
congestion_check(key)
|
243
|
+
@redis.rpush(key, payload)
|
244
|
+
else
|
245
|
+
@redis.publish(key, payload)
|
246
|
+
end
|
247
|
+
rescue => e
|
248
|
+
@logger.warn("Failed to send event to Redis", :event => event,
|
249
|
+
:identity => identity, :exception => e,
|
250
|
+
:backtrace => e.backtrace)
|
251
|
+
sleep @reconnect_interval
|
252
|
+
@redis = nil
|
253
|
+
retry
|
254
|
+
end
|
255
|
+
end
|
251
256
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
|
3
3
|
s.name = 'logstash-output-redis'
|
4
|
-
s.version = '2.0.
|
4
|
+
s.version = '2.0.4'
|
5
5
|
s.licenses = ['Apache License (2.0)']
|
6
6
|
s.summary = "This output will send events to a Redis queue using RPUSH"
|
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"
|
@@ -20,11 +20,14 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.metadata = { "logstash_plugin" => "true", "logstash_group" => "output" }
|
21
21
|
|
22
22
|
# Gem dependencies
|
23
|
-
s.add_runtime_dependency "logstash-core", "
|
23
|
+
s.add_runtime_dependency "logstash-core-plugin-api", "~> 1.0"
|
24
24
|
|
25
25
|
s.add_runtime_dependency 'redis'
|
26
26
|
s.add_runtime_dependency 'stud'
|
27
27
|
|
28
28
|
s.add_development_dependency 'logstash-devutils'
|
29
|
+
s.add_development_dependency 'logstash-input-generator'
|
30
|
+
s.add_development_dependency 'logstash-codec-json'
|
31
|
+
s.add_development_dependency 'flores'
|
29
32
|
end
|
30
33
|
|
data/spec/outputs/redis_spec.rb
CHANGED
@@ -2,83 +2,38 @@ require "logstash/devutils/rspec/spec_helper"
|
|
2
2
|
require "logstash/outputs/redis"
|
3
3
|
require "logstash/json"
|
4
4
|
require "redis"
|
5
|
+
require "flores/random"
|
5
6
|
|
6
7
|
describe LogStash::Outputs::Redis, :redis => true do
|
7
|
-
|
8
8
|
|
9
|
-
|
10
|
-
key
|
11
|
-
event_count
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
type => "generator"
|
19
|
-
}
|
20
|
-
}
|
21
|
-
output {
|
22
|
-
redis {
|
23
|
-
host => "127.0.0.1"
|
24
|
-
key => "#{key}"
|
25
|
-
data_type => list
|
26
|
-
}
|
9
|
+
shared_examples_for "writing to redis list" do |extra_config|
|
10
|
+
let(:key) { 10.times.collect { rand(10).to_s }.join("") }
|
11
|
+
let(:event_count) { Flores::Random.integer(0..10000) }
|
12
|
+
let(:message) { Flores::Random.text(0..100) }
|
13
|
+
let(:default_config) {
|
14
|
+
{
|
15
|
+
"key" => key,
|
16
|
+
"data_type" => "list",
|
17
|
+
"host" => "localhost"
|
27
18
|
}
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
id, element = redis.blpop(key, 0)
|
40
|
-
event = LogStash::Event.new(LogStash::Json.load(element))
|
41
|
-
insist { event["sequence"] } == value
|
42
|
-
insist { event["message"] } == "hello world"
|
19
|
+
}
|
20
|
+
let(:redis_config) {
|
21
|
+
default_config.merge(extra_config || {})
|
22
|
+
}
|
23
|
+
let(:redis_output) { described_class.new(redis_config) }
|
24
|
+
|
25
|
+
before do
|
26
|
+
redis_output.register
|
27
|
+
event_count.times do |i|
|
28
|
+
event = LogStash::Event.new("sequence" => i, "message" => message)
|
29
|
+
redis_output.receive(event)
|
43
30
|
end
|
31
|
+
redis_output.close
|
32
|
+
end
|
44
33
|
|
45
|
-
|
46
|
-
insist { redis.llen(key) } == 0
|
47
|
-
end # agent
|
48
|
-
end
|
49
|
-
|
50
|
-
describe "batch mode" do
|
51
|
-
key = 10.times.collect { rand(10).to_s }.join("")
|
52
|
-
event_count = 200000
|
53
|
-
|
54
|
-
config <<-CONFIG
|
55
|
-
input {
|
56
|
-
generator {
|
57
|
-
message => "hello world"
|
58
|
-
count => #{event_count}
|
59
|
-
type => "generator"
|
60
|
-
}
|
61
|
-
}
|
62
|
-
output {
|
63
|
-
redis {
|
64
|
-
host => "127.0.0.1"
|
65
|
-
key => "#{key}"
|
66
|
-
data_type => list
|
67
|
-
batch => true
|
68
|
-
batch_timeout => 5
|
69
|
-
timeout => 5
|
70
|
-
}
|
71
|
-
}
|
72
|
-
CONFIG
|
73
|
-
|
74
|
-
agent do
|
75
|
-
# we have to wait for close to execute & flush the last batch.
|
76
|
-
# otherwise we might start doing assertions before everything has been
|
77
|
-
# sent out to redis.
|
78
|
-
sleep 2
|
79
|
-
|
34
|
+
it "should successfully send all events to redis" do
|
80
35
|
redis = Redis.new(:host => "127.0.0.1")
|
81
|
-
|
36
|
+
|
82
37
|
# The list should contain the number of elements our agent pushed up.
|
83
38
|
insist { redis.llen(key) } == event_count
|
84
39
|
|
@@ -87,42 +42,34 @@ describe LogStash::Outputs::Redis, :redis => true do
|
|
87
42
|
id, element = redis.blpop(key, 0)
|
88
43
|
event = LogStash::Event.new(LogStash::Json.load(element))
|
89
44
|
insist { event["sequence"] } == value
|
90
|
-
insist { event["message"] } ==
|
45
|
+
insist { event["message"] } == message
|
91
46
|
end
|
92
47
|
|
93
48
|
# The list should now be empty
|
94
49
|
insist { redis.llen(key) } == 0
|
95
|
-
end
|
50
|
+
end
|
96
51
|
end
|
97
52
|
|
98
|
-
|
99
|
-
|
53
|
+
context "when batch_mode is false" do
|
54
|
+
include_examples "writing to redis list"
|
55
|
+
end
|
100
56
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
type => "generator"
|
108
|
-
}
|
109
|
-
}
|
110
|
-
output {
|
111
|
-
redis {
|
112
|
-
host => "127.0.0.1"
|
113
|
-
key => "#{key}"
|
114
|
-
data_type => list
|
115
|
-
}
|
116
|
-
}
|
117
|
-
CONFIG
|
57
|
+
context "when batch_mode is true" do
|
58
|
+
batch_events = Flores::Random.integer(1..1000)
|
59
|
+
batch_settings = {
|
60
|
+
"batch" => true,
|
61
|
+
"batch_events" => batch_events
|
62
|
+
}
|
118
63
|
|
119
|
-
|
120
|
-
# Query redis directly and inspect the goodness.
|
121
|
-
redis = Redis.new(:host => "127.0.0.1")
|
64
|
+
include_examples "writing to redis list", batch_settings do
|
122
65
|
|
123
|
-
#
|
124
|
-
|
125
|
-
|
66
|
+
# A canary to make sure we're actually enabling batch mode
|
67
|
+
# in this shared example.
|
68
|
+
it "should have batch mode enabled" do
|
69
|
+
expect(redis_config).to include("batch")
|
70
|
+
expect(redis_config["batch"]).to be_truthy
|
71
|
+
end
|
72
|
+
end
|
126
73
|
end
|
127
74
|
end
|
128
75
|
|
metadata
CHANGED
@@ -1,39 +1,33 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-output-redis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elastic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
|
-
- -
|
16
|
+
- - "~>"
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version:
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: 3.0.0
|
22
|
-
name: logstash-core
|
18
|
+
version: '1.0'
|
19
|
+
name: logstash-core-plugin-api
|
23
20
|
prerelease: false
|
24
21
|
type: :runtime
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
|
-
- -
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: 2.0.0.beta2
|
30
|
-
- - <
|
24
|
+
- - "~>"
|
31
25
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
26
|
+
version: '1.0'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
requirement: !ruby/object:Gem::Requirement
|
35
29
|
requirements:
|
36
|
-
- -
|
30
|
+
- - ">="
|
37
31
|
- !ruby/object:Gem::Version
|
38
32
|
version: '0'
|
39
33
|
name: redis
|
@@ -41,13 +35,13 @@ dependencies:
|
|
41
35
|
type: :runtime
|
42
36
|
version_requirements: !ruby/object:Gem::Requirement
|
43
37
|
requirements:
|
44
|
-
- -
|
38
|
+
- - ">="
|
45
39
|
- !ruby/object:Gem::Version
|
46
40
|
version: '0'
|
47
41
|
- !ruby/object:Gem::Dependency
|
48
42
|
requirement: !ruby/object:Gem::Requirement
|
49
43
|
requirements:
|
50
|
-
- -
|
44
|
+
- - ">="
|
51
45
|
- !ruby/object:Gem::Version
|
52
46
|
version: '0'
|
53
47
|
name: stud
|
@@ -55,13 +49,13 @@ dependencies:
|
|
55
49
|
type: :runtime
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
51
|
requirements:
|
58
|
-
- -
|
52
|
+
- - ">="
|
59
53
|
- !ruby/object:Gem::Version
|
60
54
|
version: '0'
|
61
55
|
- !ruby/object:Gem::Dependency
|
62
56
|
requirement: !ruby/object:Gem::Requirement
|
63
57
|
requirements:
|
64
|
-
- -
|
58
|
+
- - ">="
|
65
59
|
- !ruby/object:Gem::Version
|
66
60
|
version: '0'
|
67
61
|
name: logstash-devutils
|
@@ -69,7 +63,49 @@ dependencies:
|
|
69
63
|
type: :development
|
70
64
|
version_requirements: !ruby/object:Gem::Requirement
|
71
65
|
requirements:
|
72
|
-
- -
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
name: logstash-input-generator
|
76
|
+
prerelease: false
|
77
|
+
type: :development
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
name: logstash-codec-json
|
90
|
+
prerelease: false
|
91
|
+
type: :development
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
name: flores
|
104
|
+
prerelease: false
|
105
|
+
type: :development
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
73
109
|
- !ruby/object:Gem::Version
|
74
110
|
version: '0'
|
75
111
|
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
|
@@ -99,12 +135,12 @@ require_paths:
|
|
99
135
|
- lib
|
100
136
|
required_ruby_version: !ruby/object:Gem::Requirement
|
101
137
|
requirements:
|
102
|
-
- -
|
138
|
+
- - ">="
|
103
139
|
- !ruby/object:Gem::Version
|
104
140
|
version: '0'
|
105
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
142
|
requirements:
|
107
|
-
- -
|
143
|
+
- - ">="
|
108
144
|
- !ruby/object:Gem::Version
|
109
145
|
version: '0'
|
110
146
|
requirements: []
|