fluent-plugin-ddl-redis-store 0.3.0 → 0.3.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e297bfd4b33f894d418409472cfe990597772affc569fecb1d1a371d9c45b19e
4
- data.tar.gz: ec63c76ec0074f18da13daa82a4ca82a9a5b93d5e312eb2415d850d1095ff71c
3
+ metadata.gz: af55b99d427e9fe7a98c858d8e654677f2fe707694db40fcaf20b327a96f7ed1
4
+ data.tar.gz: c5e088703cf5d27aa7bbbad6cd6de33beed94027b86df0683e63fe845a2fc873
5
5
  SHA512:
6
- metadata.gz: 5720f4a0aad3fe67fff9fcd8fee15f61a58e08e2868cdd4f2dfeb1e8ee46644ee950f81c6d99345737bcef8ac668ce2fb5927b605a2dd7b11567866cecf9b05d
7
- data.tar.gz: 5d28612ac90fcdc9614b170eb706fa673cc0be75d7394e6e1394ffae0d042049c9c055960ae91dbea2a0872d7bcecfb6cb8cc0dbc75621ec3be5722173309312
6
+ metadata.gz: f138decaa02bfdb0fe9410c70a14def933cce2ceb9484fba1d7d6e38a367fe311fd24a4d8060c1a916ea2e5fdaf8a07cd438fe1930572468cea1398c8155c59d
7
+ data.tar.gz: 42f7c294e76ab3bf5ad43e930fe73638cb4a5906d005b71fef0f04d3a0a2a945d22231a4e15a3c408ff43b18ba508b080a2e8daf0ec8c841683012dcac2a9700
@@ -0,0 +1 @@
1
+ * @cerebrotech/eng-distributions
@@ -0,0 +1,25 @@
1
+ ## PR Type
2
+ What kind of change does this PR introduce?
3
+
4
+ <!-- Please check the one that applies to this PR using "x". -->
5
+ - [ ] Bugfix
6
+ - [ ] Feature
7
+ - [ ] Code style update (formatting)
8
+ - [ ] Refactoring (no functional changes)
9
+ - [ ] CI-related changes
10
+ - [ ] Other... Please describe:
11
+
12
+ ## What is the current behavior?
13
+ <!-- Please describe the current behavior that you are modifying, or link to a relevant issue. -->
14
+
15
+ Issue Number: https://dominodatalab.atlassian.net/browse/PLAT-XYZ
16
+
17
+ ## What is the new behavior?
18
+
19
+ ## Does this PR introduce a breaking change?
20
+ - [ ] Yes
21
+ - [ ] No
22
+
23
+ <!-- If this PR contains a breaking change, please describe the impact and migration path for existing applications below. -->
24
+
25
+ ## Other information
@@ -0,0 +1,44 @@
1
+ name: test
2
+ on:
3
+ push:
4
+ branches: [master]
5
+ pull_request:
6
+
7
+ jobs:
8
+ unit:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ ruby: ["3.2", "3.3", "3.4"]
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ - uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: ${{ matrix.ruby }}
18
+ bundler-cache: true
19
+ - run: bundle exec rake test
20
+
21
+ integration:
22
+ runs-on: ubuntu-latest
23
+ services:
24
+ redis:
25
+ image: redis:7-alpine
26
+ ports: ["6379:6379"]
27
+ options: >-
28
+ --health-cmd "redis-cli ping"
29
+ --health-interval 5s
30
+ --health-timeout 3s
31
+ --health-retries 5
32
+ strategy:
33
+ matrix:
34
+ ruby: ["3.2", "3.3", "3.4"]
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+ - uses: ruby/setup-ruby@v1
38
+ with:
39
+ ruby-version: ${{ matrix.ruby }}
40
+ bundler-cache: true
41
+ - run: bundle exec rake test:integration
42
+ env:
43
+ REDIS_HOST: 127.0.0.1
44
+ REDIS_PORT: 6379
data/.gitignore CHANGED
@@ -1 +1,8 @@
1
1
  *.gem
