flueconf 0.0.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 +7 -0
- data/lib/flueconf.rb +10 -0
- data/lib/flueconf/builder.rb +94 -0
- data/lib/flueconf/serializer.rb +44 -0
- data/lib/flueconf/version.rb +8 -0
- data/spec/flueconf_spec.rb +340 -0
- data/spec/spec_helper.rb +1 -0
- metadata +94 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9effe81389c67ea7f4b51c8683f99402fcc20cf5bc43a18f5200ea43a712b363
|
4
|
+
data.tar.gz: 697df4d11e65ecf85ec54427e5326e9231b6e75b320d2be589bd9ac3327bd872
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: eb218202d17afbd5afb401ab713e83cfe4ad748f6429af6d34089426cdc95cfc17c2bfc13e0080aa3de81bfe6a6dafd46cf8cc946d705142335c8ee89508de51
|
7
|
+
data.tar.gz: 212ef5b7c85e2fd53c4ddb8401c2623d353644d74fa19f4e9103b058ee09460ebf533d1baae430b94300ed091a46489f0a3dc40b6d365e2d92336cc7a87a842a
|
data/lib/flueconf.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Flueconf::Builder
|
4
|
+
def initialize(options = {}, &block)
|
5
|
+
@attributes = {}
|
6
|
+
@current = @attributes
|
7
|
+
@context = nil
|
8
|
+
|
9
|
+
build(&block) if block_given?
|
10
|
+
end
|
11
|
+
|
12
|
+
def build(&block)
|
13
|
+
return unless block_given?
|
14
|
+
|
15
|
+
@context = eval('self', block.binding)
|
16
|
+
|
17
|
+
instance_eval(&block)
|
18
|
+
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def label(*args, &block)
|
23
|
+
method = block_given? ? :label : :@label
|
24
|
+
add(method, *args, &block)
|
25
|
+
end
|
26
|
+
|
27
|
+
%i(type id).each do |method|
|
28
|
+
define_method method do |*args, &block|
|
29
|
+
add(:"@#{method}", *args, &block)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
%i(source match filter system).each do |method|
|
34
|
+
define_method method do |*args, &block|
|
35
|
+
add(method, *args, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_missing(method, *args, &block)
|
40
|
+
if @context and @context.respond_to?(method)
|
41
|
+
@context.send(method, *args, &block)
|
42
|
+
else
|
43
|
+
add(method, *args, &block)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def add(*args, &block)
|
48
|
+
if block_given?
|
49
|
+
obj = {}
|
50
|
+
k = args.first.to_sym
|
51
|
+
|
52
|
+
@current[k] = [] unless @current[k].is_a? Array
|
53
|
+
@current[k] << obj
|
54
|
+
|
55
|
+
c = obj
|
56
|
+
args[1..-1].each do |k|
|
57
|
+
obj = {}
|
58
|
+
c[k.to_sym] = obj
|
59
|
+
c = obj
|
60
|
+
end
|
61
|
+
|
62
|
+
previous = @current
|
63
|
+
@current = obj
|
64
|
+
instance_eval(&block)
|
65
|
+
@current = previous
|
66
|
+
elsif args.length >= 1
|
67
|
+
method = args.shift.to_sym
|
68
|
+
|
69
|
+
value = case args.length
|
70
|
+
when 0
|
71
|
+
nil
|
72
|
+
when 1
|
73
|
+
args.first
|
74
|
+
else
|
75
|
+
args
|
76
|
+
end
|
77
|
+
value = case value
|
78
|
+
when Hash
|
79
|
+
value.map { |k, v| v.nil? ? nil : "#{k}:#{v}" }.compact.join(',')
|
80
|
+
when Array
|
81
|
+
value.compact.join(',')
|
82
|
+
else
|
83
|
+
value
|
84
|
+
end
|
85
|
+
@current[method] = value
|
86
|
+
else
|
87
|
+
raise ArgumentError, "One key and at least one of values are required: #{args.join(',')}"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_fluent(*args)
|
92
|
+
Flueconf::Serializer.serialize(@attributes, *args)
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
class Flueconf::Serializer
|
4
|
+
class << self
|
5
|
+
def serialize(obj, options = {})
|
6
|
+
indent = options[:indent]
|
7
|
+
indent = 2 unless indent.is_a? Integer and indent >= 0
|
8
|
+
|
9
|
+
dump(obj, [], indent, 0)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def dump(obj, keys = [], indent = 0, depth = 0)
|
15
|
+
prefix = ' ' * indent * depth
|
16
|
+
key = keys.empty? ? nil : keys.join(' ')
|
17
|
+
|
18
|
+
case obj
|
19
|
+
when Array
|
20
|
+
obj.map do |v|
|
21
|
+
send(__method__, v, [key], indent, depth)
|
22
|
+
end.compact.join("\n")
|
23
|
+
when Hash
|
24
|
+
compacted = keys.empty? || (!obj.empty? && obj.values.all? { |v| v.is_a? Hash })
|
25
|
+
|
26
|
+
str = obj.map do |k, v|
|
27
|
+
k = k.to_s.strip
|
28
|
+
|
29
|
+
send(__method__, v, (compacted ? (keys + [k]) : [k]), indent, (compacted ? depth : depth + 1))
|
30
|
+
end.compact.join("\n")
|
31
|
+
|
32
|
+
compacted ? str : "#{prefix}<#{key}>\n" + (str.empty? ? '' : "#{str}\n") + "#{prefix}</#{keys.first}>"
|
33
|
+
when Numeric, TrueClass, FalseClass
|
34
|
+
(key ? "#{prefix}#{key} " : '') + obj.inspect
|
35
|
+
when NilClass
|
36
|
+
key ? "#{prefix}#{key}" : nil
|
37
|
+
when Regexp
|
38
|
+
(key ? "#{prefix}#{key} " : '') + obj.to_s
|
39
|
+
else
|
40
|
+
(key ? "#{prefix}#{key} " : '') + (/["#]/.match?(obj) ? obj.to_s.to_json : obj.to_s)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,340 @@
|
|
1
|
+
describe Flueconf do
|
2
|
+
it 'can handle primitive types' do
|
3
|
+
fluent = Flueconf.build do
|
4
|
+
it_is_integer 1
|
5
|
+
it_is_negtive_integer -1
|
6
|
+
it_is_float 1.23
|
7
|
+
it_is_negtive_float -1.23
|
8
|
+
it_is_string 'foo'
|
9
|
+
it_is_special_string '#{Socket.gethostname}'
|
10
|
+
it_is_null nil
|
11
|
+
it_is_true true
|
12
|
+
it_is_false false
|
13
|
+
it_is_regexp /^.*$/
|
14
|
+
it_is_array [1, -2, 3.3, -4.4, 'bar', nil, true, false]
|
15
|
+
it_is_empty_array []
|
16
|
+
it_is_hash({ foo: 123, bar: 'aaa', null: nil })
|
17
|
+
it_is_empty_hash({})
|
18
|
+
end.to_fluent
|
19
|
+
|
20
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
21
|
+
it_is_integer 1
|
22
|
+
it_is_negtive_integer -1
|
23
|
+
it_is_float 1.23
|
24
|
+
it_is_negtive_float -1.23
|
25
|
+
it_is_string foo
|
26
|
+
it_is_special_string "#{Socket.gethostname}"
|
27
|
+
it_is_null
|
28
|
+
it_is_true true
|
29
|
+
it_is_false false
|
30
|
+
it_is_regexp (?-mix:^.*$)
|
31
|
+
it_is_array 1,-2,3.3,-4.4,bar,true,false
|
32
|
+
it_is_empty_array
|
33
|
+
it_is_hash foo:123,bar:aaa
|
34
|
+
it_is_empty_hash
|
35
|
+
EOF
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'can handle array object' do
|
39
|
+
fluent = Flueconf.build do
|
40
|
+
it_is_array_object do
|
41
|
+
foo 'bar'
|
42
|
+
end
|
43
|
+
end.to_fluent
|
44
|
+
|
45
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
46
|
+
<it_is_array_object>
|
47
|
+
foo bar
|
48
|
+
</it_is_array_object>
|
49
|
+
EOF
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'can handle empty array object' do
|
53
|
+
fluent = Flueconf.build do
|
54
|
+
it_is_array_object do
|
55
|
+
end
|
56
|
+
end.to_fluent
|
57
|
+
|
58
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
59
|
+
<it_is_array_object>
|
60
|
+
</it_is_array_object>
|
61
|
+
EOF
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'can handle object' do
|
65
|
+
fluent = Flueconf.build do
|
66
|
+
it_is_object 'obj' do
|
67
|
+
foo 'bar'
|
68
|
+
end
|
69
|
+
end.to_fluent
|
70
|
+
|
71
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
72
|
+
<it_is_object obj>
|
73
|
+
foo bar
|
74
|
+
</it_is_object>
|
75
|
+
EOF
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'can handle empty object' do
|
79
|
+
fluent = Flueconf.build do
|
80
|
+
it_is_object 'obj' do
|
81
|
+
end
|
82
|
+
end.to_fluent
|
83
|
+
|
84
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
85
|
+
<it_is_object obj>
|
86
|
+
</it_is_object>
|
87
|
+
EOF
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'can handle object with multiple keys' do
|
91
|
+
fluent = Flueconf.build do
|
92
|
+
it_is_object 'o', 'b', 'j' do
|
93
|
+
foo 'bar'
|
94
|
+
end
|
95
|
+
end.to_fluent
|
96
|
+
|
97
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
98
|
+
<it_is_object o b j>
|
99
|
+
foo bar
|
100
|
+
</it_is_object>
|
101
|
+
EOF
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'can handle nested data types' do
|
105
|
+
fluent = Flueconf.build do
|
106
|
+
foo 'bar'
|
107
|
+
obj 'nested', 'obj' do
|
108
|
+
obj 'obj', 'in', 'obj' do
|
109
|
+
float 3.14
|
110
|
+
arr do
|
111
|
+
int 123
|
112
|
+
end
|
113
|
+
arr do
|
114
|
+
bool true
|
115
|
+
arr_in_arr do
|
116
|
+
bool false
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end.to_fluent
|
122
|
+
|
123
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
124
|
+
foo bar
|
125
|
+
<obj nested obj>
|
126
|
+
<obj obj in obj>
|
127
|
+
float 3.14
|
128
|
+
<arr>
|
129
|
+
int 123
|
130
|
+
</arr>
|
131
|
+
<arr>
|
132
|
+
bool true
|
133
|
+
<arr_in_arr>
|
134
|
+
bool false
|
135
|
+
</arr_in_arr>
|
136
|
+
</arr>
|
137
|
+
</obj>
|
138
|
+
</obj>
|
139
|
+
EOF
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'can handle multiple builds' do
|
143
|
+
builder = Flueconf.build do
|
144
|
+
obj do
|
145
|
+
first 1
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
fluent = builder.build do
|
150
|
+
second 2
|
151
|
+
end.to_fluent
|
152
|
+
|
153
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
154
|
+
<obj>
|
155
|
+
first 1
|
156
|
+
</obj>
|
157
|
+
second 2
|
158
|
+
EOF
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'can serialize with different indent' do
|
162
|
+
fluent = Flueconf.build do
|
163
|
+
foo 'bar'
|
164
|
+
obj 'nested', 'obj' do
|
165
|
+
obj 'obj', 'in', 'obj' do
|
166
|
+
float 3.14
|
167
|
+
arr do
|
168
|
+
int 123
|
169
|
+
end
|
170
|
+
arr do
|
171
|
+
bool true
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end.to_fluent(indent: 4)
|
176
|
+
|
177
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
178
|
+
foo bar
|
179
|
+
<obj nested obj>
|
180
|
+
<obj obj in obj>
|
181
|
+
float 3.14
|
182
|
+
<arr>
|
183
|
+
int 123
|
184
|
+
</arr>
|
185
|
+
<arr>
|
186
|
+
bool true
|
187
|
+
</arr>
|
188
|
+
</obj>
|
189
|
+
</obj>
|
190
|
+
EOF
|
191
|
+
end
|
192
|
+
|
193
|
+
it 'can handle method in different context' do
|
194
|
+
def bar
|
195
|
+
'barbar'
|
196
|
+
end
|
197
|
+
|
198
|
+
fluent = Flueconf.build do
|
199
|
+
foo bar
|
200
|
+
end.to_fluent
|
201
|
+
|
202
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
203
|
+
foo barbar
|
204
|
+
EOF
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'can handle predefined types' do
|
208
|
+
fluent = Flueconf.build do
|
209
|
+
system do
|
210
|
+
dir_permission '0755'
|
211
|
+
end
|
212
|
+
source do
|
213
|
+
type 'forward'
|
214
|
+
id 'in_forward'
|
215
|
+
label '@outside'
|
216
|
+
port 24224
|
217
|
+
end
|
218
|
+
source do
|
219
|
+
type 'tail'
|
220
|
+
id 'in_tail_httpd_access'
|
221
|
+
path '/var/log/httpd-access.log'
|
222
|
+
pos_file '/var/log/td-agent/httpd-access.log.pos'
|
223
|
+
tag 'apache.access'
|
224
|
+
parse do
|
225
|
+
type 'apache2'
|
226
|
+
end
|
227
|
+
end
|
228
|
+
filter 'fluent.**' do
|
229
|
+
type 'record_transformer'
|
230
|
+
record do
|
231
|
+
level '${tag_parts[1]}'
|
232
|
+
end
|
233
|
+
end
|
234
|
+
filter '**' do
|
235
|
+
type 'record_transformer'
|
236
|
+
record do
|
237
|
+
hostname '#{Socket.gethostname}'
|
238
|
+
end
|
239
|
+
end
|
240
|
+
match 'fluent.**' do
|
241
|
+
type 'rewrite_tag_filter'
|
242
|
+
rule do
|
243
|
+
key 'message'
|
244
|
+
pattern /.*/
|
245
|
+
tag 'fluent'
|
246
|
+
end
|
247
|
+
end
|
248
|
+
match '**' do
|
249
|
+
type 'forward'
|
250
|
+
server do
|
251
|
+
host '192.0.2.1'
|
252
|
+
weight 100
|
253
|
+
end
|
254
|
+
server do
|
255
|
+
host '192.0.2.2'
|
256
|
+
weight 50
|
257
|
+
end
|
258
|
+
end
|
259
|
+
label '@outside' do
|
260
|
+
match '**' do
|
261
|
+
type 'forward'
|
262
|
+
server do
|
263
|
+
host '192.0.2.1'
|
264
|
+
weight 100
|
265
|
+
end
|
266
|
+
server do
|
267
|
+
host '192.0.2.2'
|
268
|
+
weight 50
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end.to_fluent
|
273
|
+
|
274
|
+
expect(fluent).to eq <<~'EOF'.chomp
|
275
|
+
<system>
|
276
|
+
dir_permission 0755
|
277
|
+
</system>
|
278
|
+
<source>
|
279
|
+
@type forward
|
280
|
+
@id in_forward
|
281
|
+
@label @outside
|
282
|
+
port 24224
|
283
|
+
</source>
|
284
|
+
<source>
|
285
|
+
@type tail
|
286
|
+
@id in_tail_httpd_access
|
287
|
+
path /var/log/httpd-access.log
|
288
|
+
pos_file /var/log/td-agent/httpd-access.log.pos
|
289
|
+
tag apache.access
|
290
|
+
<parse>
|
291
|
+
@type apache2
|
292
|
+
</parse>
|
293
|
+
</source>
|
294
|
+
<filter fluent.**>
|
295
|
+
@type record_transformer
|
296
|
+
<record>
|
297
|
+
level ${tag_parts[1]}
|
298
|
+
</record>
|
299
|
+
</filter>
|
300
|
+
<filter **>
|
301
|
+
@type record_transformer
|
302
|
+
<record>
|
303
|
+
hostname "#{Socket.gethostname}"
|
304
|
+
</record>
|
305
|
+
</filter>
|
306
|
+
<match fluent.**>
|
307
|
+
@type rewrite_tag_filter
|
308
|
+
<rule>
|
309
|
+
key message
|
310
|
+
pattern (?-mix:.*)
|
311
|
+
tag fluent
|
312
|
+
</rule>
|
313
|
+
</match>
|
314
|
+
<match **>
|
315
|
+
@type forward
|
316
|
+
<server>
|
317
|
+
host 192.0.2.1
|
318
|
+
weight 100
|
319
|
+
</server>
|
320
|
+
<server>
|
321
|
+
host 192.0.2.2
|
322
|
+
weight 50
|
323
|
+
</server>
|
324
|
+
</match>
|
325
|
+
<label @outside>
|
326
|
+
<match **>
|
327
|
+
@type forward
|
328
|
+
<server>
|
329
|
+
host 192.0.2.1
|
330
|
+
weight 100
|
331
|
+
</server>
|
332
|
+
<server>
|
333
|
+
host 192.0.2.2
|
334
|
+
weight 50
|
335
|
+
</server>
|
336
|
+
</match>
|
337
|
+
</label>
|
338
|
+
EOF
|
339
|
+
end
|
340
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'flueconf'
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flueconf
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Rianol Jou
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-08-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
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: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '12.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '12.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.8'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.8'
|
55
|
+
description: " Config fluentd in ruby. And featuring all programming features (variables,
|
56
|
+
iterators, functions, regexp, etc) in ruby.\n"
|
57
|
+
email:
|
58
|
+
- rianol.jou@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- lib/flueconf.rb
|
64
|
+
- lib/flueconf/builder.rb
|
65
|
+
- lib/flueconf/serializer.rb
|
66
|
+
- lib/flueconf/version.rb
|
67
|
+
- spec/flueconf_spec.rb
|
68
|
+
- spec/spec_helper.rb
|
69
|
+
homepage: https://github.com/RiANOl/flueconf
|
70
|
+
licenses:
|
71
|
+
- MIT
|
72
|
+
metadata: {}
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ">="
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '2.4'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
requirements: []
|
88
|
+
rubygems_version: 3.0.3
|
89
|
+
signing_key:
|
90
|
+
specification_version: 4
|
91
|
+
summary: Config fluentd in ruby.
|
92
|
+
test_files:
|
93
|
+
- spec/flueconf_spec.rb
|
94
|
+
- spec/spec_helper.rb
|