fluent-mixin-config-placeholders 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +28 -4
- data/fluent-mixin-config-placeholders.gemspec +1 -1
- data/lib/fluent/mixin/config_placeholders.rb +40 -16
- data/test/mixin/test_config_placeholders.rb +72 -8
- data/test/plugin.rb +11 -0
- metadata +2 -2
data/README.md
CHANGED
@@ -2,13 +2,15 @@
|
|
2
2
|
|
3
3
|
Fluent::Mixin::ConfigPlaceHolders provide some placeholders to fluentd plugins that includes this mix-in. Placeholders below are expanded in 'super' of including plugin's #configure method.
|
4
4
|
|
5
|
+
Placeholder patterns are `${..}` and `__XXX__`. With optional setting in plugin code, `%{...}` is available.
|
6
|
+
|
5
7
|
Available placeholders are:
|
6
8
|
|
7
|
-
* hostname (${hostname} or \_\_HOSTNAME\_\_)
|
9
|
+
* hostname (${hostname}, %{hostname} or \_\_HOSTNAME\_\_)
|
8
10
|
* you can specify hostname string explicitly on 'hostname' parameter
|
9
|
-
* random uuid (${uuid}, ${uuid:random}, \_\_UUID\_\_ or \_\_UUID\_RANDOM\_\_)
|
10
|
-
* hostname string based uuid (${uuid:hostname} or \_\_UUID\_HOSTNAME\_\_)
|
11
|
-
* timestamp based uuid (${uuid:timestamp} or \_\_UUID\_TIMESTAMP\_\_)
|
11
|
+
* random uuid (${uuid}, ${uuid:random}, %{uuid}, %{uuid:random}, \_\_UUID\_\_ or \_\_UUID\_RANDOM\_\_)
|
12
|
+
* hostname string based uuid (${uuid:hostname}, %{uuid:hostname} or \_\_UUID\_HOSTNAME\_\_)
|
13
|
+
* timestamp based uuid (${uuid:timestamp} %{uuid:timestamp} or \_\_UUID\_TIMESTAMP\_\_)
|
12
14
|
|
13
15
|
## Usage
|
14
16
|
|
@@ -32,9 +34,31 @@ In plugin (both of input and output), just include mixin.
|
|
32
34
|
|
33
35
|
You can use this feature for tags for each fluentd node, paths for remote storage services like /root/${hostname}/access_log or non-race-condition paths like /files/${uuid:random}.
|
34
36
|
|
37
|
+
### Plugin setting
|
38
|
+
|
39
|
+
Plugin can determine which placeholders are enabled in their configurations, like this:
|
40
|
+
|
41
|
+
class FooInput < Fluent::Input
|
42
|
+
# ....
|
43
|
+
|
44
|
+
# instance method #placeholders should return array of symbols
|
45
|
+
|
46
|
+
def placeholders
|
47
|
+
[:dollar, :percentage, :underscore]
|
48
|
+
end
|
49
|
+
|
50
|
+
# default is [:dollar, :underscore]
|
51
|
+
|
52
|
+
include Fluent::Mixin::ConfigPlaceholders
|
53
|
+
|
54
|
+
# ....
|
55
|
+
end
|
56
|
+
|
35
57
|
## AUTHORS
|
36
58
|
|
37
59
|
* TAGOMORI Satoshi <tagomoris@gmail.com>
|
60
|
+
* Contributors
|
61
|
+
* @ijin
|
38
62
|
|
39
63
|
## LICENSE
|
40
64
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
Gem::Specification.new do |gem|
|
3
3
|
gem.name = "fluent-mixin-config-placeholders"
|
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{to add various placeholders for plugin configurations}
|
@@ -6,17 +6,19 @@ module Fluent
|
|
6
6
|
module ConfigPlaceholders
|
7
7
|
attr_accessor :hostname
|
8
8
|
|
9
|
-
|
9
|
+
PLACEHOLDERS_DEFAULT = [ :dollar, :underscore ] # and :percent
|
10
10
|
|
11
|
-
# ${
|
11
|
+
# ${hostname}, %{hostname}, __HOSTNAME__
|
12
|
+
|
13
|
+
# ${uuid} or ${uuid:random} , %{uuid} or %{uuid:random} __UUID__ or __UUID_RANDOM__
|
12
14
|
# UUIDTools::UUID.random_create
|
13
15
|
# => #<UUID:0x19013a UUID:984265dc-4200-4f02-ae70-fe4f48964159>
|
14
16
|
|
15
|
-
# ${uuid:hostname} , __UUID_HOSTNAME__
|
17
|
+
# ${uuid:hostname} , %{uuid:hostname} , __UUID_HOSTNAME__
|
16
18
|
# UUIDTools::UUID.sha1_create(UUIDTools::UUID_DNS_NAMESPACE, "www.widgets.com")
|
17
19
|
# => #<UUID:0x2a0116 UUID:21f7f8de-8051-5b89-8680-0195ef798b6a>
|
18
20
|
|
19
|
-
# ${uuid:timestamp} , __UUID_TIMESTAMP__
|
21
|
+
# ${uuid:timestamp} , %{uuid:timestamp} , __UUID_TIMESTAMP__
|
20
22
|
# UUIDTools::UUID.timestamp_create
|
21
23
|
# => #<UUID:0x2adfdc UUID:64a5189c-25b3-11da-a97b-00c04fd430c8>
|
22
24
|
|
@@ -40,18 +42,40 @@ module Fluent
|
|
40
42
|
# Element#has_key? inserts key name into 'used' list, so we should escape that method...
|
41
43
|
hostname = conf.keys.include?('hostname') ? conf['hostname'] : `hostname`.chomp
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
45
|
+
placeholders = self.respond_to?(:placeholders) ? self.placeholders : PLACEHOLDERS_DEFAULT
|
46
|
+
|
47
|
+
mapping = {}
|
48
|
+
|
49
|
+
placeholders.each do |p|
|
50
|
+
case p
|
51
|
+
when :dollar
|
52
|
+
mapping.update({
|
53
|
+
'${hostname}' => lambda{ hostname },
|
54
|
+
'${uuid}' => lambda{ uuid_random() },
|
55
|
+
'${uuid:random}' => lambda{ uuid_random() },
|
56
|
+
'${uuid:hostname}' => lambda{ uuid_hostname(hostname) },
|
57
|
+
'${uuid:timestamp}' => lambda{ uuid_timestamp() },
|
58
|
+
})
|
59
|
+
when :percent
|
60
|
+
mapping.update({
|
61
|
+
'%{hostname}' => lambda{ hostname },
|
62
|
+
'%{uuid}' => lambda{ uuid_random() },
|
63
|
+
'%{uuid:random}' => lambda{ uuid_random() },
|
64
|
+
'%{uuid:hostname}' => lambda{ uuid_hostname(hostname) },
|
65
|
+
'%{uuid:timestamp}' => lambda{ uuid_timestamp() },
|
66
|
+
})
|
67
|
+
when :underscore
|
68
|
+
mapping.update({
|
69
|
+
'__HOSTNAME__' => lambda{ hostname },
|
70
|
+
'__UUID__' => lambda{ uuid_random() },
|
71
|
+
'__UUID_RANDOM__' => lambda{ uuid_random() },
|
72
|
+
'__UUID_HOSTNAME__' => lambda{ uuid_hostname(hostname) },
|
73
|
+
'__UUID_TIMESTAMP__' => lambda{ uuid_timestamp() },
|
74
|
+
})
|
75
|
+
else
|
76
|
+
raise ArgumentError, "unknown placeholder format: #{p}"
|
77
|
+
end
|
78
|
+
end
|
55
79
|
|
56
80
|
def check_element(map,c)
|
57
81
|
c.arg = replace(map, c.arg)
|
@@ -30,13 +30,24 @@ path POSPOSPOS ${hostname} MOGEMOGE
|
|
30
30
|
assert_equal [], p.conf.used
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
33
|
+
def test_default
|
34
34
|
conf = %[
|
35
|
+
hostname testing
|
36
|
+
tag ${hostname}.%{hostname}.__HOSTNAME__
|
37
|
+
path /${hostname}/%{hostname}/__HOSTNAME__.log
|
38
|
+
]
|
39
|
+
p = Fluent::Test::InputTestDriver.new(Fluent::ConfigPlaceholdersTestDefaultInput).configure(conf).instance
|
40
|
+
assert_equal 'testing.%{hostname}.testing', p.tag
|
41
|
+
assert_equal '/testing/%{hostname}/testing.log', p.path
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_hostname
|
45
|
+
conf1 = %[
|
35
46
|
hostname testing.local
|
36
47
|
tag out.${hostname}
|
37
48
|
path /path/to/file.__HOSTNAME__.txt
|
38
49
|
]
|
39
|
-
p1, p2, p3 = create_plugin_instances(
|
50
|
+
p1, p2, p3 = create_plugin_instances(conf1)
|
40
51
|
|
41
52
|
assert_equal 'out.${hostname}', p1.tag
|
42
53
|
assert_equal 'out.testing.local', p2.tag
|
@@ -45,6 +56,21 @@ path /path/to/file.__HOSTNAME__.txt
|
|
45
56
|
assert_equal '/path/to/file.__HOSTNAME__.txt', p1.path
|
46
57
|
assert_equal '/path/to/file.testing.local.txt', p2.path
|
47
58
|
assert_equal '/PATH/TO/FILE.TESTING.LOCAL.TXT', p3.path
|
59
|
+
|
60
|
+
conf2 = %[
|
61
|
+
hostname testing.local
|
62
|
+
tag out.%{hostname}
|
63
|
+
path /path/to/file.%{hostname}.txt
|
64
|
+
]
|
65
|
+
p1, p2, p3 = create_plugin_instances(conf2)
|
66
|
+
|
67
|
+
assert_equal 'out.%{hostname}', p1.tag
|
68
|
+
assert_equal 'out.testing.local', p2.tag
|
69
|
+
assert_equal 'out.testing.local', p3.tag
|
70
|
+
|
71
|
+
assert_equal '/path/to/file.%{hostname}.txt', p1.path
|
72
|
+
assert_equal '/path/to/file.testing.local.txt', p2.path
|
73
|
+
assert_equal '/PATH/TO/FILE.TESTING.LOCAL.TXT', p3.path
|
48
74
|
end
|
49
75
|
|
50
76
|
PATH_CHECK_REGEXP = Regexp.compile('^/path/to/file\.[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}.txt$')
|
@@ -82,37 +108,67 @@ path /path/to/file.__UUID__.txt
|
|
82
108
|
p1, p2, p3 = create_plugin_instances(conf4)
|
83
109
|
assert_match PATH_CHECK_REGEXP, p2.path
|
84
110
|
assert_match PATH_CHECK_REGEXP2, p3.path
|
111
|
+
|
112
|
+
conf5 = %[
|
113
|
+
tag test.out
|
114
|
+
path /path/to/file.%{uuid}.txt
|
115
|
+
]
|
116
|
+
p1, p2, p3 = create_plugin_instances(conf5)
|
117
|
+
assert_match PATH_CHECK_REGEXP, p2.path
|
118
|
+
assert_match PATH_CHECK_REGEXP2, p3.path
|
119
|
+
|
120
|
+
conf6 = %[
|
121
|
+
tag test.out
|
122
|
+
path /path/to/file.%{uuid:random}.txt
|
123
|
+
]
|
124
|
+
p1, p2, p3 = create_plugin_instances(conf6)
|
125
|
+
assert_match PATH_CHECK_REGEXP, p2.path
|
126
|
+
assert_match PATH_CHECK_REGEXP2, p3.path
|
85
127
|
end
|
86
128
|
|
87
129
|
PATH_CHECK_H_REGEXP = Regexp.compile('^/path/to/file\.[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}.log$')
|
88
130
|
PATH_CHECK_H_REGEXP2 = Regexp.compile('^/PATH/TO/FILE\.[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}.LOG$')
|
89
131
|
|
132
|
+
|
90
133
|
def test_uuid_hostname
|
91
134
|
conf1 = %[
|
135
|
+
hostname testing.local
|
92
136
|
tag test.out
|
93
137
|
path /path/to/file.${uuid:hostname}.log
|
94
138
|
]
|
95
139
|
p1, p2, p3 = create_plugin_instances(conf1)
|
96
140
|
assert_match PATH_CHECK_H_REGEXP, p2.path
|
97
|
-
assert_equal '/path/to/file.
|
141
|
+
assert_equal '/path/to/file.acc701f6-9be5-578b-9580-85ec8a505600.log', p2.path
|
98
142
|
assert_match PATH_CHECK_H_REGEXP2, p3.path
|
99
|
-
assert_equal '/PATH/TO/FILE.
|
143
|
+
assert_equal '/PATH/TO/FILE.ACC701F6-9BE5-578B-9580-85EC8A505600.LOG', p3.path
|
100
144
|
|
101
145
|
conf2 = %[
|
146
|
+
hostname testing.local
|
102
147
|
tag test.out
|
103
148
|
path /path/to/file.__UUID_HOSTNAME__.log
|
104
149
|
]
|
105
150
|
p1, p2, p3 = create_plugin_instances(conf2)
|
106
151
|
assert_match PATH_CHECK_H_REGEXP, p2.path
|
107
|
-
assert_equal '/path/to/file.
|
152
|
+
assert_equal '/path/to/file.acc701f6-9be5-578b-9580-85ec8a505600.log', p2.path
|
153
|
+
assert_match PATH_CHECK_H_REGEXP2, p3.path
|
154
|
+
assert_equal '/PATH/TO/FILE.ACC701F6-9BE5-578B-9580-85EC8A505600.LOG', p3.path
|
155
|
+
|
156
|
+
conf3 = %[
|
157
|
+
hostname testing.local
|
158
|
+
tag test.out
|
159
|
+
path /path/to/file.%{uuid:hostname}.log
|
160
|
+
]
|
161
|
+
p1, p2, p3 = create_plugin_instances(conf3)
|
162
|
+
assert_match PATH_CHECK_H_REGEXP, p2.path
|
163
|
+
assert_equal '/path/to/file.acc701f6-9be5-578b-9580-85ec8a505600.log', p2.path
|
108
164
|
assert_match PATH_CHECK_H_REGEXP2, p3.path
|
109
|
-
assert_equal '/PATH/TO/FILE.
|
165
|
+
assert_equal '/PATH/TO/FILE.ACC701F6-9BE5-578B-9580-85EC8A505600.LOG', p3.path
|
110
166
|
end
|
111
167
|
|
112
168
|
PATH_CHECK_T_REGEXP = Regexp.compile('^/path/to/file\.[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}.out$')
|
113
169
|
PATH_CHECK_T_REGEXP2 = Regexp.compile('^/PATH/TO/FILE\.[0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12}.OUT$')
|
114
170
|
|
115
|
-
def
|
171
|
+
def test_uuid_timestamp
|
116
172
|
conf1 = %[
|
117
173
|
tag test.out
|
118
174
|
path /path/to/file.${uuid:timestamp}.out
|
@@ -123,11 +179,19 @@ path /path/to/file.${uuid:timestamp}.out
|
|
123
179
|
|
124
180
|
conf2 = %[
|
125
181
|
tag test.out
|
126
|
-
path /path/to/file.
|
182
|
+
path /path/to/file.__UUID_TIMESTAMP__.out
|
127
183
|
]
|
128
184
|
p1, p2, p3 = create_plugin_instances(conf2)
|
129
185
|
assert_match PATH_CHECK_T_REGEXP, p2.path
|
130
186
|
assert_match PATH_CHECK_T_REGEXP2, p3.path
|
187
|
+
|
188
|
+
conf3 = %[
|
189
|
+
tag test.out
|
190
|
+
path /path/to/file.%{uuid:timestamp}.out
|
191
|
+
]
|
192
|
+
p1, p2, p3 = create_plugin_instances(conf3)
|
193
|
+
assert_match PATH_CHECK_T_REGEXP, p2.path
|
194
|
+
assert_match PATH_CHECK_T_REGEXP2, p3.path
|
131
195
|
end
|
132
196
|
|
133
197
|
def test_nested
|
data/test/plugin.rb
CHANGED
@@ -9,6 +9,15 @@ class Fluent::ConfigPlaceholdersTestXInput < Fluent::Input
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
+
class Fluent::ConfigPlaceholdersTestDefaultInput < Fluent::Input
|
13
|
+
Fluent::Plugin.register_input('config_placeholder_test_1', self)
|
14
|
+
|
15
|
+
config_param :tag, :string
|
16
|
+
config_param :path, :string
|
17
|
+
|
18
|
+
include Fluent::Mixin::ConfigPlaceholders
|
19
|
+
end
|
20
|
+
|
12
21
|
class Fluent::ConfigPlaceholdersTest0Input < Fluent::Input
|
13
22
|
Fluent::Plugin.register_input('config_placeholder_test_0', self)
|
14
23
|
|
@@ -30,6 +39,7 @@ class Fluent::ConfigPlaceholdersTest1Input < Fluent::Input
|
|
30
39
|
config_param :tag, :string
|
31
40
|
config_param :path, :string
|
32
41
|
|
42
|
+
def placeholders; [:dollar, :percent, :underscore]; end
|
33
43
|
include Fluent::Mixin::ConfigPlaceholders
|
34
44
|
end
|
35
45
|
|
@@ -43,6 +53,7 @@ class Fluent::ConfigPlaceholdersTest2Input < Fluent::Input
|
|
43
53
|
|
44
54
|
attr_accessor :conf
|
45
55
|
|
56
|
+
def placeholders; [:dollar, :percent, :underscore]; end
|
46
57
|
def configure(conf)
|
47
58
|
super
|
48
59
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-mixin-config-placeholders
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fluentd
|