logstash-filter-rediss 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7f19ec0db128b3d2fab457046c9cef823897d334dc142c17230b9ee4d634f6dc
4
+ data.tar.gz: ecf92c21293d5a49d37fb3a958cdeb3cdbe14591732c1e5bef892b1aa034c452
5
+ SHA512:
6
+ metadata.gz: e162d6c193d0f035a4b23bf0a0e5a9bb960d1cce69883b286a0706f265d7a40d676b478976c6e39c8a3d82eaea91657352dec4fc16644c0833e20d6d37f20acc
7
+ data.tar.gz: '04908bcb693b5beefa287da14e49926958bb05100e617f606582c5f5cb0348e0bef8193992c6e1df46c8591991c7a71470ea84ee497f2d700fb48c60d76c32ef'
data/CHANGELOG.md ADDED
@@ -0,0 +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
data/CONTRIBUTORS ADDED
@@ -0,0 +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.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+ gem 'coveralls', require: false
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +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.
data/README.md ADDED
@@ -0,0 +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).
@@ -0,0 +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
@@ -0,0 +1,25 @@
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
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-filter-rediss
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.4
5
+ platform: ruby
6
+ authors:
7
+ - David Robakowski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-10-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logstash-core-plugin-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: redis
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.3'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 3.3.3
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '3.3'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 3.3.3
47
+ - !ruby/object:Gem::Dependency
48
+ name: redlock
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 0.2.0
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '0.2'
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: 0.2.0
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '0.2'
67
+ - !ruby/object:Gem::Dependency
68
+ name: logstash-devutils
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ description: A Logstash filter plugin for storing and retrieving data from redis cache.
82
+ This gem is a Logstash plugin required to be installed on top of the Logstash core
83
+ pipeline using $LS_HOME/bin/logstash-plugin install gem_name. This gem is not a
84
+ stand-alone program.
85
+ email: david.robakowski@synlay.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - CHANGELOG.md
91
+ - CONTRIBUTORS
92
+ - Gemfile
93
+ - LICENSE
94
+ - README.md
95
+ - lib/logstash/filters/rediss.rb
96
+ - logstash-filter-rediss.gemspec
97
+ homepage: https://github.com/bruno-sales/logstash-filter-cache-redis
98
+ licenses:
99
+ - MIT
100
+ metadata:
101
+ logstash_plugin: 'true'
102
+ logstash_group: filter
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubygems_version: 3.0.3
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Redis Cache Filter for Logstash
122
+ test_files: []