2
+ pkg/
3
+ .bundle/
4
+ vendor/
5
+ Gemfile.lock
6
+ *.log
7
+ .DS_Store
8
+ coverage/
data/README.md CHANGED
@@ -10,15 +10,31 @@ Requirements
10
10
 
11
11
  | fluent-plugin-redis-store | fluentd | ruby |
12
12
  |------------------------|---------|------|
13
- | >= 0.2.0 | >= v0.14.15 | >= 2.1 |
13
+ | >= 0.3.0 | >= v0.14.15 | >= 3.2 |
14
+ | >= 0.2.0, < 0.3.0 | >= v0.14.15 | >= 2.1 |
14
15
  | < 0.2.0 | >= v0.12.0 | >= 1.9 |
15
16
 
16
17
  Background
17
18
  ----------
18
19
 
19
- This is folked project from [fluent-plugin-redisstore][].
20
+ This is a forked project from [fluent-plugin-redis-store][].
21
+
22
+ [fluent-plugin-redis-store]: https://github.com/pokehanai/fluent-plugin-redis-store/
23
+
24
+ Release Process
25
+ ---------------
26
+ 1. Bump `version` in `fluent-plugin-ddl-redis-store.gemspec`
27
+ 2. Bump `version` in `domino.yml` to match. It is **not** kept in sync automatically —
28
+ unlike sibling `domino.yml`s that track an external base image via Renovate, this one
29
+ tracks the gem's own release number, which nothing here polls or rewrites for you.
30
+ 3. `gem build fluent-plugin-ddl-redis-store.gemspec`
31
+ 4. `gem push <.gem file>` (with the gem file generated in the previous step)
32
+ Ex: `gem push fluent-plugin-ddl-redis-store-0.3.1.gem`
33
+
34
+ The `push` command needs to be authenticated with [RubyGems.org](https://rubygems.org/).
35
+
36
+ Latest release: https://rubygems.org/gems/fluent-plugin-ddl-redis-store
20
37
 
21
- [fluent-plugin-redisstore]: https://github.com/moaikids/fluent-plugin-redisstore
22
38
 
23
39
  Features
24
40
  --------
@@ -92,10 +108,10 @@ Installation
92
108
  ------------
93
109
 
94
110
  ```bash
95
- fluent-gem install fluent-plugin-redis-store
111
+ fluent-gem install fluent-plugin-ddl-redis-store
96
112
 
97
113
  # or if you are using td-agent:
98
- td-agent-gem install fluent-plugin-redis-store
114
+ td-agent-gem install fluent-plugin-ddl-redis-store
99
115
  ```
100
116
 
101
117
  Configuration
@@ -161,6 +177,31 @@ based on *timestamp* and it deletes expired _members_ every after new event data
161
177
  No more options than common options.
162
178
 
163
179
 
180
+ Testing
181
+ -------
182
+
183
+ Unit tests (`test/plugin/`) stub out the `Redis` class entirely and only exercise
184
+ config parsing and key/value traversal -- they cannot detect a redis-rb client API
185
+ break.
186
+
187
+ ```bash
188
+ bundle exec rake test
189
+ ```
190
+
191
+ Integration tests (`test/integration/`) run against a real Redis server and assert
192
+ on actual `ZCARD`/`LLEN`/`GET`/etc. Start one first:
193
+
194
+ ```bash
195
+ docker run -d --rm -p 6379:6379 redis:7-alpine
196
+ bundle exec rake test:integration
197
+ ```
198
+
199
+ They read `REDIS_HOST`/`REDIS_PORT` from the environment (default `127.0.0.1:6379`)
200
+ and are skipped with a message if no Redis is reachable.
201
+
202
+ Note: redis-rb 6.x requires Ruby 3.2+; if your local Ruby is older, run both tasks
203
+ inside a container that matches the target fluentd image's Ruby/redis-rb version.
204
+
164
205
  Contributors
165
206
  ------------
166
207
 
data/Rakefile CHANGED
@@ -4,7 +4,14 @@ require "bundler/gem_tasks"
4
4
  require 'rake/testtask'
5
5
  Rake::TestTask.new(:test) do |test|
6
6
  test.libs << 'lib' << 'test'
7
- test.pattern = 'test/**/test_*.rb'
7
+ test.pattern = 'test/plugin/**/test_*.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ desc "Integration tests against a real Redis server (see test/integration for setup)"
12
+ Rake::TestTask.new('test:integration') do |test|
13
+ test.libs << 'lib' << 'test'
14
+ test.pattern = 'test/integration/**/test_*.rb'
8
15
  test.verbose = true
9
16
  end
10
17
 
data/domino.yml ADDED
@@ -0,0 +1,7 @@
1
+ workflowVersion: 0
2
+ name: fluent-plugin-redis-store
3
+ type: library
4
+ version: 0.3.1
5
+ versionFormat: semver
6
+ language:
7
+ name: shell
@@ -2,7 +2,7 @@
2
2
  Gem::Specification.new do |gem|
3
3
  gem.name = "fluent-plugin-ddl-redis-store"
4
4
  gem.email = "builds@dominodatalab.com"
5
- gem.version = "0.3.0"
5
+ gem.version = "0.3.1"
6
6
  gem.authors = ["moaikids", "HANAI Tohru aka pokehanai"]
7
7
  gem.licenses = ["Apache License Version 2.0"]
8
8
  gem.summary = %q{Redis(zset/set/list/string/publish) output plugin for Fluentd}
@@ -17,5 +17,5 @@ Gem::Specification.new do |gem|
17
17
  gem.add_development_dependency "rake"
18
18
  gem.add_development_dependency "test-unit"
19
19
  gem.add_runtime_dependency "fluentd", [">= 0.14.15", "< 2"]
20
- gem.add_runtime_dependency "redis"
20
+ gem.add_runtime_dependency "redis", [">= 5.0", "< 7"]
21
21
  end
@@ -55,10 +55,10 @@ module Fluent::Plugin
55
55
  super
56
56
  if @path
57
57
  @redis = Redis.new(:path => @path, :password => @password,
58
- :timeout => @timeout, :thread_safe => true, :db => @db)
58
+ :timeout => @timeout, :db => @db)
59
59
  else
