fluent-plugin-forest 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +51 -1
- data/fluent-plugin-forest.gemspec +1 -1
- data/lib/fluent/plugin/out_forest.rb +28 -7
- data/test/plugin/test_out_forest.rb +155 -6
- data/test/plugin/test_out_forest_test.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8de96a623bfa6608e043f68ca1dbd0549ed4d315
|
4
|
+
data.tar.gz: e34249c2332e2520d75aba897b852045db5ce983
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64f32283a2f2cde11e07ce690ed810b492990ee9a48b7a18e91bb643b31140dec89991d9f924998ce0152505df703466adaf01d6bc8f2562c679ff20f7d4aa86
|
7
|
+
data.tar.gz: 35aa6d7e0c3e8dd8df00387569d60a6a583a66511fb0bdaa9fea9d04bba75f9b2742450b39c367f9d0dab1d164083125e99a6144c49fa8cf6165265a15ef2e45
|
data/README.md
CHANGED
@@ -98,9 +98,59 @@ If you want to place logs /var/archive for `service.search.**` as filename with
|
|
98
98
|
</case>
|
99
99
|
</match>
|
100
100
|
|
101
|
+
Version 0.2.0 or later, subsections adding/overwriting are supported. About the case below, three `<store>` subsections are defined for `search.**` pattern.
|
102
|
+
|
103
|
+
<match service.*>
|
104
|
+
type forest
|
105
|
+
subtype copy
|
106
|
+
<template>
|
107
|
+
<store>
|
108
|
+
type file
|
109
|
+
path /path/to/copy1
|
110
|
+
</store>
|
111
|
+
<store>
|
112
|
+
type file
|
113
|
+
path /path/to/copy2
|
114
|
+
</store>
|
115
|
+
</template>
|
116
|
+
<case search.**>
|
117
|
+
<store>
|
118
|
+
type file
|
119
|
+
path /path/to/copy3
|
120
|
+
</store>
|
121
|
+
</case>
|
122
|
+
</match>
|
123
|
+
|
124
|
+
Subsections with same arguments will be overwritten. See this example:
|
125
|
+
|
126
|
+
<match service.*>
|
127
|
+
type forest
|
128
|
+
subtype route
|
129
|
+
<template>
|
130
|
+
<route {search,admin}.a>
|
131
|
+
add_prefix first
|
132
|
+
</route>
|
133
|
+
<route {search,admin}.b>
|
134
|
+
add_prefix second
|
135
|
+
</route>
|
136
|
+
<route {search,admin}.c>
|
137
|
+
add_prefix third
|
138
|
+
</route>
|
139
|
+
<route {search,admin}.*>
|
140
|
+
add_prefix extra
|
141
|
+
</route>
|
142
|
+
</template>
|
143
|
+
<case admin.*>
|
144
|
+
<route {search,admin}.*>
|
145
|
+
add_prefix other
|
146
|
+
</route>
|
147
|
+
</case>
|
148
|
+
</match>
|
149
|
+
|
150
|
+
In this case, `<route {search,admin}.*>` subsection will be overwritten to add prefix 'other' for tag `service.admin.*`.
|
151
|
+
|
101
152
|
## TODO
|
102
153
|
|
103
|
-
* consider what to do next
|
104
154
|
* patches welcome!
|
105
155
|
|
106
156
|
## Copyright
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
Gem::Specification.new do |gem|
|
3
3
|
gem.name = "fluent-plugin-forest"
|
4
|
-
gem.version = "0.
|
4
|
+
gem.version = "0.2.0"
|
5
5
|
gem.authors = ["TAGOMORI Satoshi"]
|
6
6
|
gem.email = ["tagomoris@gmail.com"]
|
7
7
|
gem.description = %q{create sub-plugin dynamically per tags, with template configuration and parameters}
|
@@ -28,10 +28,9 @@ class Fluent::ForestOutput < Fluent::MultiOutput
|
|
28
28
|
@cases = []
|
29
29
|
|
30
30
|
conf.elements.each do |element|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
31
|
+
# read and throw away to supress unread configuration warning
|
32
|
+
touch_recursive(element)
|
33
|
+
|
35
34
|
case element.name
|
36
35
|
when 'template'
|
37
36
|
@template = element
|
@@ -44,6 +43,15 @@ class Fluent::ForestOutput < Fluent::MultiOutput
|
|
44
43
|
self
|
45
44
|
end
|
46
45
|
|
46
|
+
def touch_recursive(e)
|
47
|
+
e.keys.each do |k|
|
48
|
+
e[k]
|
49
|
+
end
|
50
|
+
e.elements.each do |child|
|
51
|
+
touch_recursive(child)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
47
55
|
def shutdown
|
48
56
|
super
|
49
57
|
@mapping.values.each do |output|
|
@@ -51,12 +59,15 @@ class Fluent::ForestOutput < Fluent::MultiOutput
|
|
51
59
|
end
|
52
60
|
end
|
53
61
|
|
54
|
-
def parameter(tag, e)
|
62
|
+
def parameter(tag, e, name = 'instance', arg = '')
|
55
63
|
pairs = {}
|
56
64
|
e.each do |k,v|
|
57
65
|
pairs[k] = v.gsub('__TAG__', tag).gsub('${tag}', tag).gsub('__HOSTNAME__', @hostname).gsub('${hostname}', @hostname)
|
58
66
|
end
|
59
|
-
|
67
|
+
elements = e.elements.map do |child|
|
68
|
+
parameter(tag, child, child.name, child.arg)
|
69
|
+
end
|
70
|
+
Fluent::Config::Element.new(name, arg, pairs, elements)
|
60
71
|
end
|
61
72
|
|
62
73
|
def spec(tag)
|
@@ -64,7 +75,17 @@ class Fluent::ForestOutput < Fluent::MultiOutput
|
|
64
75
|
conf = parameter(tag, @template) + conf if @template # a + b -> b.merge(a) (see: fluentd/lib/fluent/config.rb)
|
65
76
|
@cases.each do |m,e|
|
66
77
|
if m.match(tag)
|
67
|
-
|
78
|
+
matched_case = parameter(tag, e)
|
79
|
+
|
80
|
+
matched_case.elements.each { |case_child|
|
81
|
+
unless case_child.arg.empty?
|
82
|
+
conf.elements.delete_if { |conf_child|
|
83
|
+
conf_child.name == case_child.name && conf_child.arg == case_child.arg
|
84
|
+
}
|
85
|
+
end
|
86
|
+
}
|
87
|
+
|
88
|
+
conf = matched_case + conf
|
68
89
|
break
|
69
90
|
end
|
70
91
|
end
|
@@ -12,7 +12,7 @@ remove_prefix test
|
|
12
12
|
<template>
|
13
13
|
key_name f
|
14
14
|
suffix !
|
15
|
-
tag out.__TAG__
|
15
|
+
tag out.__TAG__
|
16
16
|
</template>
|
17
17
|
<case foo.bar>
|
18
18
|
prefix p1:
|
@@ -62,7 +62,7 @@ subtype hoge
|
|
62
62
|
assert_equal 'yyyyyy.xx', conf['keyy']
|
63
63
|
assert_equal 'z1', conf['keyz']
|
64
64
|
assert_equal 'b', conf['alt_key']
|
65
|
-
|
65
|
+
|
66
66
|
conf = d.instance.spec('yy')
|
67
67
|
assert_equal 'xxxxxx', conf['keyx']
|
68
68
|
assert_equal 'yyyyyy.yy', conf['keyy']
|
@@ -82,6 +82,155 @@ subtype hoge
|
|
82
82
|
assert_equal 'd.zz', conf['alt_key']
|
83
83
|
end
|
84
84
|
|
85
|
+
NESTED_CONF = %[
|
86
|
+
subtype hoge
|
87
|
+
<template>
|
88
|
+
keyx xxxxxx
|
89
|
+
keyy yyyyyy.__TAG__
|
90
|
+
alt_key a
|
91
|
+
<tagx>
|
92
|
+
key xxx
|
93
|
+
</tagx>
|
94
|
+
<tagy>
|
95
|
+
key yyy.__TAG__
|
96
|
+
</tagy>
|
97
|
+
<tag_with attr.foo>
|
98
|
+
key bar
|
99
|
+
</tag_with>
|
100
|
+
<tag_with attr.foo>
|
101
|
+
key dup
|
102
|
+
</tag_with>
|
103
|
+
<tag_with attr.foo>
|
104
|
+
key dupdup
|
105
|
+
</tag_with>
|
106
|
+
</template>
|
107
|
+
<case xx>
|
108
|
+
keyz z1
|
109
|
+
alt_key b
|
110
|
+
</case>
|
111
|
+
<case yy.**>
|
112
|
+
keyz z2
|
113
|
+
alt_key c
|
114
|
+
<tagx>
|
115
|
+
key not_overwrite
|
116
|
+
</tagx>
|
117
|
+
<tag_with attr.foo>
|
118
|
+
key overwrite
|
119
|
+
</tag_with>
|
120
|
+
<tag_with attr.foo>
|
121
|
+
key overwrite_dup
|
122
|
+
</tag_with>
|
123
|
+
</case>
|
124
|
+
<case *>
|
125
|
+
keyz z3
|
126
|
+
alt_key d.__TAG__
|
127
|
+
<tagz>
|
128
|
+
<tagw>
|
129
|
+
key www
|
130
|
+
</tagw>
|
131
|
+
</tagz>
|
132
|
+
<tag_with attr.*>
|
133
|
+
key not_overwrite
|
134
|
+
</tag_with>
|
135
|
+
</case>
|
136
|
+
]
|
137
|
+
|
138
|
+
def test_spec_nested_overwrite_attributes_only
|
139
|
+
d = create_driver NESTED_CONF
|
140
|
+
conf = d.instance.spec('xx')
|
141
|
+
assert_equal 'xxxxxx', conf['keyx']
|
142
|
+
assert_equal 'yyyyyy.xx', conf['keyy']
|
143
|
+
assert_equal 'z1', conf['keyz']
|
144
|
+
assert_equal 'b', conf['alt_key']
|
145
|
+
|
146
|
+
assert_equal 5, conf.elements.size
|
147
|
+
|
148
|
+
assert_equal 'tagx', conf.elements[0].name
|
149
|
+
assert_equal 'xxx', conf.elements[0]['key']
|
150
|
+
|
151
|
+
assert_equal 'tagy', conf.elements[1].name
|
152
|
+
assert_equal 'yyy.xx', conf.elements[1]['key']
|
153
|
+
|
154
|
+
assert_equal 'tag_with', conf.elements[2].name
|
155
|
+
assert_equal 'attr.foo', conf.elements[2].arg
|
156
|
+
assert_equal 'bar', conf.elements[2]['key']
|
157
|
+
|
158
|
+
assert_equal 'tag_with', conf.elements[3].name
|
159
|
+
assert_equal 'attr.foo', conf.elements[3].arg
|
160
|
+
assert_equal 'dup', conf.elements[3]['key']
|
161
|
+
|
162
|
+
assert_equal 'tag_with', conf.elements[4].name
|
163
|
+
assert_equal 'attr.foo', conf.elements[4].arg
|
164
|
+
assert_equal 'dupdup', conf.elements[4]['key']
|
165
|
+
end
|
166
|
+
def test_spec_nested_overwrite_subsections_with_arg
|
167
|
+
d = create_driver NESTED_CONF
|
168
|
+
conf = d.instance.spec('yy')
|
169
|
+
|
170
|
+
assert_equal 'xxxxxx', conf['keyx']
|
171
|
+
assert_equal 'yyyyyy.yy', conf['keyy']
|
172
|
+
assert_equal 'z2', conf['keyz']
|
173
|
+
assert_equal 'c', conf['alt_key']
|
174
|
+
|
175
|
+
assert_equal 5, conf.elements.size
|
176
|
+
|
177
|
+
assert_equal 'tagx', conf.elements[0].name
|
178
|
+
assert_equal 'not_overwrite', conf.elements[0]['key']
|
179
|
+
|
180
|
+
assert_equal 'tag_with', conf.elements[1].name
|
181
|
+
assert_equal 'attr.foo', conf.elements[1].arg
|
182
|
+
assert_equal 'overwrite', conf.elements[1]['key']
|
183
|
+
|
184
|
+
assert_equal 'tag_with', conf.elements[2].name
|
185
|
+
assert_equal 'attr.foo', conf.elements[2].arg
|
186
|
+
assert_equal 'overwrite_dup', conf.elements[2]['key']
|
187
|
+
|
188
|
+
assert_equal 'tagx', conf.elements[3].name
|
189
|
+
assert_equal 'xxx', conf.elements[3]['key']
|
190
|
+
|
191
|
+
assert_equal 'tagy', conf.elements[4].name
|
192
|
+
assert_equal 'yyy.yy', conf.elements[4]['key']
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_spec_nested_subsections_added
|
196
|
+
d = create_driver NESTED_CONF
|
197
|
+
conf = d.instance.spec('zz')
|
198
|
+
|
199
|
+
assert_equal 'xxxxxx', conf['keyx']
|
200
|
+
assert_equal 'yyyyyy.zz', conf['keyy']
|
201
|
+
assert_equal 'z3', conf['keyz']
|
202
|
+
assert_equal 'd.zz', conf['alt_key']
|
203
|
+
|
204
|
+
assert_equal 7, conf.elements.size
|
205
|
+
|
206
|
+
assert_equal 'tagz', conf.elements[0].name
|
207
|
+
assert_equal 1, conf.elements[0].elements.size
|
208
|
+
assert_equal 'tagw', conf.elements[0].elements[0].name
|
209
|
+
assert_equal 'www', conf.elements[0].elements[0]['key']
|
210
|
+
|
211
|
+
assert_equal 'tag_with', conf.elements[1].name
|
212
|
+
assert_equal 'attr.*', conf.elements[1].arg
|
213
|
+
assert_equal 'not_overwrite', conf.elements[1]['key']
|
214
|
+
|
215
|
+
assert_equal 'tagx', conf.elements[2].name
|
216
|
+
assert_equal 'xxx', conf.elements[2]['key']
|
217
|
+
|
218
|
+
assert_equal 'tagy', conf.elements[3].name
|
219
|
+
assert_equal 'yyy.zz', conf.elements[3]['key']
|
220
|
+
|
221
|
+
assert_equal 'tag_with', conf.elements[4].name
|
222
|
+
assert_equal 'attr.foo', conf.elements[4].arg
|
223
|
+
assert_equal 'bar', conf.elements[4]['key']
|
224
|
+
|
225
|
+
assert_equal 'tag_with', conf.elements[5].name
|
226
|
+
assert_equal 'attr.foo', conf.elements[5].arg
|
227
|
+
assert_equal 'dup', conf.elements[5]['key']
|
228
|
+
|
229
|
+
assert_equal 'tag_with', conf.elements[6].name
|
230
|
+
assert_equal 'attr.foo', conf.elements[6].arg
|
231
|
+
assert_equal 'dupdup', conf.elements[6]['key']
|
232
|
+
end
|
233
|
+
|
85
234
|
def test_spec_hostname
|
86
235
|
d = create_driver %[
|
87
236
|
subtype hoge
|
@@ -109,7 +258,7 @@ hostname somehost.local
|
|
109
258
|
assert_equal 'yyyyyy.xx', conf['keyy']
|
110
259
|
assert_equal 'z1', conf['keyz']
|
111
260
|
assert_equal 'b', conf['alt_key']
|
112
|
-
|
261
|
+
|
113
262
|
conf = d.instance.spec('yy')
|
114
263
|
assert_equal 'xxxxxx.somehost.local', conf['keyx']
|
115
264
|
assert_equal 'yyyyyy.yy', conf['keyy']
|
@@ -156,7 +305,7 @@ subtype hoge
|
|
156
305
|
assert_equal 'yyyyyy.xx', conf['keyy']
|
157
306
|
assert_equal 'z1', conf['keyz']
|
158
307
|
assert_equal 'b', conf['alt_key']
|
159
|
-
|
308
|
+
|
160
309
|
conf = d.instance.spec('yy')
|
161
310
|
assert_equal 'xxxxxx.' + hostname, conf['keyx']
|
162
311
|
assert_equal 'yyyyyy.yy', conf['keyy']
|
@@ -189,7 +338,7 @@ remove_prefix test
|
|
189
338
|
<template>
|
190
339
|
key_name f
|
191
340
|
suffix !
|
192
|
-
tag __TAG__
|
341
|
+
tag __TAG__
|
193
342
|
</template>
|
194
343
|
<case foo.bar>
|
195
344
|
prefix p1:
|
@@ -229,7 +378,7 @@ remove_prefix test
|
|
229
378
|
assert_equal time, e[1]
|
230
379
|
assert_equal "p4:message 1!", e[2]['f']
|
231
380
|
assert_nil e[2]['not_started']
|
232
|
-
|
381
|
+
|
233
382
|
e = emits[1]
|
234
383
|
assert_equal 'out.second', e[0]
|
235
384
|
assert_equal time, e[1]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-forest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TAGOMORI Satoshi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
76
|
version: '0'
|
77
77
|
requirements: []
|
78
78
|
rubyforge_project:
|
79
|
-
rubygems_version: 2.0.
|
79
|
+
rubygems_version: 2.0.2
|
80
80
|
signing_key:
|
81
81
|
specification_version: 4
|
82
82
|
summary: plugin to create output plugin instances per tags dynamically
|
@@ -85,3 +85,4 @@ test_files:
|
|
85
85
|
- test/output/out_forest_test.rb
|
86
86
|
- test/plugin/test_out_forest.rb
|
87
87
|
- test/plugin/test_out_forest_test.rb
|
88
|
+
has_rdoc:
|