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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f75be7f2480c2f0fbdddf1999dc3163b91f6bd75fb53b71ff3d7a0ee4f670af
4
- data.tar.gz: 5089bdce54388f855748befd4234ceb945f4ef7c6aa0f2a4f1aeea21adb516da
3
+ metadata.gz: e87e035a4839980ff8d1a31999d731790802d1e92f1c45fe1694622d34ea59c9
4
+ data.tar.gz: 787e06b6b6b74ee3f93e3e066627f11e02af7d10027f2dea913d22d14b1eab7f
5
5
  SHA512:
6
- metadata.gz: 6dfd02456cd7a47aaf483759b57075cc0b8c0bbe322a41c20cd6df7f9a163150af07a21201e8514b0ba097f50dc56ae7004c4116f2f4c2b5347eebde303a19a2
7
- data.tar.gz: 1ec01c129c043f8fafee99360a3a625907cff7666f9a605093110b4b1cc57691e7fd1eba543e2003568a9aa48d714a853b2644e83d2823f5773f49615bc0d265
6
+ metadata.gz: a56f21ab62ce38de8eb55d4f5f87340b08c603c46a64553e55475a22df5af40caf75d0768b0d87df99d7581e6a47f5344e8ffa590527d7456ee6334ec5a62d16
7
+ data.tar.gz: 34c24131c84b70c74201781f1ff87c3e0d5081b56f92c81144cb52dfe3ba89b2c5c2202be0d7e990ccab87945ae0333eb8a8f8a37ea3f02eb3528bcf3d2d3ff8
@@ -49,6 +49,10 @@ matrix:
49
49
  - rvm: 2.4.6
50
50
  os: osx
51
51
  osx_image: xcode8.3
52
+ - rvm: 2.5.5
53
+ os: linux
54
+ arch: s390x
55
+ dist: xenial
52
56
  - rvm: ruby-head
53
57
 
54
58
  branches:
@@ -1,9 +1,13 @@
1
- # Unreleased
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
 
@@ -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
- "#{nindent}#{k} xxxxxx\n"
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
- if @v1_config
202
- case param_type(k)
203
- when :string
204
- "#{nindent}#{k} \"#{self.class.unescape_parameter(v)}\"\n"
205
- when :enum, :integer, :float, :size, :bool, :time
206
- "#{nindent}#{k} #{v}\n"
207
- when :hash, :array
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
@@ -23,4 +23,10 @@ module Fluent
23
23
 
24
24
  class ObsoletedParameterError < ConfigError
25
25
  end
26
+
27
+ class SetNil < Exception
28
+ end
29
+
30
+ class SetDefault < Exception
31
+ end
26
32
  end
@@ -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
- return string.join
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
- @eval_context.instance_eval(code)
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
- section_params[key] = self.instance_exec(conf.arg, opts, name, &block)
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
- section_params[varname] = self.instance_exec(val, opts, name, &block)
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
 
@@ -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.to_i
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.to_f
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
- STRING_TYPE = Proc.new { |val, opts|
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
- ENUM_TYPE = Proc.new { |val, opts|
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
- INTEGER_TYPE = Proc.new { |val, opts| val.to_i }
102
- FLOAT_TYPE = Proc.new { |val, opts| val.to_f }
103
- SIZE_TYPE = Proc.new { |val, opts| Config.size_value(val) }
104
- BOOL_TYPE = Proc.new { |val, opts| Config.bool_value(val) }
105
- TIME_TYPE = Proc.new { |val, opts| Config.time_value(val) }
106
- REGEXP_TYPE = Proc.new { |val, opts| Config.regexp_value(val) }
107
-
108
- REFORMAT_VALUE = ->(type, value) {
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.to_i
115
- when :float then value.to_f
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
- HASH_TYPE = Proc.new { |val, opts|
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
- ARRAY_TYPE = Proc.new { |val, opts|
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