logstash-filter-rediss 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f19ec0db128b3d2fab457046c9cef823897d334dc142c17230b9ee4d634f6dc
4
- data.tar.gz: ecf92c21293d5a49d37fb3a958cdeb3cdbe14591732c1e5bef892b1aa034c452
3
+ metadata.gz: 2e73636b9648b878f1d962d5fe80287c306c9ca68cfb4611ffc18789712a36c9
4
+ data.tar.gz: cc85150046052b65002092f9000997065056290d68159030cdd0be58ce48c93f
5
5
  SHA512:
6
- metadata.gz: e162d6c193d0f035a4b23bf0a0e5a9bb960d1cce69883b286a0706f265d7a40d676b478976c6e39c8a3d82eaea91657352dec4fc16644c0833e20d6d37f20acc
7
- data.tar.gz: '04908bcb693b5beefa287da14e49926958bb05100e617f606582c5f5cb0348e0bef8193992c6e1df46c8591991c7a71470ea84ee497f2d700fb48c60d76c32ef'
6
+ metadata.gz: 85774259a88a2df9e31439a077d22c590b2a3d87533056637368d626a198dfefeacce1dd2dda1cc23f31ed85fb8b2b427f51ccec8ba38d3bb057074d25aac018
7
+ data.tar.gz: c0ad14407e0736b3b768a01ae7cdbbcd293dddb3f4048023802c6dea3be459d446a81247c72cbb5e030fa79450d1586518c294fc0917ecc6afa12027a7becb83
@@ -1,19 +1,19 @@
1
- ## 0.3.2
2
- - Introduce redis command `sismember`
3
-
4
- ## 0.3.1
5
- - Prevent infinite loops for retries after errors or failed lock acquisitions
6
- - Introduce optional configuration options for controlling the count and
7
- the interval of retries - see :max_retries, :lock_retry_interval and
8
- :max_lock_retries
9
-
10
- ## 0.3.0
11
- - Support for GET, SET, EXISTS, DEL, SADD, SMEMBERS and SCARD
12
- - Introduce new control field `cmd_key_is_formatted` for declaring commands
13
- to be resolved through - see %{foo} handling
14
-
15
- ## 0.2.0
16
- - Support for HSET and HGET
17
-
18
- ## 0.1.0
19
- - Initial version; simple caching with redis
1
+ ## 0.3.2
2
+ - Introduce redis command `sismember`
3
+
4
+ ## 0.3.1
5
+ - Prevent infinite loops for retries after errors or failed lock acquisitions
6
+ - Introduce optional configuration options for controlling the count and
7
+ the interval of retries - see :max_retries, :lock_retry_interval and
8
+ :max_lock_retries
9
+
10
+ ## 0.3.0
11
+ - Support for GET, SET, EXISTS, DEL, SADD, SMEMBERS and SCARD
12
+ - Introduce new control field `cmd_key_is_formatted` for declaring commands
13
+ to be resolved through - see %{foo} handling
14
+
15
+ ## 0.2.0
16
+ - Support for HSET and HGET
17
+
18
+ ## 0.1.0
19
+ - Initial version; simple caching with redis
@@ -1,10 +1,10 @@
1
- The following is a list of people who have contributed ideas, code, bug
2
- reports, or in general have helped logstash-filter-cache-redis along its way.
3
-
4
- Contributors:
5
- * David Robakowski (drobakowski)
6
-
7
- Note: If you've sent us patches, bug reports, or otherwise contributed to
8
- logstash-filter-cache-redis, and you aren't on the list above and want to be,
9
- please let us know and we'll make sure you're here. Contributions from folks
10
- like you are what make open source awesome.
1
+ The following is a list of people who have contributed ideas, code, bug
2
+ reports, or in general have helped logstash-filter-cache-redis along its way.
3
+
4
+ Contributors:
5
+ * David Robakowski (drobakowski)
6
+
7
+ Note: If you've sent us patches, bug reports, or otherwise contributed to
8
+ logstash-filter-cache-redis, and you aren't on the list above and want to be,
9
+ please let us know and we'll make sure you're here. Contributions from folks
10
+ like you are what make open source awesome.
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
- source 'https://rubygems.org'
2
- gem 'coveralls', require: false
3
- gemspec
1
+ source 'https://rubygems.org'
2
+ gem 'coveralls', require: false
3
+ gemspec
data/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2016, Synlay Technologies UG & Co. KG.
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2016, Synlay Technologies UG & Co. KG.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,27 +1,27 @@
1
- # Logstash Filter Redis Cache Plugin
2
-
3
- [![Build Status](https://travis-ci.org/synlay/logstash-filter-cache-redis.svg)](https://travis-ci.org/synlay/logstash-filter-cache-redis)
4
- [![Coverage Status](https://coveralls.io/repos/github/synlay/logstash-filter-cache-redis/badge.svg?branch=master)](https://coveralls.io/github/synlay/logstash-filter-cache-redis?branch=master)
5
- [![Gem Version](https://badge.fury.io/rb/logstash-filter-cache-redis.svg)](https://badge.fury.io/rb/logstash-filter-cache-redis)
6
- [![GitHub license](https://img.shields.io/github/license/synlay/logstash-filter-cache-redis.svg)](https://github.com/synlay/logstash-filter-cache-redis)
7
-
8
- This is a plugin for [Logstash](https://github.com/elastic/logstash).
9
-
10
- It is fully free and fully open source. The license is MIT, see [LICENSE](http://github.com/synlay/logstash-filter-cache-redis/LICENSE) for further infos.
11
-
12
- ## Documentation
13
-
14
- This filter will store and retrieve data from Redis data cache. The fields `source` and `target` are used alternatively as data in- or output fields, while the value of a defined command like `rpush` will look for the corresponding event and use that value as the key. The following example for instance will store data from the event `ProductEntity` under the key based upon the data from the event `ProductId`:
15
-
16
- ```ruby
17
- filter {
18
- cache_redis {
19
- rpush => "ProductId"
20
- source => "ProductEntity"
21
- }
22
- }
23
- ```
24
-
25
- ## Developing
26
-
27
- For further instructions on howto develop on logstash plugins, please see the documentation of the official [logstash-filter-example](https://github.com/logstash-plugins/logstash-filter-example#developing).
1
+ # Logstash Filter Redis Cache Plugin
2
+
3
+ [![Build Status](https://travis-ci.org/synlay/logstash-filter-cache-redis.svg)](https://travis-ci.org/synlay/logstash-filter-cache-redis)
4
+ [![Coverage Status](https://coveralls.io/repos/github/synlay/logstash-filter-cache-redis/badge.svg?branch=master)](https://coveralls.io/github/synlay/logstash-filter-cache-redis?branch=master)
5
+ [![Gem Version](https://badge.fury.io/rb/logstash-filter-cache-redis.svg)](https://badge.fury.io/rb/logstash-filter-cache-redis)
6
+ [![GitHub license](https://img.shields.io/github/license/synlay/logstash-filter-cache-redis.svg)](https://github.com/synlay/logstash-filter-cache-redis)
7
+
8
+ This is a plugin for [Logstash](https://github.com/elastic/logstash).
9
+
10
+ It is fully free and fully open source. The license is MIT, see [LICENSE](http://github.com/synlay/logstash-filter-cache-redis/LICENSE) for further infos.
11
+
12
+ ## Documentation
13
+
14
+ This filter will store and retrieve data from Redis data cache. The fields `source` and `target` are used alternatively as data in- or output fields, while the value of a defined command like `rpush` will look for the corresponding event and use that value as the key. The following example for instance will store data from the event `ProductEntity` under the key based upon the data from the event `ProductId`:
15
+
16
+ ```ruby
17
+ filter {
18
+ cache_redis {
19
+ rpush => "ProductId"
20
+ source => "ProductEntity"
21
+ }
22
+ }
23
+ ```
24
+
25
+ ## Developing
26
+
27
+ For further instructions on howto develop on logstash plugins, please see the documentation of the official [logstash-filter-example](https://github.com/logstash-plugins/logstash-filter-example#developing).
@@ -1,284 +1,284 @@
1
- # encoding: utf-8
2
- require "logstash/filters/base"
3
- require "logstash/namespace"
4
- require "redis"
5
- require "redlock"
6
-
7
- class LogStash::Filters::Rediss < LogStash::Filters::Base
8
- config_name "rediss"
9
-
10
- # The field to perform filter
11
- #
12
- config :source, :validate => :string, :default => "message"
13
-
14
- # The name of the container to put the result
15
- #
16
- config :target, :validate => :string, :default => "message"
17
-
18
- config :field, :validate => :string
19
-
20
- # Expire time in seconds
21
- config :ttl => :number
22
-
23
- # Informs if the connection is to be made with SSL or not
24
- config :ssl => :boolean
25
-
26
- # For now only working for rpushnx and llen!
27
- config :cmd_key_is_formatted, :validate => :boolean, :default => false
28
-
29
- # The hostname(s) of your Redis server(s). Ports may be specified on any
30
- # hostname, which will override the global port config.
31
- # If the hosts list is an array, Logstash will pick one random host to connect to,
32
- # if that host is disconnected it will then pick another.
33
- #
34
- # For example:
35
- # [source,ruby]
36
- # "127.0.0.1"
37
- # ["127.0.0.1", "127.0.0.2"]
38
- # ["127.0.0.1:6380", "127.0.0.1"]
39
- config :host, :validate => :array, :default => ["127.0.0.1"]
40
-
41
- # Shuffle the host list during Logstash startup.
42
- config :shuffle_hosts, :validate => :boolean, :default => true
43
-
44
- # The default port to connect on. Can be overridden on any hostname.
45
- config :port, :validate => :number, :default => 6379
46
-
47
- # The Redis database number.
48
- config :db, :validate => :number, :default => 0
49
-
50
- # Redis initial connection timeout in seconds.
51
- config :timeout, :validate => :number, :default => 5
52
-
53
- # Password to authenticate with. There is no authentication by default.
54
- config :password, :validate => :password
55
-
56
- # Interval for reconnecting to failed Redis connections
57
- config :reconnect_interval, :validate => :number, :default => 1
58
-
59
- # Maximal count of command retries after a crash because of a failure
60
- config :max_retries, :validate => :number, :default => 3
61
-
62
- # Interval for retrying to acquire a lock
63
- config :lock_retry_interval, :validate => :number, :default => 1
64
-
65
- # Maximal count of retries to acquire a lock
66
- config :max_lock_retries, :validate => :number, :default => 3
67
-
68
- config :get, :validate => :string
69
-
70
- config :set, :validate => :string
71
-
72
- config :setex, :validate => :string
73
-
74
- config :exists, :validate => :string
75
-
76
- config :del, :validate => :string
77
-
78
- # # Sets the action. If set to true, it will get the data from redis cache
79
- # config :get, :validate => :boolean, :default => false
80
- config :llen, :validate => :string
81
-
82
- # # Sets the action. If set to true, it will get the data from redis cache
83
- # config :get, :validate => :boolean, :default => false
84
- config :rpush, :validate => :string
85
-
86
- # # Sets the action. If set to true, it will get the data from redis cache
87
- # config :get, :validate => :boolean, :default => false
88
- config :rpushnx, :validate => :string
89
-
90
- # Sets the action. If set to true, it will get the data from redis cache
91
- config :hset, :validate => :string
92
-
93
- # Sets the action. If set to true, it will get the data from redis cache
94
- config :hget, :validate => :string
95
-
96
- config :sadd, :validate => :string
97
-
98
- config :sismember, :validate => :string
99
-
100
- config :smembers, :validate => :string
101
-
102
- config :scard, :validate => :string
103
-
104
- # config :get, :validate => :boolean, :default => false
105
- config :lock_timeout, :validate => :number, :default => 5000
106
-
107
- # # Sets the action. If set to true, it will get the data from redis cache
108
- # config :get, :validate => :boolean, :default => false
109
- config :rpop, :validate => :string
110
-
111
- # # Sets the action. If set to true, it will get the data from redis cache
112
- # config :get, :validate => :boolean, :default => false
113
- config :lpop, :validate => :string
114
-
115
- # # Sets the action. If set to true, it will get the data from redis cache
116
- # config :get, :validate => :boolean, :default => false
117
- # O(N)
118
- config :lget, :validate => :string
119
-
120
-
121
- public
122
- def register
123
- @redis = nil
124
- @lock_manager = nil
125
- if @shuffle_hosts
126
- @host.shuffle!
127
- end
128
- @host_idx = 0
129
- end # def register
130
-
131
-
132
- def filter(event)
133
-
134
- # TODO: Maybe refactor the interface into a more flexible one with two
135
- # main configs 'cmd' & 'args'. Then it would be possible to eliminate
136
- # all if clauses and replace it through one hashmap call, where
137
- # the hashmap would be a mapping from 'cmd' -> <cmd_function_ref>
138
- # E.q.: cmds.fetch(event.get(@llen), &method(:cmd_not_found_err))
139
- max_retries = @max_retries
140
- begin
141
- @redis ||= connect
142
-
143
- if @get
144
- event.set(@target, @redis.get(event.get(@get)))
145
- end
146
-
147
- if @set
148
- @redis.set(event.get(@set), event.get(@source))
149
- end
150
-
151
- if @setex
152
- @redis.setex(event.get(@setex), event.get(@ttl), event.get(@source))
153
- end
154
-
155
- if @exists
156
- @redis.exists(event.get(@exists))
157
- end
158
-
159
- if @del
160
- @redis.del(event.get(@del))
161
- end
162
-
163
- if @hget
164
- event.set(@target, @redis.hget(event.get(@hget), event.get(@source)))
165
- end
166
-
167
- if @hset
168
- @redis.hset(event.get(@hset), event.get(@field), event.get(@source))
169
- end
170
-
171
- if @sadd
172
- @redis.sadd(event.get(@sadd), event.get(@source))
173
- end
174
-
175
- if @sismember
176
- event.set(@target, @redis.sismember(event.get(@sismember), event.get(@source)))
177
- end
178
-
179
- if @smembers
180
- @redis.smembers(event.get(@smembers))
181
- end
182
-
183
- if @scard
184
- event.set(@target, @redis.scard(event.get(@scard)))
185
- end
186
-
187
- if @llen
188
- key = @cmd_key_is_formatted ? event.sprintf(@llen) : event.get(@llen)
189
- event.set(@target, @redis.llen(key))
190
- end
191
-
192
- if @rpush
193
- @redis.rpush(event.get(@rpush), event.get(@source))
194
- end
195
-
196
- if @rpushnx
197
- key = @cmd_key_is_formatted ? event.sprintf(@rpushnx) : event.get(@rpushnx)
198
- max_lock_retries = @max_lock_retries
199
- begin
200
- @lock_manager ||= connect_lockmanager
201
- @lock_manager.lock!("lock_#{key}", @lock_timeout) do
202
- @redis.rpush(key, event.get(@source)) unless @redis.exists(key)
203
- end
204
- rescue Redlock::LockError => e
205
- @logger.warn("Failed to lock section 'rpushnx' for key: #{key}",
206
- :event => event, :exception => e)
207
- sleep @lock_retry_interval
208
- max_lock_retries -= 1
209
- unless max_lock_retries < 0
210
- retry
211
- else
212
- @logger.error("Max retries reached for trying to lock section 'rpushnx' for key: #{key}",
213
- :event => event, :exception => e)
214
- end
215
- end
216
- end
217
-
218
- if @rpop
219
- event.set(@target, @redis.rpop(event.get(@rpop)))
220
- end
221
-
222
- if @lget
223
- event.set(@target, @redis.lrange(event.get(@lget), 0, -1))
224
- end
225
-
226
- rescue => e
227
- @logger.warn("Failed to send event to Redis, retrying after #{@reconnect_interval} seconds...", :event => event,
228
- :exception => e, :backtrace => e.backtrace)
229
- sleep @reconnect_interval
230
- @redis = nil
231
- @lock_manager = nil
232
- max_retries -= 1
233
- unless max_retries < 0
234
- retry
235
- else
236
- @logger.error("Max retries reached for trying to execute a command",
237
- :event => event, :exception => e)
238
- end
239
- end
240
-
241
- # filter_matched should go in the last line of our successful code
242
- filter_matched(event)
243
- end # def filter
244
-
245
-
246
- private
247
- def connect
248
- @current_host, @current_port = @host[@host_idx].split(':')
249
- @host_idx = @host_idx + 1 >= @host.length ? 0 : @host_idx + 1
250
-
251
- if not @current_port
252
- @current_port = @port
253
- end
254
-
255
- params = {
256
- :host => @current_host,
257
- :port => @current_port,
258
- :timeout => @timeout,
259
- :db => @db,
260
- :ssl => @ssl
261
- }
262
-
263
- @logger.debug("connection params", params)
264
-
265
- if @password
266
- params[:password] = @password.value
267
- end
268
-
269
- Redis.new(params)
270
- end # def connect
271
-
272
- def connect_lockmanager
273
- @protocol = @ssl ? 'rediss://' : 'redis://'
274
-
275
- hosts = Array(@host).map { |host|
276
- host.prepend(@protocol) unless host.start_with?(@protocol)
277
- }
278
-
279
- @logger.debug("lock_manager hosts", hosts)
280
-
281
- Redlock::Client.new(hosts)
282
- end # def connect
283
-
284
- end # class LogStash::Filters::Example
1
+ # encoding: utf-8
2
+ require "logstash/filters/base"
3
+ require "logstash/namespace"
4
+ require "redis"
5
+ require "redlock"
6
+
7
+ class LogStash::Filters::Rediss < LogStash::Filters::Base
8
+ config_name "rediss"
9
+
10
+ # The field to perform filter
11
+ #
12
+ config :source, :validate => :string, :default => "message"
13
+
14
+ # The name of the container to put the result
15
+ #
16
+ config :target, :validate => :string, :default => "message"
17
+
18
+ config :field, :validate => :string
19
+
20
+ # Expire time in seconds
21
+ config :ttl => :number
22
+
23
+ # Informs if the connection is to be made with SSL or not
24
+ config :ssl => :boolean
25
+
26
+ # For now only working for rpushnx and llen!
27
+ config :cmd_key_is_formatted, :validate => :boolean, :default => false
28
+
29
+ # The hostname(s) of your Redis server(s). Ports may be specified on any
30
+ # hostname, which will override the global port config.
31
+ # If the hosts list is an array, Logstash will pick one random host to connect to,
32
+ # if that host is disconnected it will then pick another.
33
+ #
34
+ # For example:
35
+ # [source,ruby]
36
+ # "127.0.0.1"
37
+ # ["127.0.0.1", "127.0.0.2"]
38
+ # ["127.0.0.1:6380", "127.0.0.1"]
39
+ config :host, :validate => :array, :default => ["127.0.0.1"]
40
+
41
+ # Shuffle the host list during Logstash startup.
42
+ config :shuffle_hosts, :validate => :boolean, :default => true
43
+
44
+ # The default port to connect on. Can be overridden on any hostname.
45
+ config :port, :validate => :number, :default => 6379
46
+
47
+ # The Redis database number.
48
+ config :db, :validate => :number, :default => 0
49
+
50
+ # Redis initial connection timeout in seconds.
51
+ config :timeout, :validate => :number, :default => 5
52
+
53
+ # Password to authenticate with. There is no authentication by default.
54
+ config :password, :validate => :password
55
+
56
+ # Interval for reconnecting to failed Redis connections
57
+ config :reconnect_interval, :validate => :number, :default => 1
58
+
59
+ # Maximal count of command retries after a crash because of a failure
60
+ config :max_retries, :validate => :number, :default => 3
61
+
62
+ # Interval for retrying to acquire a lock
63
+ config :lock_retry_interval, :validate => :number, :default => 1
64
+
65
+ # Maximal count of retries to acquire a lock
66
+ config :max_lock_retries, :validate => :number, :default => 3
67
+
68
+ config :get, :validate => :string
69
+
70
+ config :set, :validate => :string
71
+
72
+ config :setex, :validate => :string
73
+
74
+ config :exists, :validate => :string
75
+
76
+ config :del, :validate => :string
77
+
78
+ # # Sets the action. If set to true, it will get the data from redis cache
79
+ # config :get, :validate => :boolean, :default => false
80
+ config :llen, :validate => :string
81
+
82
+ # # Sets the action. If set to true, it will get the data from redis cache
83
+ # config :get, :validate => :boolean, :default => false
84
+ config :rpush, :validate => :string
85
+
86
+ # # Sets the action. If set to true, it will get the data from redis cache
87
+ # config :get, :validate => :boolean, :default => false
88
+ config :rpushnx, :validate => :string
89
+
90
+ # Sets the action. If set to true, it will get the data from redis cache
91
+ config :hset, :validate => :string
92
+
93
+ # Sets the action. If set to true, it will get the data from redis cache
94
+ config :hget, :validate => :string
95
+
96
+ config :sadd, :validate => :string
97
+
98
+ config :sismember, :validate => :string
99
+
100
+ config :smembers, :validate => :string
101
+
102
+ config :scard, :validate => :string
103
+
104
+ # config :get, :validate => :boolean, :default => false
105
+ config :lock_timeout, :validate => :number, :default => 5000
106
+
107
+ # # Sets the action. If set to true, it will get the data from redis cache
108
+ # config :get, :validate => :boolean, :default => false
109
+ config :rpop, :validate => :string
110
+
111
+ # # Sets the action. If set to true, it will get the data from redis cache
112
+ # config :get, :validate => :boolean, :default => false
113
+ config :lpop, :validate => :string
114
+
115
+ # # Sets the action. If set to true, it will get the data from redis cache
116
+ # config :get, :validate => :boolean, :default => false
117
+ # O(N)
118
+ config :lget, :validate => :string
119
+
120
+
121
+ public
122
+ def register
123
+ @redis = nil
124
+ @lock_manager = nil
125
+ if @shuffle_hosts
126
+ @host.shuffle!
127
+ end
128
+ @host_idx = 0
129
+ end # def register
130
+
131
+
132
+ def filter(event)
133
+
134
+ # TODO: Maybe refactor the interface into a more flexible one with two
135
+ # main configs 'cmd' & 'args'. Then it would be possible to eliminate
136
+ # all if clauses and replace it through one hashmap call, where
137
+ # the hashmap would be a mapping from 'cmd' -> <cmd_function_ref>
138
+ # E.q.: cmds.fetch(event.get(@llen), &method(:cmd_not_found_err))
139
+ max_retries = @max_retries
140
+ begin
141
+ @redis ||= connect
142
+
143
+ if @get
144
+ event.set(@target, @redis.get(event.get(@get)))
145
+ end
146
+
147
+ if @set
148
+ @redis.set(event.get(@set), event.get(@source))
149
+ end
150
+
151
+ if @setex
152
+ @redis.setex(event.get(@setex), event.get(@ttl), event.get(@source))
153
+ end
154
+
155
+ if @exists
156
+ @redis.exists(event.get(@exists))
157
+ end
158
+
159
+ if @del
160
+ @redis.del(event.get(@del))
161
+ end
162
+
163
+ if @hget
164
+ event.set(@target, @redis.hget(event.get(@hget), event.get(@source)))
165
+ end
166
+
167
+ if @hset
168
+ @redis.hset(event.get(@hset), event.get(@field), event.get(@source))
169
+ end
170
+
171
+ if @sadd
172
+ @redis.sadd(event.get(@sadd), event.get(@source))
173
+ end
174
+
175
+ if @sismember
176
+ event.set(@target, @redis.sismember(event.get(@sismember), event.get(@source)))
177
+ end
178
+
179
+ if @smembers
180
+ @redis.smembers(event.get(@smembers))
181
+ end
182
+
183
+ if @scard
184
+ event.set(@target, @redis.scard(event.get(@scard)))
185
+ end
186
+
187
+ if @llen
188
+ key = @cmd_key_is_formatted ? event.sprintf(@llen) : event.get(@llen)
189
+ event.set(@target, @redis.llen(key))
190
+ end
191
+
192
+ if @rpush
193
+ @redis.rpush(event.get(@rpush), event.get(@source))
194
+ end
195
+
196
+ if @rpushnx
197
+ key = @cmd_key_is_formatted ? event.sprintf(@rpushnx) : event.get(@rpushnx)
198
+ max_lock_retries = @max_lock_retries
199
+ begin
200
+ @lock_manager ||= connect_lockmanager
201
+ @lock_manager.lock!("lock_#{key}", @lock_timeout) do
202
+ @redis.rpush(key, event.get(@source)) unless @redis.exists(key)
203
+ end
204
+ rescue Redlock::LockError => e
205
+ @logger.warn("Failed to lock section 'rpushnx' for key: #{key}",
206
+ :event => event, :exception => e)
207
+ sleep @lock_retry_interval
208
+ max_lock_retries -= 1
209
+ unless max_lock_retries < 0
210
+ retry
211
+ else
212
+ @logger.error("Max retries reached for trying to lock section 'rpushnx' for key: #{key}",
213
+ :event => event, :exception => e)
214
+ end
215
+ end
216
+ end
217
+
218
+ if @rpop
219
+ event.set(@target, @redis.rpop(event.get(@rpop)))
220
+ end
221
+
222
+ if @lget
223
+ event.set(@target, @redis.lrange(event.get(@lget), 0, -1))
224
+ end
225
+
226
+ rescue => e
227
+ @logger.warn("Failed to send event to Redis, retrying after #{@reconnect_interval} seconds...", :event => event,
228
+ :exception => e, :backtrace => e.backtrace)
229
+ sleep @reconnect_interval
230
+ @redis = nil
231
+ @lock_manager = nil
232
+ max_retries -= 1
233
+ unless max_retries < 0
234
+ retry
235
+ else
236
+ @logger.error("Max retries reached for trying to execute a command",
237
+ :event => event, :exception => e)
238
+ end
239
+ end
240
+
241
+ # filter_matched should go in the last line of our successful code
242
+ filter_matched(event)
243
+ end # def filter
244
+
245
+
246
+ private
247
+ def connect
248
+ @current_host, @current_port = @host[@host_idx].split(':')
249
+ @host_idx = @host_idx + 1 >= @host.length ? 0 : @host_idx + 1
250
+
251
+ if not @current_port
252
+ @current_port = @port
253
+ end
254
+
255
+ params = {
256
+ :host => @current_host,
257
+ :port => @current_port,
258
+ :timeout => @timeout,
259
+ :db => @db,
260
+ :ssl => @ssl
261
+ }
262
+
263
+ @logger.debug("connection params", params)
264
+
265
+ if @password
266
+ params[:password] = @password.value
267
+ end
268
+
269
+ Redis.new(params)
270
+ end # def connect
271
+
272
+ def connect_lockmanager
273
+ @protocol = @ssl ? 'rediss://' : 'redis://'
274
+
275
+ hosts = Array(@host).map { |host|
276
+ host.prepend(@protocol) unless host.start_with?(@protocol)
277
+ }
278
+
279
+ @logger.debug("lock_manager hosts", hosts)
280
+
281
+ Redlock::Client.new(hosts)
282
+ end # def connect
283
+
284
+ end # class LogStash::Filters::Example
@@ -1,25 +1,26 @@
1
- Gem::Specification.new do |s|
2
- s.name = 'logstash-filter-rediss'
3
- s.version = '0.3.4'
4
- s.licenses = ['MIT']
5
- s.summary = "Redis Cache Filter for Logstash"
6
- s.description = "A Logstash filter plugin for storing and retrieving data from redis cache. This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gem_name. This gem is not a stand-alone program."
7
- s.authors = ["David Robakowski"]
8
- s.email = 'david.robakowski@synlay.com'
9
- s.homepage = "https://github.com/bruno-sales/logstash-filter-cache-redis"
10
- s.require_paths = ["lib"]
11
-
12
- # Files
13
- s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE']
14
- # Tests
15
- s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
-
17
- # Special flag to let us know this is actually a logstash plugin
18
- s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
19
-
20
- # Gem dependencies
21
- s.add_runtime_dependency "logstash-core-plugin-api", "~> 2.0"
22
- s.add_runtime_dependency 'redis', '~> 3.3', '>= 3.3.3'
23
- s.add_runtime_dependency 'redlock', '~> 0.2', '>= 0.2.0'
24
- s.add_development_dependency 'logstash-devutils', '~> 0'
25
- end
1
+ Gem::Specification.new do |s|
2
+ s.name = 'logstash-filter-rediss'
3
+ s.version = '0.3.5'
4
+ s.licenses = ['MIT']
5
+ s.summary = "Redis Cache Filter for Logstash"
6
+ s.description = "A Logstash filter plugin for storing and retrieving data from redis cache. This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gem_name. This gem is not a stand-alone program."
7
+ s.authors = ["David Robakowski"]
8
+ s.email = 'david.robakowski@synlay.com'
9
+ s.homepage = "https://github.com/bruno-sales/logstash-filter-cache-redis"
10
+ s.require_paths = ["lib"]
11
+ s.platform = Gem::Platform::JAVA if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
12
+
13
+ # Files
14
+ s.files = Dir['lib/**/*','spec/**/*','vendor/**/*','*.gemspec','*.md','CONTRIBUTORS','Gemfile','LICENSE']
15
+ # Tests
16
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
17
+
18
+ # Special flag to let us know this is actually a logstash plugin
19
+ s.metadata = { "logstash_plugin" => "true", "logstash_group" => "filter" }
20
+
21
+ # Gem dependencies
22
+ s.add_runtime_dependency "logstash-core-plugin-api", "~> 2.0"
23
+ s.add_runtime_dependency 'redis', '~> 3.3', '>= 3.3.3'
24
+ s.add_runtime_dependency 'redlock', '~> 0.2', '>= 0.2.0'
25
+ s.add_development_dependency 'logstash-devutils', '~> 0'
26
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-rediss
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Robakowski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-01 00:00:00.000000000 Z
11
+ date: 2019-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logstash-core-plugin-api
@@ -48,22 +48,22 @@ dependencies:
48
48
  name: redlock
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: 0.2.0
54
51
  - - "~>"
55
52
  - !ruby/object:Gem::Version
56
53
  version: '0.2'
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 0.2.0
57
57
  type: :runtime
58
58
  prerelease: false
59
59
  version_requirements: !ruby/object:Gem::Requirement
60
60
  requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- version: 0.2.0
64
61
  - - "~>"
65
62
  - !ruby/object:Gem::Version
66
63
  version: '0.2'
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 0.2.0
67
67
  - !ruby/object:Gem::Dependency
68
68
  name: logstash-devutils
69
69
  requirement: !ruby/object:Gem::Requirement
@@ -115,7 +115,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
115
  - !ruby/object:Gem::Version
116
116
  version: '0'
117
117
  requirements: []
118
- rubygems_version: 3.0.3
118
+ rubyforge_project:
119
+ rubygems_version: 2.7.7
119
120
  signing_key:
120
121
  specification_version: 4
121
122
  summary: Redis Cache Filter for Logstash