fluent-mixin-config-placeholders 0.1.0 → 0.2.0
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.
- 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
|