fluent-plugin-redisstore-data 0.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 +7 -0
- data/.gitignore +18 -0
- data/AUTHORS +1 -0
- data/Gemfile +3 -0
- data/README.rdoc +43 -0
- data/Rakefile +11 -0
- data/benchmarking/.gitignore +1 -0
- data/benchmarking/Gemfile +5 -0
- data/benchmarking/README.rdoc +15 -0
- data/benchmarking/default.conf +21 -0
- data/benchmarking/dummer.conf +13 -0
- data/benchmarking/hiredis.conf +22 -0
- data/benchmarking/monitor.rb +30 -0
- data/fluent-plugin-redisstore-data.gemspec +20 -0
- data/lib/fluent/plugin/out_redisstore.rb +220 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9e1ecf5297235faeb1ac35f5e26b16eb8b1bb2f6a117d13ffaa588e4c9195f3a
|
4
|
+
data.tar.gz: e853015c29e622eb0283bb6a9a25e0ab204f67ba0fdf318cab054065a13e4470
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 628aeefe1687b77217e18d496d4cc34aafce2b349681df75144fd780669bc94452701684052c263153f430bec2ec08fec140372fb25d5705b544981d1500e820
|
7
|
+
data.tar.gz: 1efa75869870ce64bda99196937472c7cd6e9434f9360ccebb24a43e8e30cb7d7e3ccab3ea9ade31b5e52fa47308ef642889d00ac3f54fee122fce1ce0f0297a
|
data/.gitignore
ADDED
data/AUTHORS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
moaikids
|
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
= Redis output plugin for Fluent event collector
|
2
|
+
|
3
|
+
== Overview
|
4
|
+
|
5
|
+
*redisstore* output plugin buffers event logs in local file and upload it to redis storage.
|
6
|
+
|
7
|
+
this sources folked 'fluent-plugin-redis'. (https://github.com/yuki24/fluent-plugin-redis)
|
8
|
+
|
9
|
+
== Installation
|
10
|
+
|
11
|
+
== Configuration
|
12
|
+
|
13
|
+
<match pattern>
|
14
|
+
type redisstore
|
15
|
+
host REDIS_HOST_ADDRESS(string, all , localhost)
|
16
|
+
port REDIS_PORT(int, all, 6379)
|
17
|
+
db_number REDIS_DB_NUMBER(int, all , nil)
|
18
|
+
timeout TIMEOUT(float, all , 5.0)
|
19
|
+
key_prefix prefix_(string, all, '')
|
20
|
+
key_suffix _suffix(string, all , '')
|
21
|
+
store_type zset(zset|set|list|string, all, zset)
|
22
|
+
key_name key(string, all, nil)
|
23
|
+
score_name score(string, all , nil)
|
24
|
+
value_name value(string, all, nill)
|
25
|
+
key_expire 604800(int, all, nil)
|
26
|
+
value_expire 86400(int , zset, nil)
|
27
|
+
value_length 100(int, zset|list, nil)
|
28
|
+
order asc(asc|desc, zset/list, nil)
|
29
|
+
</match>
|
30
|
+
|
31
|
+
# use hiredis for better performance
|
32
|
+
# this configuration requires "gem install hiredis"
|
33
|
+
<match pattern>
|
34
|
+
type redisstore
|
35
|
+
driver hiredis
|
36
|
+
...
|
37
|
+
</match>
|
38
|
+
|
39
|
+
== Copyright
|
40
|
+
|
41
|
+
Copyright:: Copyright (c) 2013 moaikids
|
42
|
+
License:: Apache License, Version 2.0
|
43
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
dummy.log
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<source>
|
2
|
+
type tail
|
3
|
+
path dummy.log
|
4
|
+
pos_file /var/tmp/_var_log_dummy.pos
|
5
|
+
format none
|
6
|
+
tag dummy
|
7
|
+
</source>
|
8
|
+
<match dummy>
|
9
|
+
type redisstore
|
10
|
+
host 127.0.0.1
|
11
|
+
timeout 15.0
|
12
|
+
store_type zset
|
13
|
+
key_name method
|
14
|
+
key_suffix _suffix
|
15
|
+
score_name uri
|
16
|
+
value_name reqtime
|
17
|
+
key_expire 604800
|
18
|
+
value_expire 259200
|
19
|
+
value_length 10
|
20
|
+
flush_interval 0.1
|
21
|
+
</match>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
configure 'sample' do
|
2
|
+
output "dummy.log"
|
3
|
+
rate 100000
|
4
|
+
delimiter "\t"
|
5
|
+
labeled true
|
6
|
+
field :id, type: :integer, countup: true, format: "%04d"
|
7
|
+
field :time, type: :datetime, format: "[%Y-%m-%d %H:%M:%S]", random: false
|
8
|
+
field :level, type: :string, any: %w[DEBUG INFO WARN ERROR]
|
9
|
+
field :method, type: :string, any: %w[GET POST PUT]
|
10
|
+
field :uri, type: :string, any: %w[/api/v1/people /api/v1/textdata /api/v1/messages]
|
11
|
+
field :reqtime, type: :float, range: 0.1..5.0
|
12
|
+
field :foobar, type: :string, length: 8
|
13
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<source>
|
2
|
+
type tail
|
3
|
+
path dummy.log
|
4
|
+
pos_file /var/tmp/_var_log_dummy.pos
|
5
|
+
format none
|
6
|
+
tag dummy
|
7
|
+
</source>
|
8
|
+
<match dummy>
|
9
|
+
type redisstore
|
10
|
+
driver hiredis
|
11
|
+
host 127.0.0.1
|
12
|
+
timeout 15.0
|
13
|
+
store_type zset
|
14
|
+
key_name method
|
15
|
+
key_suffix _suffix
|
16
|
+
score_name uri
|
17
|
+
value_name reqtime
|
18
|
+
key_expire 604800
|
19
|
+
value_expire 259200
|
20
|
+
value_length 10
|
21
|
+
flush_interval 0.1
|
22
|
+
</match>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'terminal-table'
|
5
|
+
require 'pp'
|
6
|
+
require 'redis'
|
7
|
+
require 'hiredis'
|
8
|
+
|
9
|
+
class RedisInfo
|
10
|
+
def initialize(host,port)
|
11
|
+
@redis = Redis.new(:host => host, :port => port, driver: :hiredis)
|
12
|
+
end
|
13
|
+
def get_total_commands_processed
|
14
|
+
@redis.info["total_commands_processed"].to_i
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
chk = RedisInfo.new("127.0.0.1","6379")
|
19
|
+
previous = 0
|
20
|
+
|
21
|
+
res = []
|
22
|
+
(1..30).each do |i|
|
23
|
+
current = chk.get_total_commands_processed
|
24
|
+
res << current - previous
|
25
|
+
previous = current
|
26
|
+
sleep 1
|
27
|
+
end
|
28
|
+
|
29
|
+
res.shift
|
30
|
+
puts "#{1.0 * res.inject(:+) / res.size} req/s"
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
Gem::Specification.new do |gem|
|
3
|
+
gem.name = "fluent-plugin-redisstore-data"
|
4
|
+
gem.version = "0.0.4"
|
5
|
+
gem.authors = ["moaikids"]
|
6
|
+
gem.licenses = ["Apache License Version 2.0"]
|
7
|
+
gem.summary = %q{Redis(zset/set/list/string) output plugin for Fluentd}
|
8
|
+
gem.description = %q{Redis(zset/set/list/string) output plugin for Fluentd...}
|
9
|
+
gem.homepage = "https://github.com/moaikids/fluent-plugin-redisstore"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.require_paths = ["lib"]
|
15
|
+
|
16
|
+
gem.add_development_dependency "rake"
|
17
|
+
gem.add_development_dependency "shoulda"
|
18
|
+
gem.add_runtime_dependency "fluentd"
|
19
|
+
gem.add_runtime_dependency "redis"
|
20
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
module Fluent
|
2
|
+
class RedisOutput < BufferedOutput
|
3
|
+
Fluent::Plugin.register_output('redisstore', self)
|
4
|
+
attr_reader :host, :port, :db_number, :redis, :timeout, :key_prefix, :key_suffix, :store_type, :key_name, :fixed_key_value, :score_name, :value_name, :key_expire, :value_expire, :value_length, :order
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
super
|
8
|
+
require 'redis'
|
9
|
+
require 'msgpack'
|
10
|
+
end
|
11
|
+
|
12
|
+
def configure(conf)
|
13
|
+
super
|
14
|
+
|
15
|
+
@driver = conf.has_key?('driver') ? conf['driver'] : nil
|
16
|
+
|
17
|
+
@host = conf.has_key?('host') ? conf['host'] : 'localhost'
|
18
|
+
@port = conf.has_key?('port') ? conf['port'].to_i : 6379
|
19
|
+
@db_number = conf.has_key?('db_number') ? conf['db_number'].to_i : nil
|
20
|
+
@timeout = conf.has_key?('timeout') ? conf['timeout'].to_f : 5.0
|
21
|
+
|
22
|
+
@key_prefix = conf.has_key?('key_prefix') ? conf['key_prefix'] : ''
|
23
|
+
@key_suffix = conf.has_key?('key_suffix') ? conf['key_suffix'] : ''
|
24
|
+
@store_type = conf.has_key?('store_type') ? conf['store_type'] : 'zset'
|
25
|
+
@key_name = conf['key_name']
|
26
|
+
#@fixed_key_value = conf.has_key?('fixed_key_value') ? conf['fixed_key_value'] : nil
|
27
|
+
@fixed_key_value = conf['fixed_key_value']
|
28
|
+
@score_name = conf['score_name']
|
29
|
+
@value_name = conf['value_name']
|
30
|
+
@key_expire = conf.has_key?('key_expire') ? conf['key_expire'].to_i : -1
|
31
|
+
@value_expire = conf.has_key?('value_expire') ? conf['value_expire'].to_i : -1
|
32
|
+
@value_length = conf.has_key?('value_length') ? conf['value_length'].to_i : -1
|
33
|
+
@order = conf.has_key?('order') ? conf['order'] : 'asc'
|
34
|
+
|
35
|
+
puts conf
|
36
|
+
puts 'Key_name: '+@key_name.to_s
|
37
|
+
puts 'Fixed_key_name: '+@fixed_key_name.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
def start
|
41
|
+
super
|
42
|
+
|
43
|
+
opt = {
|
44
|
+
:host => @host,
|
45
|
+
:port => @port,
|
46
|
+
:db => @db_number,
|
47
|
+
:timeout => @timeout,
|
48
|
+
:thread_safe => true,
|
49
|
+
}
|
50
|
+
|
51
|
+
if @driver
|
52
|
+
opt[:driver] = @driver.to_sym
|
53
|
+
end
|
54
|
+
|
55
|
+
@redis = Redis.new(opt)
|
56
|
+
end
|
57
|
+
|
58
|
+
def shutdown
|
59
|
+
super
|
60
|
+
|
61
|
+
@redis.quit
|
62
|
+
end
|
63
|
+
|
64
|
+
def format(tag, time, record)
|
65
|
+
identifier = [tag, time].join(".")
|
66
|
+
[identifier, record].to_msgpack
|
67
|
+
end
|
68
|
+
|
69
|
+
def write(chunk)
|
70
|
+
@redis.pipelined {
|
71
|
+
chunk.open { |io|
|
72
|
+
begin
|
73
|
+
MessagePack::Unpacker.new(io).each { |message|
|
74
|
+
begin
|
75
|
+
(tag, record) = message
|
76
|
+
if @store_type == 'zset'
|
77
|
+
operation_for_zset(record)
|
78
|
+
elsif @store_type == 'set'
|
79
|
+
operation_for_set(record)
|
80
|
+
elsif @store_type == 'list'
|
81
|
+
operation_for_list(record)
|
82
|
+
elsif @store_type == 'string'
|
83
|
+
operation_for_string(record)
|
84
|
+
end
|
85
|
+
rescue NoMethodError => e
|
86
|
+
puts e
|
87
|
+
end
|
88
|
+
}
|
89
|
+
rescue EOFError
|
90
|
+
# EOFError always occured when reached end of chunk.
|
91
|
+
end
|
92
|
+
}
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
def operation_for_zset(record)
|
97
|
+
now = Time.now.to_i
|
98
|
+
if @fixed_key_value
|
99
|
+
k = @fixed_key_value
|
100
|
+
else
|
101
|
+
k = traverse(record, @key_name).to_s
|
102
|
+
end
|
103
|
+
if @score_name
|
104
|
+
s = traverse(record, @score_name)
|
105
|
+
else
|
106
|
+
s = now
|
107
|
+
end
|
108
|
+
v = traverse(record, @value_name)
|
109
|
+
sk = @key_prefix + k + @key_suffix
|
110
|
+
|
111
|
+
@redis.zadd sk , s, v
|
112
|
+
if @key_expire > 0
|
113
|
+
@redis.expire sk , @key_expire
|
114
|
+
end
|
115
|
+
if @value_expire > 0
|
116
|
+
@redis.zremrangebyscore sk , '-inf' , (now - @value_expire)
|
117
|
+
end
|
118
|
+
if @value_length > 0
|
119
|
+
script = generate_zremrangebyrank_script(sk, @value_length, @order)
|
120
|
+
@redis.eval script
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def operation_for_set(record)
|
125
|
+
if @fixed_key_value
|
126
|
+
k = @fixed_key_value
|
127
|
+
else
|
128
|
+
k = @key_name
|
129
|
+
end
|
130
|
+
#v = traverse(record, @value_name)
|
131
|
+
sk = @key_prefix + k + @key_suffix
|
132
|
+
|
133
|
+
@redis.sadd sk, v
|
134
|
+
if @key_expire > 0
|
135
|
+
@redis.expire sk, @key_expire
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def operation_for_list(record)
|
140
|
+
if @fixed_key_value
|
141
|
+
k = @fixed_key_value
|
142
|
+
else
|
143
|
+
k = traverse(record, @key_name).to_s
|
144
|
+
end
|
145
|
+
v = traverse(record, @value_name)
|
146
|
+
sk = @key_prefix + k + @key_suffix
|
147
|
+
|
148
|
+
if @order == 'asc'
|
149
|
+
@redis.rpush sk, v
|
150
|
+
else
|
151
|
+
@redis.lpush sk, v
|
152
|
+
end
|
153
|
+
if @key_expire > 0
|
154
|
+
@redis.expire sk, @key_expire
|
155
|
+
end
|
156
|
+
if @value_length > 0
|
157
|
+
script = generate_ltrim_script(sk, @value_length, @order)
|
158
|
+
@redis.eval script
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def operation_for_string(record)
|
163
|
+
if @fixed_key_value
|
164
|
+
k = @fixed_key_value
|
165
|
+
else
|
166
|
+
k = @key_name
|
167
|
+
|
168
|
+
end
|
169
|
+
sk = @key_prefix + k + @key_suffix
|
170
|
+
data = record.to_s
|
171
|
+
@redis.set record[sk],data
|
172
|
+
end
|
173
|
+
|
174
|
+
def generate_zremrangebyrank_script(key, maxlen, order)
|
175
|
+
script = "local key = '" + key.to_s + "'\n"
|
176
|
+
script += "local maxlen = " + maxlen.to_s + "\n"
|
177
|
+
script += "local order ='" + order.to_s + "'\n"
|
178
|
+
script += "local len = tonumber(redis.call('ZCOUNT', key, '-inf', '+inf'))\n"
|
179
|
+
script += "if len > maxlen then\n"
|
180
|
+
script += " if order == 'asc' then\n"
|
181
|
+
script += " local l = len - maxlen\n"
|
182
|
+
script += " if l >= 0 then\n"
|
183
|
+
script += " return redis.call('ZREMRANGEBYRANK', key, 0, l)\n"
|
184
|
+
script += " end\n"
|
185
|
+
script += " else\n"
|
186
|
+
script += " return redis.call('ZREMRANGEBYRANK', key, maxlen, -1)\n"
|
187
|
+
script += " end\n"
|
188
|
+
script += "end\n"
|
189
|
+
return script
|
190
|
+
end
|
191
|
+
|
192
|
+
def generate_ltrim_script(key, maxlen, order)
|
193
|
+
script = "local key = '" + key.to_s + "'\n"
|
194
|
+
script += "local maxlen = " + maxlen.to_s + "\n"
|
195
|
+
script += "local order ='" + order.to_s + "'\n"
|
196
|
+
script += "local len = tonumber(redis.call('LLEN', key))\n"
|
197
|
+
script += "if len > maxlen then\n"
|
198
|
+
script += " if order == 'asc' then\n"
|
199
|
+
script += " local l = len - maxlen\n"
|
200
|
+
script += " return redis.call('LTRIM', key, l, -1)\n"
|
201
|
+
script += " else\n"
|
202
|
+
script += " return redis.call('LTRIM', key, 0, maxlen - 1)\n"
|
203
|
+
script += " end\n"
|
204
|
+
script += "end\n"
|
205
|
+
return script
|
206
|
+
end
|
207
|
+
|
208
|
+
def traverse(data, key)
|
209
|
+
val = data
|
210
|
+
key.split('.').each{ |k|
|
211
|
+
if val.has_key?(k)
|
212
|
+
val = val[k]
|
213
|
+
else
|
214
|
+
return nil
|
215
|
+
end
|
216
|
+
}
|
217
|
+
return val
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-redisstore-data
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- moaikids
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-04-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: shoulda
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: fluentd
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: redis
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Redis(zset/set/list/string) output plugin for Fluentd...
|
70
|
+
email:
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- ".gitignore"
|
76
|
+
- AUTHORS
|
77
|
+
- Gemfile
|
78
|
+
- README.rdoc
|
79
|
+
- Rakefile
|
80
|
+
- benchmarking/.gitignore
|
81
|
+
- benchmarking/Gemfile
|
82
|
+
- benchmarking/README.rdoc
|
83
|
+
- benchmarking/default.conf
|
84
|
+
- benchmarking/dummer.conf
|
85
|
+
- benchmarking/hiredis.conf
|
86
|
+
- benchmarking/monitor.rb
|
87
|
+
- fluent-plugin-redisstore-data.gemspec
|
88
|
+
- lib/fluent/plugin/out_redisstore.rb
|
89
|
+
homepage: https://github.com/moaikids/fluent-plugin-redisstore
|
90
|
+
licenses:
|
91
|
+
- Apache License Version 2.0
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubygems_version: 3.1.2
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Redis(zset/set/list/string) output plugin for Fluentd
|
112
|
+
test_files: []
|