fluentd 1.8.0.rc3 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of fluentd might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/CHANGELOG.md +24 -2
- data/MAINTAINERS.md +1 -0
- data/lib/fluent/command/fluentd.rb +4 -0
- data/lib/fluent/config/element.rb +28 -15
- data/lib/fluent/config/error.rb +6 -0
- data/lib/fluent/config/literal_parser.rb +24 -2
- data/lib/fluent/config/section.rb +43 -6
- data/lib/fluent/config/types.rb +98 -26
- data/lib/fluent/configurable.rb +2 -2
- data/lib/fluent/engine.rb +6 -6
- data/lib/fluent/plugin/base.rb +1 -1
- data/lib/fluent/plugin/formatter_stdout.rb +1 -1
- data/lib/fluent/plugin/in_monitor_agent.rb +4 -2
- data/lib/fluent/plugin/out_forward.rb +3 -3
- data/lib/fluent/plugin/output.rb +11 -3
- data/lib/fluent/plugin_helper/compat_parameters.rb +11 -1
- data/lib/fluent/supervisor.rb +53 -65
- data/lib/fluent/system_config.rb +21 -7
- data/lib/fluent/time.rb +5 -3
- data/lib/fluent/version.rb +1 -1
- data/test/config/test_configurable.rb +154 -0
- data/test/config/test_element.rb +18 -0
- data/test/config/test_literal_parser.rb +4 -0
- data/test/config/test_system_config.rb +2 -1
- data/test/config/test_types.rb +293 -120
- data/test/plugin/out_forward/test_load_balancer.rb +1 -1
- data/test/plugin/test_in_monitor_agent.rb +2 -1
- data/test/plugin/test_out_stdout.rb +36 -1
- data/test/plugin/test_output.rb +25 -1
- data/test/test_logger_initializer.rb +26 -0
- data/test/test_supervisor.rb +26 -40
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e87e035a4839980ff8d1a31999d731790802d1e92f1c45fe1694622d34ea59c9
|
4
|
+
data.tar.gz: 787e06b6b6b74ee3f93e3e066627f11e02af7d10027f2dea913d22d14b1eab7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a56f21ab62ce38de8eb55d4f5f87340b08c603c46a64553e55475a22df5af40caf75d0768b0d87df99d7581e6a47f5344e8ffa590527d7456ee6334ec5a62d16
|
7
|
+
data.tar.gz: 34c24131c84b70c74201781f1ff87c3e0d5081b56f92c81144cb52dfe3ba89b2c5c2202be0d7e990ccab87945ae0333eb8a8f8a37ea3f02eb3528bcf3d2d3ff8
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
-
#
|
1
|
+
# v1.8
|
2
|
+
|
3
|
+
## Release v1.8.0 - 2019/12/11
|
2
4
|
|
3
5
|
### New feature
|
4
6
|
|
5
7
|
* Add service discovery plugin and `out_forward` use it
|
6
8
|
https://github.com/fluent/fluentd/pull/2541
|
9
|
+
* config: Add strict mode and support `default`/`nil` value in ruby embedded mode
|
10
|
+
https://github.com/fluent/fluentd/pull/2685
|
7
11
|
|
8
12
|
### Enhancement
|
9
13
|
|
@@ -15,6 +19,15 @@
|
|
15
19
|
https://github.com/fluent/fluentd/pull/2673
|
16
20
|
* log: Deprecate top-level match for capturing fluentd logs
|
17
21
|
https://github.com/fluent/fluentd/pull/2689
|
22
|
+
* in_monitor_agent: Expose Fluentd verion in REST API
|
23
|
+
https://github.com/fluent/fluentd/pull/2706
|
24
|
+
* time: Accept localtime xor utc
|
25
|
+
https://github.com/fluent/fluentd/pull/2720
|
26
|
+
https://github.com/fluent/fluentd/pull/2731
|
27
|
+
* formatter_stdout: Make time_format configurable in stdout format
|
28
|
+
https://github.com/fluent/fluentd/pull/2721
|
29
|
+
* supervisor: create log directory when it doesn't exists
|
30
|
+
https://github.com/fluent/fluentd/pull/2732
|
18
31
|
* clean up internal classes / methods / code
|
19
32
|
https://github.com/fluent/fluentd/pull/2647
|
20
33
|
https://github.com/fluent/fluentd/pull/2648
|
@@ -25,9 +38,14 @@
|
|
25
38
|
https://github.com/fluent/fluentd/pull/2674
|
26
39
|
https://github.com/fluent/fluentd/pull/2677
|
27
40
|
https://github.com/fluent/fluentd/pull/2680
|
41
|
+
https://github.com/fluent/fluentd/pull/2709
|
42
|
+
https://github.com/fluent/fluentd/pull/2730
|
28
43
|
|
29
44
|
### Bug fixes
|
30
45
|
|
46
|
+
* output: Fix warning printed when chunk key placeholder not replaced
|
47
|
+
https://github.com/fluent/fluentd/pull/2523
|
48
|
+
https://github.com/fluent/fluentd/pull/2733
|
31
49
|
* Fix dry-run mode
|
32
50
|
https://github.com/fluent/fluentd/pull/2651
|
33
51
|
* suppress warning
|
@@ -44,7 +62,11 @@
|
|
44
62
|
https://github.com/fluent/fluentd/pull/2695
|
45
63
|
* server helper: Fix IPv6 dual stack mode issue for tcp socket.
|
46
64
|
https://github.com/fluent/fluentd/pull/2697
|
47
|
-
|
65
|
+
* supervisor: Fix inline config handling
|
66
|
+
https://github.com/fluent/fluentd/pull/2708
|
67
|
+
* Fix typo
|
68
|
+
https://github.com/fluent/fluentd/pull/2710
|
69
|
+
https://github.com/fluent/fluentd/pull/2714
|
48
70
|
|
49
71
|
# v1.7
|
50
72
|
|
data/MAINTAINERS.md
CHANGED
@@ -5,3 +5,4 @@
|
|
5
5
|
- [Hiroshi Hatake](https://github.com/cosmo0920), [Clearcode](https://www.clear-code.com/)
|
6
6
|
- [Masahiro Nakagawa](https://github.com/repeatedly), [Treasure Data](https://www.treasuredata.com/)
|
7
7
|
- [Satoshi Tagomori](https://github.com/tagomoris), [Treasure Data](https://www.treasuredata.com/)
|
8
|
+
- [Eduardo Silva](https://github.com/edsiper), [Arm Treasure Data](https://www.treasuredata.com/)
|
@@ -131,6 +131,10 @@ op.on('--use-v0-config', "Use v0 configuration format", TrueClass) {|b|
|
|
131
131
|
opts[:use_v1_config] = !b
|
132
132
|
}
|
133
133
|
|
134
|
+
op.on('--strict-config-value', "Parse config values strictly", TrueClass) {|b|
|
135
|
+
opts[:strict_config_value] = b
|
136
|
+
}
|
137
|
+
|
134
138
|
op.on('-v', '--verbose', "increase verbose level (-v: debug, -vv: trace)", TrueClass) {|b|
|
135
139
|
if b
|
136
140
|
opts[:log_level] = [opts[:log_level] - 1, Fluent::Log::LEVEL_TRACE].max
|
@@ -142,7 +142,7 @@ module Fluent
|
|
142
142
|
indent = " " * nest
|
143
143
|
nindent = " " * (nest + 1)
|
144
144
|
out = ""
|
145
|
-
if @arg.empty?
|
145
|
+
if @arg.nil? || @arg.empty?
|
146
146
|
out << "#{indent}<#{@name}>\n"
|
147
147
|
else
|
148
148
|
out << "#{indent}<#{@name} #{@arg}>\n"
|
@@ -194,23 +194,36 @@ module Fluent
|
|
194
194
|
opts[:type]
|
195
195
|
end
|
196
196
|
|
197
|
+
def default_value(key)
|
198
|
+
return nil if @corresponding_proxies.empty?
|
199
|
+
|
200
|
+
param_key = key.to_sym
|
201
|
+
proxy = @corresponding_proxies.detect do |_proxy|
|
202
|
+
_proxy.params.has_key?(param_key)
|
203
|
+
end
|
204
|
+
return nil unless proxy
|
205
|
+
proxy.defaults[param_key]
|
206
|
+
end
|
207
|
+
|
197
208
|
def dump_value(k, v, nindent)
|
198
|
-
if secret_param?(k)
|
199
|
-
|
209
|
+
return "#{nindent}#{k} xxxxxx\n" if secret_param?(k)
|
210
|
+
return "#{nindent}#{k} #{v}\n" unless @v1_config
|
211
|
+
|
212
|
+
# for v1 config
|
213
|
+
if v.nil?
|
214
|
+
"#{nindent}#{k} \n"
|
215
|
+
elsif v == :default
|
216
|
+
"#{nindent}#{k} #{default_value(k)}\n"
|
200
217
|
else
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
"#{nindent}#{k} #{v}\n"
|
209
|
-
else
|
210
|
-
# Unknown type
|
211
|
-
"#{nindent}#{k} #{v}\n"
|
212
|
-
end
|
218
|
+
case param_type(k)
|
219
|
+
when :string
|
220
|
+
"#{nindent}#{k} \"#{self.class.unescape_parameter(v)}\"\n"
|
221
|
+
when :enum, :integer, :float, :size, :bool, :time
|
222
|
+
"#{nindent}#{k} #{v}\n"
|
223
|
+
when :hash, :array
|
224
|
+
"#{nindent}#{k} #{v}\n"
|
213
225
|
else
|
226
|
+
# Unknown type
|
214
227
|
"#{nindent}#{k} #{v}\n"
|
215
228
|
end
|
216
229
|
end
|
data/lib/fluent/config/error.rb
CHANGED
@@ -52,6 +52,16 @@ module Fluent
|
|
52
52
|
def initialize(strscan, eval_context)
|
53
53
|
super(strscan)
|
54
54
|
@eval_context = eval_context
|
55
|
+
unless @eval_context.respond_to?(:use_nil)
|
56
|
+
def @eval_context.use_nil
|
57
|
+
raise SetNil
|
58
|
+
end
|
59
|
+
end
|
60
|
+
unless @eval_context.respond_to?(:use_default)
|
61
|
+
def @eval_context.use_default
|
62
|
+
raise SetDefault
|
63
|
+
end
|
64
|
+
end
|
55
65
|
end
|
56
66
|
|
57
67
|
def parse_literal(string_boundary_charset = LINE_END)
|
@@ -81,7 +91,13 @@ module Fluent
|
|
81
91
|
string = []
|
82
92
|
while true
|
83
93
|
if skip(/\"/)
|
84
|
-
|
94
|
+
if string.include?(nil)
|
95
|
+
return nil
|
96
|
+
elsif string.include?(:default)
|
97
|
+
return :default
|
98
|
+
else
|
99
|
+
return string.join
|
100
|
+
end
|
85
101
|
elsif check(/[^"]#{LINE_END_WITHOUT_SPACING_AND_COMMENT}/)
|
86
102
|
if s = check(/[^\\]#{LINE_END_WITHOUT_SPACING_AND_COMMENT}/)
|
87
103
|
string << s
|
@@ -168,7 +184,13 @@ module Fluent
|
|
168
184
|
hostname = Socket.gethostname
|
169
185
|
worker_id = ENV['SERVERENGINE_WORKER_ID'] || ''
|
170
186
|
EOM
|
171
|
-
|
187
|
+
begin
|
188
|
+
@eval_context.instance_eval(code)
|
189
|
+
rescue SetNil => e
|
190
|
+
nil
|
191
|
+
rescue SetDefault => e
|
192
|
+
:default
|
193
|
+
end
|
172
194
|
end
|
173
195
|
|
174
196
|
def eval_escape_char(c)
|
@@ -106,7 +106,7 @@ module Fluent
|
|
106
106
|
end
|
107
107
|
|
108
108
|
module SectionGenerator
|
109
|
-
def self.generate(proxy, conf, logger, plugin_class, stack = [])
|
109
|
+
def self.generate(proxy, conf, logger, plugin_class, stack = [], strict_config_value = false)
|
110
110
|
return nil if conf.nil?
|
111
111
|
|
112
112
|
section_stack = ""
|
@@ -122,9 +122,23 @@ module Fluent
|
|
122
122
|
end
|
123
123
|
|
124
124
|
if proxy.argument
|
125
|
-
unless conf.arg.empty?
|
125
|
+
unless conf.arg.nil? || conf.arg.empty?
|
126
126
|
key, block, opts = proxy.argument
|
127
|
-
|
127
|
+
opts = opts.merge(strict: true) if strict_config_value
|
128
|
+
|
129
|
+
if conf.arg == :default
|
130
|
+
unless section_params.has_key?(key)
|
131
|
+
logger.error "config error in:\n#{conf}" if logger
|
132
|
+
raise ConfigError, "'#{key}' doesn't have default value"
|
133
|
+
end
|
134
|
+
else
|
135
|
+
begin
|
136
|
+
section_params[key] = self.instance_exec(conf.arg, opts, key, &block)
|
137
|
+
rescue ConfigError => e
|
138
|
+
logger.error "config error in:\n#{conf}" if logger
|
139
|
+
raise e
|
140
|
+
end
|
141
|
+
end
|
128
142
|
end
|
129
143
|
unless section_params.has_key?(proxy.argument.first)
|
130
144
|
logger.error "config error in:\n#{conf}" if logger # logger should exist, but somethimes it's nil (e.g, in tests)
|
@@ -136,13 +150,36 @@ module Fluent
|
|
136
150
|
proxy.params.each_pair do |name, defval|
|
137
151
|
varname = name.to_sym
|
138
152
|
block, opts = defval
|
153
|
+
opts = opts.merge(strict: true) if strict_config_value
|
154
|
+
|
139
155
|
if conf.has_key?(name.to_s) || opts[:alias] && conf.has_key?(opts[:alias].to_s)
|
140
156
|
val = if conf.has_key?(name.to_s)
|
141
157
|
conf[name.to_s]
|
142
158
|
else
|
143
159
|
conf[opts[:alias].to_s]
|
144
160
|
end
|
145
|
-
|
161
|
+
|
162
|
+
if val == :default
|
163
|
+
# default value is already set if it exists
|
164
|
+
unless section_params.has_key?(varname)
|
165
|
+
logger.error "config error in:\n#{conf}" if logger
|
166
|
+
raise ConfigError, "'#{varname}' doesn't have default value"
|
167
|
+
end
|
168
|
+
else
|
169
|
+
begin
|
170
|
+
section_params[varname] = self.instance_exec(val, opts, name, &block)
|
171
|
+
rescue ConfigError => e
|
172
|
+
logger.error "config error in:\n#{conf}" if logger
|
173
|
+
raise e
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
if section_params[varname].nil?
|
178
|
+
unless proxy.defaults.has_key?(varname) and proxy.defaults[varname].nil?
|
179
|
+
logger.error "config error in:\n#{conf}" if logger
|
180
|
+
raise ConfigError, "'#{name}' parameter is required but nil is specified"
|
181
|
+
end
|
182
|
+
end
|
146
183
|
|
147
184
|
# Source of definitions of deprecated/obsoleted:
|
148
185
|
# https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features
|
@@ -190,13 +227,13 @@ module Fluent
|
|
190
227
|
raise ConfigError, "'<#{subproxy.name}>' sections are required" + section_stack
|
191
228
|
end
|
192
229
|
if subproxy.multi?
|
193
|
-
section_params[varname] = elements.map{ |e| generate(subproxy, e, logger, plugin_class, stack + [subproxy.name]) }
|
230
|
+
section_params[varname] = elements.map{ |e| generate(subproxy, e, logger, plugin_class, stack + [subproxy.name], strict_config_value) }
|
194
231
|
else
|
195
232
|
if elements.size > 1
|
196
233
|
logger.error "config error in:\n#{conf}" if logger
|
197
234
|
raise ConfigError, "'<#{subproxy.name}>' section cannot be written twice or more" + section_stack
|
198
235
|
end
|
199
|
-
section_params[varname] = generate(subproxy, elements.first, logger, plugin_class, stack + [subproxy.name])
|
236
|
+
section_params[varname] = generate(subproxy, elements.first, logger, plugin_class, stack + [subproxy.name], strict_config_value)
|
200
237
|
end
|
201
238
|
end
|
202
239
|
|
data/lib/fluent/config/types.rb
CHANGED
@@ -20,7 +20,9 @@ require 'fluent/config/error'
|
|
20
20
|
|
21
21
|
module Fluent
|
22
22
|
module Config
|
23
|
-
def self.size_value(str)
|
23
|
+
def self.size_value(str, opts = {}, name = nil)
|
24
|
+
return nil if str.nil?
|
25
|
+
|
24
26
|
case str.to_s
|
25
27
|
when /([0-9]+)k/i
|
26
28
|
$~[1].to_i * 1024
|
@@ -31,11 +33,13 @@ module Fluent
|
|
31
33
|
when /([0-9]+)t/i
|
32
34
|
$~[1].to_i * (1024 ** 4)
|
33
35
|
else
|
34
|
-
str
|
36
|
+
INTEGER_TYPE.call(str, opts, name)
|
35
37
|
end
|
36
38
|
end
|
37
39
|
|
38
|
-
def self.time_value(str)
|
40
|
+
def self.time_value(str, opts = {}, name = nil)
|
41
|
+
return nil if str.nil?
|
42
|
+
|
39
43
|
case str.to_s
|
40
44
|
when /([0-9]+)s/
|
41
45
|
$~[1].to_i
|
@@ -46,12 +50,13 @@ module Fluent
|
|
46
50
|
when /([0-9]+)d/
|
47
51
|
$~[1].to_i * 24 * 60 * 60
|
48
52
|
else
|
49
|
-
str
|
53
|
+
FLOAT_TYPE.call(str, opts, name)
|
50
54
|
end
|
51
55
|
end
|
52
56
|
|
53
|
-
def self.bool_value(str)
|
57
|
+
def self.bool_value(str, opts = {}, name = nil)
|
54
58
|
return nil if str.nil?
|
59
|
+
|
55
60
|
case str.to_s
|
56
61
|
when 'true', 'yes'
|
57
62
|
true
|
@@ -64,14 +69,17 @@ module Fluent
|
|
64
69
|
# parser should pass empty string in this case but changing behaviour may break existing environment so keep parser behaviour. Just ignore comment value in boolean handling for now.
|
65
70
|
if str.respond_to?('start_with?') && str.start_with?('#')
|
66
71
|
true
|
72
|
+
elsif opts[:strict]
|
73
|
+
raise Fluent::ConfigError, "#{name}: invalid bool value: #{str}"
|
67
74
|
else
|
68
75
|
nil
|
69
76
|
end
|
70
77
|
end
|
71
78
|
end
|
72
79
|
|
73
|
-
def self.regexp_value(str)
|
80
|
+
def self.regexp_value(str, opts = {}, name = nil)
|
74
81
|
return nil unless str
|
82
|
+
|
75
83
|
return Regexp.compile(str) unless str.start_with?("/")
|
76
84
|
right_slash_position = str.rindex("/")
|
77
85
|
if right_slash_position < str.size - 3
|
@@ -84,12 +92,21 @@ module Fluent
|
|
84
92
|
Regexp.compile(str[1...right_slash_position], option)
|
85
93
|
end
|
86
94
|
|
87
|
-
|
95
|
+
def self.string_value(val, opts = {}, name = nil)
|
96
|
+
return nil if val.nil?
|
97
|
+
|
88
98
|
v = val.to_s
|
89
99
|
v = v.frozen? ? v.dup : v # config_param can't assume incoming string is mutable
|
90
100
|
v.force_encoding(Encoding::UTF_8)
|
101
|
+
end
|
102
|
+
|
103
|
+
STRING_TYPE = Proc.new { |val, opts = {}, name = nil|
|
104
|
+
Config.string_value(val, opts, name)
|
91
105
|
}
|
92
|
-
|
106
|
+
|
107
|
+
def self.enum_value(val, opts = {}, name = nil)
|
108
|
+
return nil if val.nil?
|
109
|
+
|
93
110
|
s = val.to_sym
|
94
111
|
list = opts[:list]
|
95
112
|
raise "Plugin BUG: config type 'enum' requires :list of symbols" unless list.is_a?(Array) && list.all?{|v| v.is_a? Symbol }
|
@@ -97,33 +114,77 @@ module Fluent
|
|
97
114
|
raise ConfigError, "valid options are #{list.join(',')} but got #{val}"
|
98
115
|
end
|
99
116
|
s
|
117
|
+
end
|
118
|
+
|
119
|
+
ENUM_TYPE = Proc.new { |val, opts = {}, name = nil|
|
120
|
+
Config.enum_value(val, opts, name)
|
121
|
+
}
|
122
|
+
|
123
|
+
INTEGER_TYPE = Proc.new { |val, opts = {}, name = nil|
|
124
|
+
if val.nil?
|
125
|
+
nil
|
126
|
+
elsif opts[:strict]
|
127
|
+
begin
|
128
|
+
Integer(val)
|
129
|
+
rescue ArgumentError, TypeError => e
|
130
|
+
raise ConfigError, "#{name}: #{e.message}"
|
131
|
+
end
|
132
|
+
else
|
133
|
+
val.to_i
|
134
|
+
end
|
100
135
|
}
|
101
|
-
|
102
|
-
FLOAT_TYPE = Proc.new { |val, opts
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
136
|
+
|
137
|
+
FLOAT_TYPE = Proc.new { |val, opts = {}, name = nil|
|
138
|
+
if val.nil?
|
139
|
+
nil
|
140
|
+
elsif opts[:strict]
|
141
|
+
begin
|
142
|
+
Float(val)
|
143
|
+
rescue ArgumentError, TypeError => e
|
144
|
+
raise ConfigError, "#{name}: #{e.message}"
|
145
|
+
end
|
146
|
+
else
|
147
|
+
val.to_f
|
148
|
+
end
|
149
|
+
}
|
150
|
+
|
151
|
+
SIZE_TYPE = Proc.new { |val, opts = {}, name = nil|
|
152
|
+
Config.size_value(val, opts, name)
|
153
|
+
}
|
154
|
+
|
155
|
+
BOOL_TYPE = Proc.new { |val, opts = {}, name = nil|
|
156
|
+
Config.bool_value(val, opts, name)
|
157
|
+
}
|
158
|
+
|
159
|
+
TIME_TYPE = Proc.new { |val, opts = {}, name = nil|
|
160
|
+
Config.time_value(val, opts, name)
|
161
|
+
}
|
162
|
+
|
163
|
+
REGEXP_TYPE = Proc.new { |val, opts = {}, name = nil|
|
164
|
+
Config.regexp_value(val, opts, name)
|
165
|
+
}
|
166
|
+
|
167
|
+
REFORMAT_VALUE = ->(type, value, opts = {}, name = nil) {
|
109
168
|
if value.nil?
|
110
169
|
value
|
111
170
|
else
|
112
171
|
case type
|
113
172
|
when :string then value.to_s.force_encoding(Encoding::UTF_8)
|
114
|
-
when :integer then value
|
115
|
-
when :float then value
|
116
|
-
when :size then Config.size_value(value)
|
117
|
-
when :bool then Config.bool_value(value)
|
118
|
-
when :time then Config.time_value(value)
|
119
|
-
when :regexp then Config.regexp_value(value)
|
173
|
+
when :integer then INTEGER_TYPE.call(value, opts, name)
|
174
|
+
when :float then FLOAT_TYPE.call(value, opts, name)
|
175
|
+
when :size then Config.size_value(value, opts, name)
|
176
|
+
when :bool then Config.bool_value(value, opts, name)
|
177
|
+
when :time then Config.time_value(value, opts, name)
|
178
|
+
when :regexp then Config.regexp_value(value, opts, name)
|
120
179
|
else
|
121
180
|
raise "unknown type in REFORMAT: #{type}"
|
122
181
|
end
|
123
182
|
end
|
124
183
|
}
|
125
184
|
|
126
|
-
|
185
|
+
def self.hash_value(val, opts = {}, name = nil)
|
186
|
+
return nil if val.nil?
|
187
|
+
|
127
188
|
param = if val.is_a?(String)
|
128
189
|
val.start_with?('{') ? JSON.load(val) : Hash[val.strip.split(/\s*,\s*/).map{|v| v.split(':', 2)}]
|
129
190
|
else
|
@@ -138,12 +199,19 @@ module Fluent
|
|
138
199
|
newparam = {}
|
139
200
|
param.each_pair do |key, value|
|
140
201
|
new_key = opts[:symbolize_keys] ? key.to_sym : key
|
141
|
-
newparam[new_key] = opts[:value_type] ? REFORMAT_VALUE.call(opts[:value_type], value) : value
|
202
|
+
newparam[new_key] = opts[:value_type] ? REFORMAT_VALUE.call(opts[:value_type], value, opts, new_key) : value
|
142
203
|
end
|
143
204
|
newparam
|
144
205
|
end
|
206
|
+
end
|
207
|
+
|
208
|
+
HASH_TYPE = Proc.new { |val, opts = {}, name = nil|
|
209
|
+
Config.hash_value(val, opts, name)
|
145
210
|
}
|
146
|
-
|
211
|
+
|
212
|
+
def self.array_value(val, opts = {}, name = nil)
|
213
|
+
return nil if val.nil?
|
214
|
+
|
147
215
|
param = if val.is_a?(String)
|
148
216
|
val.start_with?('[') ? JSON.load(val) : val.strip.split(/\s*,\s*/)
|
149
217
|
else
|
@@ -153,10 +221,14 @@ module Fluent
|
|
153
221
|
raise ConfigError, "array required but got #{val.inspect}"
|
154
222
|
end
|
155
223
|
if opts[:value_type]
|
156
|
-
param.map{|v| REFORMAT_VALUE.call(opts[:value_type], v) }
|
224
|
+
param.map{|v| REFORMAT_VALUE.call(opts[:value_type], v, opts, nil) }
|
157
225
|
else
|
158
226
|
param
|
159
227
|
end
|
228
|
+
end
|
229
|
+
|
230
|
+
ARRAY_TYPE = Proc.new { |val, opts = {}, name = nil|
|
231
|
+
Config.array_value(val, opts, name)
|
160
232
|
}
|
161
233
|
end
|
162
234
|
end
|