60
60
  @redis = Redis.new(:host => @host, :port => @port, :password => @password,
61
- :timeout => @timeout, :thread_safe => true, :db => @db)
61
+ :timeout => @timeout, :db => @db)
62
62
  end
63
63
  end
64
64
 
@@ -80,7 +80,7 @@ module Fluent::Plugin
80
80
  end
81
81
 
82
82
  def write(chunk)
83
- @redis.pipelined {
83
+ @redis.pipelined { |pipeline|
84
84
  chunk.open { |io|
85
85
  begin
86
86
  MessagePack::Unpacker.new(io).each { |message|
@@ -88,15 +88,15 @@ module Fluent::Plugin
88
88
  (_, time, record) = message
89
89
  case @store_type
90
90
  when 'zset'
91
- operation_for_zset(record, time)
91
+ operation_for_zset(pipeline, record, time)
92
92
  when 'set'
93
- operation_for_set(record)
93
+ operation_for_set(pipeline, record)
94
94
  when 'list'
95
- operation_for_list(record)
95
+ operation_for_list(pipeline, record)
96
96
  when 'string'
97
- operation_for_string(record)
97
+ operation_for_string(pipeline, record)
98
98
  when 'publish'
99
- operation_for_publish(record)
99
+ operation_for_publish(pipeline, record)
100
100
  end
101
101
  rescue NoMethodError => e
102
102
  puts e
@@ -113,66 +113,66 @@ module Fluent::Plugin
113
113
  }
114
114
  end
115
115
 
116
- def operation_for_zset(record, time)
116
+ def operation_for_zset(pipeline, record, time)
117
117
  key = get_key_from(record)
118
118
  value = get_value_from(record)
119
119
  score = get_score_from(record, time)
120
120
  if @collision_policy
121
121
  if @collision_policy == 'NX'
122
- @redis.zadd(key, score, value, :nx => true)
122
+ pipeline.zadd(key, score, value, :nx => true)
123
123
  elsif @collision_policy == 'XX'
124
- @redis.zadd(key, score, value, :xx => true)
124
+ pipeline.zadd(key, score, value, :xx => true)
125
125
  end
126
126
  else
127
- @redis.zadd(key, score, value)
127
+ pipeline.zadd(key, score, value)
128
128
  end
129
129
 
130
- set_key_expire key
130
+ set_key_expire pipeline, key
131
131
  if 0 < @value_expire
132
132
  now = Time.now.to_i
133
- @redis.zremrangebyscore key , '-inf' , (now - @value_expire)
133
+ pipeline.zremrangebyscore key , '-inf' , (now - @value_expire)
134
134
  end
135
135
  if 0 < @value_length
136
136
  script = generate_zremrangebyrank_script(key, @value_length, @order)
137
- @redis.eval script
137
+ pipeline.eval script
138
138
  end
139
139
  end
140
140
 
141
- def operation_for_set(record)
141
+ def operation_for_set(pipeline, record)
142
142
  key = get_key_from(record)
143
143
  value = get_value_from(record)
144
- @redis.sadd key, value
145
- set_key_expire key
144
+ pipeline.sadd key, value
145
+ set_key_expire pipeline, key
146
146
  end
147
147
 
148
- def operation_for_list(record)
148
+ def operation_for_list(pipeline, record)
149
149
  key = get_key_from(record)
150
150
  value = get_value_from(record)
151
151
 
152
152
  if @order == 'asc'
153
- @redis.rpush key, value
153
+ pipeline.rpush key, value
154
154
  else
155
- @redis.lpush key, value
155
+ pipeline.lpush key, value
156
156
  end
157
- set_key_expire key
157
+ set_key_expire pipeline, key
158
158
  if 0 < @value_length
159
159
  script = generate_ltrim_script(key, @value_length, @order)
160
- @redis.eval script
160
+ pipeline.eval script
161
161
  end
162
162
  end
163
163
 
164
- def operation_for_string(record)
164
+ def operation_for_string(pipeline, record)
165
165
  key = get_key_from(record)
166
166
  value = get_value_from(record)
167
- @redis.set key, value
167
+ pipeline.set key, value
168
168
 
169
- set_key_expire key
169
+ set_key_expire pipeline, key
170
170
  end
171
171
 
172
- def operation_for_publish(record)
172
+ def operation_for_publish(pipeline, record)
173
173
  key = get_key_from(record)
174
174
  value = get_value_from(record)
175
- @redis.publish key, value
175
+ pipeline.publish key, value
176
176
  end
177
177
 
178
178
  def generate_zremrangebyrank_script(key, maxlen, order)
@@ -253,9 +253,9 @@ module Fluent::Plugin
253
253
  end
254
254
  end
255
255
 
256
- def set_key_expire(key)
256
+ def set_key_expire(pipeline, key)
257
257
  if 0 < @key_expire
258
- @redis.expire key, @key_expire
258
+ pipeline.expire key, @key_expire
259
259
  end
260
260
  end
261
261
 
data/renovate.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "description": "Renovate config",
4
+ "extends": [
5
+ "github>cerebrotech/renovate-config"
6
+ ],
7
+ "packageRules": [
8
+ {
9
+ "description": "Require manual review for major bumps of the redis gem; a two-major-version unattended jump (redis-rb 4.8 -> 6.0) previously broke fluentd at boot (Redis.new ArgumentError) and silently stopped batching in write() -- see the matching rule in the sibling operations-fluentd-docker renovate config",
10
+ "matchManagers": ["bundler"],
11
+ "matchPackageNames": ["redis"],
12
+ "matchUpdateTypes": ["major"],
13
+ "enabled": false
14
+ }
15
+ ],
16
+ "vulnerabilityAlerts": {
17
+ "enabled": true
18
+ }
19
+ }
@@ -0,0 +1,151 @@
1
+ require 'helpers'
2
+ require 'redis'
3
+ require 'securerandom'
4
+
5
+ # These tests exercise the plugin against a real Redis server, unlike
6
+ # test/plugin/test_out_redis_publish.rb which stubs out the entire Redis
7
+ # class and therefore cannot detect a redis-rb client API break (e.g. the
8
+ # `pipelined` block-argument change between redis-rb 4.x and 5.x/6.x).
9
+ #
10
+ # Run a real Redis first:
11
+ # docker run -d --rm -p 6379:6379 redis:7-alpine
12
+ # then:
13
+ # bundle exec rake test:integration
14
+ class RedisStoreOutputIntegrationTest < Test::Unit::TestCase
15
+ REDIS_HOST = ENV['REDIS_HOST'] || '127.0.0.1'
16
+ REDIS_PORT = (ENV['REDIS_PORT'] || 6379).to_i
17
+
18
+ def setup
19
+ Fluent::Test.setup
20
+ @redis = Redis.new(host: REDIS_HOST, port: REDIS_PORT, timeout: 2.0)
21
+ begin
22
+ @redis.ping
23
+ rescue StandardError => e
24
+ omit "no Redis reachable at #{REDIS_HOST}:#{REDIS_PORT} (#{e.class}: #{e.message});" \
25
+ " start one with `docker run -d --rm -p 6379:6379 redis:7-alpine` to run integration tests"
26
+ end
27
+ @key = "fluent-plugin-redis-store-test:#{SecureRandom.hex(8)}"
28
+ end
29
+
30
+ def teardown
31
+ @redis.del(@key) if @redis
32
+ end
33
+
34
+ def create_driver(conf)
35
+ Fluent::Test::Driver::Output.new(Fluent::Plugin::RedisStoreOutput).configure(conf)
36
+ end
37
+
38
+ def get_time
39
+ event_time("2011-01-02 13:14:15 UTC")
40
+ end
41
+
42
+ def test_zset_batches_many_records_through_one_pipeline
43
+ config = %[
44
+ host #{REDIS_HOST}
45
+ port #{REDIS_PORT}
46
+ store_type zset
47
+ key #{@key}
48
+ score_path result
49
+ ]
50
+ d = create_driver(config)
51
+ d.run(default_tag: 'test') do
52
+ 50.times { |i| d.feed(get_time, { 'result' => i }) }
53
+ end
54
+
55
+ assert_equal 50, @redis.zcard(@key)
56
+ end
57
+
58
+ def test_zset_collision_policy_nx_does_not_overwrite
59
+ @redis.zadd(@key, 1, 'v')
60
+ config = %[
61
+ host #{REDIS_HOST}
62
+ port #{REDIS_PORT}
63
+ store_type zset
64
+ key #{@key}
65
+ score_path result
66
+ collision_policy NX
67
+ ]
68
+ d = create_driver(config)
69
+ d.run(default_tag: 'test') do
70
+ d.feed(get_time, { 'result' => 99 })
71
+ end
72
+
73
+ assert_equal 1.0, @redis.zscore(@key, 'v')
74
+ end
75
+
76
+ def test_zset_value_length_trims_via_lua_eval
77
+ config = %[
78
+ host #{REDIS_HOST}
79
+ port #{REDIS_PORT}
80
+ store_type zset
81
+ key #{@key}
82
+ score_path result
83
+ value_length 3
84
+ ]
85
+ d = create_driver(config)
86
+ d.run(default_tag: 'test') do
87
+ 10.times { |i| d.feed(get_time, { 'result' => i }) }
88
+ end
89
+
90
+ # generate_zremrangebyrank_script removes one more entry than value_length
91
+ # on the 'asc' path (a pre-existing off-by-one, not introduced by the
92
+ # pipeline fix) -- this asserts current behavior, not a spec.
93
+ assert_equal 2, @redis.zcard(@key)
94
+ end
95
+
96
+ def test_list_rpush_asc
97
+ config = %[
98
+ host #{REDIS_HOST}
99
+ port #{REDIS_PORT}
100
+ format_type plain
101
+ store_type list
102
+ key #{@key}
103
+ value_path v
104
+ ]
105
+ d = create_driver(config)
106
+ d.run(default_tag: 'test') do
107
+ 5.times { |i| d.feed(get_time, { 'v' => i.to_s }) }
108
+ end
109
+
110
+ assert_equal 5, @redis.llen(@key)
111
+ assert_equal %w[0 1 2 3 4], @redis.lrange(@key, 0, -1)
112
+ end
113
+
114
+ def test_set_sadd
115
+ config = %[
116
+ host #{REDIS_HOST}
117
+ port #{REDIS_PORT}
118
+ format_type plain
119
+ store_type set
120
+ key #{@key}
121
+ value_path v
122
+ ]
123
+ d = create_driver(config)
124
+ d.run(default_tag: 'test') do
125
+ 3.times { |i| d.feed(get_time, { 'v' => "member-#{i}" }) }
126
+ end
127
+
128
+ assert_equal 3, @redis.scard(@key)
129
+ assert_equal true, @redis.sismember(@key, 'member-1')
130
+ end
131
+
132
+ def test_string_set_and_key_expire
133
+ config = %[
134
+ host #{REDIS_HOST}
135
+ port #{REDIS_PORT}
136
+ format_type plain
137
+ store_type string
138
+ key #{@key}
139
+ value_path v
140
+ key_expire 30
141
+ ]
142
+ d = create_driver(config)
143
+ d.run(default_tag: 'test') do
144
+ d.feed(get_time, { 'v' => 'hello' })
145
+ end
146
+
147
+ assert_equal 'hello', @redis.get(@key)
148
+ ttl = @redis.ttl(@key)
149
+ assert ttl > 0 && ttl <= 30, "expected 0 < ttl <= 30, got #{ttl}"
150
+ end
151
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-ddl-redis-store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - moaikids
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-11-21 00:00:00.000000000 Z
12
+ date: 2026-09-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -65,28 +65,40 @@ dependencies:
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '5.0'
69
+ - - "<"
70
+ - !ruby/object:Gem::Version
71
+ version: '7'
69
72
  type: :runtime
70
73
  prerelease: false
71
74
  version_requirements: !ruby/object:Gem::Requirement
72
75
  requirements:
73
76
  - - ">="
74
77
  - !ruby/object:Gem::Version
75
- version: '0'
78
+ version: '5.0'
79
+ - - "<"
80
+ - !ruby/object:Gem::Version
81
+ version: '7'
76
82
  description: Redis(zset/set/list/string/publish) output plugin for Fluentd...
77
83
  email: builds@dominodatalab.com
78
84
  executables: []
79
85
  extensions: []
80
86
  extra_rdoc_files: []
81
87
  files:
88
+ - ".github/CODEOWNERS"
89
+ - ".github/PULL_REQUEST_TEMPLATE.md"
90
+ - ".github/workflows/test.yml"
82
91
  - ".gitignore"
83
92
  - AUTHORS
84
93
  - Gemfile
85
94
  - README.md
86
95
  - Rakefile
96
+ - domino.yml
87
97
  - fluent-plugin-ddl-redis-store.gemspec
88
98
  - lib/fluent/plugin/out_redis_store.rb
99
+ - renovate.json
89
100
  - test/helpers.rb
101
+ - test/integration/test_out_redis_store_integration.rb
90
102
  - test/plugin/test_out_redis_publish.rb
91
103
  homepage: https://github.com/dominodatalab/fluent-plugin-redis-store
92
104
  licenses:
@@ -113,4 +125,5 @@ specification_version: 4
113
125
  summary: Redis(zset/set/list/string/publish) output plugin for Fluentd
114
126
  test_files:
115
127
  - test/helpers.rb
128
+ - test/integration/test_out_redis_store_integration.rb
116
129
  - test/plugin/test_out_redis_publish.rb