fluentd 0.12.40 → 0.14.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.

Files changed (252) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE.md +6 -0
  3. data/.gitignore +2 -0
  4. data/.travis.yml +33 -21
  5. data/CONTRIBUTING.md +1 -0
  6. data/ChangeLog +810 -237
  7. data/README.md +0 -25
  8. data/Rakefile +2 -1
  9. data/Vagrantfile +17 -0
  10. data/appveyor.yml +35 -0
  11. data/example/filter_stdout.conf +5 -5
  12. data/example/in_forward.conf +2 -2
  13. data/example/in_http.conf +2 -2
  14. data/example/in_out_forward.conf +17 -0
  15. data/example/in_syslog.conf +2 -2
  16. data/example/in_tail.conf +2 -2
  17. data/example/in_tcp.conf +2 -2
  18. data/example/in_udp.conf +2 -2
  19. data/example/out_copy.conf +4 -4
  20. data/example/out_file.conf +2 -2
  21. data/example/out_forward.conf +2 -2
  22. data/example/out_forward_buf_file.conf +23 -0
  23. data/example/v0_12_filter.conf +8 -8
  24. data/fluent.conf +29 -0
  25. data/fluentd.gemspec +18 -11
  26. data/lib/fluent/agent.rb +60 -58
  27. data/lib/fluent/command/cat.rb +1 -1
  28. data/lib/fluent/command/debug.rb +7 -5
  29. data/lib/fluent/command/fluentd.rb +97 -2
  30. data/lib/fluent/compat/call_super_mixin.rb +67 -0
  31. data/lib/fluent/compat/filter.rb +50 -0
  32. data/lib/fluent/compat/formatter.rb +109 -0
  33. data/lib/fluent/compat/input.rb +50 -0
  34. data/lib/fluent/compat/output.rb +617 -0
  35. data/lib/fluent/compat/output_chain.rb +60 -0
  36. data/lib/fluent/compat/parser.rb +163 -0
  37. data/lib/fluent/compat/propagate_default.rb +62 -0
  38. data/lib/fluent/config.rb +23 -20
  39. data/lib/fluent/config/configure_proxy.rb +119 -70
  40. data/lib/fluent/config/dsl.rb +5 -18
  41. data/lib/fluent/config/element.rb +72 -8
  42. data/lib/fluent/config/error.rb +0 -3
  43. data/lib/fluent/config/literal_parser.rb +0 -2
  44. data/lib/fluent/config/parser.rb +4 -4
  45. data/lib/fluent/config/section.rb +39 -28
  46. data/lib/fluent/config/types.rb +2 -13
  47. data/lib/fluent/config/v1_parser.rb +1 -3
  48. data/lib/fluent/configurable.rb +48 -16
  49. data/lib/fluent/daemon.rb +15 -0
  50. data/lib/fluent/engine.rb +26 -52
  51. data/lib/fluent/env.rb +6 -4
  52. data/lib/fluent/event.rb +58 -11
  53. data/lib/fluent/event_router.rb +5 -5
  54. data/lib/fluent/filter.rb +2 -50
  55. data/lib/fluent/formatter.rb +4 -293
  56. data/lib/fluent/input.rb +2 -32
  57. data/lib/fluent/label.rb +2 -2
  58. data/lib/fluent/load.rb +3 -2
  59. data/lib/fluent/log.rb +107 -38
  60. data/lib/fluent/match.rb +0 -36
  61. data/lib/fluent/mixin.rb +117 -7
  62. data/lib/fluent/msgpack_factory.rb +62 -0
  63. data/lib/fluent/output.rb +7 -612
  64. data/lib/fluent/output_chain.rb +23 -0
  65. data/lib/fluent/parser.rb +4 -800
  66. data/lib/fluent/plugin.rb +100 -121
  67. data/lib/fluent/plugin/bare_output.rb +63 -0
  68. data/lib/fluent/plugin/base.rb +121 -0
  69. data/lib/fluent/plugin/buf_file.rb +101 -182
  70. data/lib/fluent/plugin/buf_memory.rb +9 -92
  71. data/lib/fluent/plugin/buffer.rb +473 -0
  72. data/lib/fluent/plugin/buffer/chunk.rb +135 -0
  73. data/lib/fluent/plugin/buffer/file_chunk.rb +339 -0
  74. data/lib/fluent/plugin/buffer/memory_chunk.rb +100 -0
  75. data/lib/fluent/plugin/exec_util.rb +80 -75
  76. data/lib/fluent/plugin/file_util.rb +33 -28
  77. data/lib/fluent/plugin/file_wrapper.rb +120 -0
  78. data/lib/fluent/plugin/filter.rb +51 -0
  79. data/lib/fluent/plugin/filter_grep.rb +13 -40
  80. data/lib/fluent/plugin/filter_record_transformer.rb +22 -18
  81. data/lib/fluent/plugin/formatter.rb +93 -0
  82. data/lib/fluent/plugin/formatter_csv.rb +48 -0
  83. data/lib/fluent/plugin/formatter_hash.rb +32 -0
  84. data/lib/fluent/plugin/formatter_json.rb +47 -0
  85. data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
  86. data/lib/fluent/plugin/formatter_msgpack.rb +32 -0
  87. data/lib/fluent/plugin/formatter_out_file.rb +45 -0
  88. data/lib/fluent/plugin/formatter_single_value.rb +34 -0
  89. data/lib/fluent/plugin/formatter_stdout.rb +39 -0
  90. data/lib/fluent/plugin/in_debug_agent.rb +4 -0
  91. data/lib/fluent/plugin/in_dummy.rb +22 -18
  92. data/lib/fluent/plugin/in_exec.rb +18 -8
  93. data/lib/fluent/plugin/in_forward.rb +36 -79
  94. data/lib/fluent/plugin/in_gc_stat.rb +4 -0
  95. data/lib/fluent/plugin/in_http.rb +21 -18
  96. data/lib/fluent/plugin/in_monitor_agent.rb +15 -48
  97. data/lib/fluent/plugin/in_object_space.rb +6 -1
  98. data/lib/fluent/plugin/in_stream.rb +7 -3
  99. data/lib/fluent/plugin/in_syslog.rb +46 -95
  100. data/lib/fluent/plugin/in_tail.rb +51 -595
  101. data/lib/fluent/plugin/in_tcp.rb +8 -1
  102. data/lib/fluent/plugin/in_udp.rb +8 -14
  103. data/lib/fluent/plugin/input.rb +33 -0
  104. data/lib/fluent/plugin/multi_output.rb +95 -0
  105. data/lib/fluent/plugin/out_buffered_null.rb +59 -0
  106. data/lib/fluent/plugin/out_copy.rb +11 -7
  107. data/lib/fluent/plugin/out_exec.rb +15 -11
  108. data/lib/fluent/plugin/out_exec_filter.rb +18 -10
  109. data/lib/fluent/plugin/out_file.rb +34 -5
  110. data/lib/fluent/plugin/out_forward.rb +19 -9
  111. data/lib/fluent/plugin/out_null.rb +0 -14
  112. data/lib/fluent/plugin/out_roundrobin.rb +11 -7
  113. data/lib/fluent/plugin/out_stdout.rb +5 -7
  114. data/lib/fluent/plugin/out_stream.rb +3 -1
  115. data/lib/fluent/plugin/output.rb +979 -0
  116. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  117. data/lib/fluent/plugin/parser.rb +244 -0
  118. data/lib/fluent/plugin/parser_apache.rb +24 -0
  119. data/lib/fluent/plugin/parser_apache2.rb +84 -0
  120. data/lib/fluent/plugin/parser_apache_error.rb +21 -0
  121. data/lib/fluent/plugin/parser_csv.rb +31 -0
  122. data/lib/fluent/plugin/parser_json.rb +79 -0
  123. data/lib/fluent/plugin/parser_ltsv.rb +50 -0
  124. data/lib/fluent/plugin/parser_multiline.rb +102 -0
  125. data/lib/fluent/plugin/parser_nginx.rb +24 -0
  126. data/lib/fluent/plugin/parser_none.rb +36 -0
  127. data/lib/fluent/plugin/parser_syslog.rb +82 -0
  128. data/lib/fluent/plugin/parser_tsv.rb +37 -0
  129. data/lib/fluent/plugin/socket_util.rb +120 -114
  130. data/lib/fluent/plugin/storage.rb +84 -0
  131. data/lib/fluent/plugin/storage_local.rb +116 -0
  132. data/lib/fluent/plugin/string_util.rb +16 -13
  133. data/lib/fluent/plugin_helper.rb +39 -0
  134. data/lib/fluent/plugin_helper/child_process.rb +298 -0
  135. data/lib/fluent/plugin_helper/compat_parameters.rb +99 -0
  136. data/lib/fluent/plugin_helper/event_emitter.rb +80 -0
  137. data/lib/fluent/plugin_helper/event_loop.rb +118 -0
  138. data/lib/fluent/plugin_helper/retry_state.rb +177 -0
  139. data/lib/fluent/plugin_helper/storage.rb +308 -0
  140. data/lib/fluent/plugin_helper/thread.rb +147 -0
  141. data/lib/fluent/plugin_helper/timer.rb +85 -0
  142. data/lib/fluent/plugin_id.rb +63 -0
  143. data/lib/fluent/process.rb +21 -30
  144. data/lib/fluent/registry.rb +21 -9
  145. data/lib/fluent/root_agent.rb +115 -40
  146. data/lib/fluent/supervisor.rb +330 -320
  147. data/lib/fluent/system_config.rb +42 -18
  148. data/lib/fluent/test.rb +6 -1
  149. data/lib/fluent/test/base.rb +23 -3
  150. data/lib/fluent/test/driver/base.rb +247 -0
  151. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  152. data/lib/fluent/test/driver/filter.rb +35 -0
  153. data/lib/fluent/test/driver/input.rb +31 -0
  154. data/lib/fluent/test/driver/output.rb +78 -0
  155. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  156. data/lib/fluent/test/filter_test.rb +0 -1
  157. data/lib/fluent/test/formatter_test.rb +2 -1
  158. data/lib/fluent/test/input_test.rb +23 -17
  159. data/lib/fluent/test/output_test.rb +28 -39
  160. data/lib/fluent/test/parser_test.rb +1 -1
  161. data/lib/fluent/time.rb +104 -1
  162. data/lib/fluent/{status.rb → unique_id.rb} +15 -24
  163. data/lib/fluent/version.rb +1 -1
  164. data/lib/fluent/winsvc.rb +72 -0
  165. data/test/compat/test_calls_super.rb +164 -0
  166. data/test/config/test_config_parser.rb +83 -0
  167. data/test/config/test_configurable.rb +547 -274
  168. data/test/config/test_configure_proxy.rb +146 -29
  169. data/test/config/test_dsl.rb +3 -181
  170. data/test/config/test_element.rb +274 -0
  171. data/test/config/test_literal_parser.rb +1 -1
  172. data/test/config/test_section.rb +79 -7
  173. data/test/config/test_system_config.rb +21 -0
  174. data/test/config/test_types.rb +3 -26
  175. data/test/helper.rb +78 -8
  176. data/test/plugin/test_bare_output.rb +118 -0
  177. data/test/plugin/test_base.rb +75 -0
  178. data/test/plugin/test_buf_file.rb +420 -521
  179. data/test/plugin/test_buf_memory.rb +32 -194
  180. data/test/plugin/test_buffer.rb +981 -0
  181. data/test/plugin/test_buffer_chunk.rb +110 -0
  182. data/test/plugin/test_buffer_file_chunk.rb +770 -0
  183. data/test/plugin/test_buffer_memory_chunk.rb +265 -0
  184. data/test/plugin/test_filter.rb +255 -0
  185. data/test/plugin/test_filter_grep.rb +2 -73
  186. data/test/plugin/test_filter_record_transformer.rb +24 -68
  187. data/test/plugin/test_filter_stdout.rb +6 -6
  188. data/test/plugin/test_in_debug_agent.rb +2 -0
  189. data/test/plugin/test_in_dummy.rb +11 -17
  190. data/test/plugin/test_in_exec.rb +6 -25
  191. data/test/plugin/test_in_forward.rb +112 -151
  192. data/test/plugin/test_in_gc_stat.rb +2 -0
  193. data/test/plugin/test_in_http.rb +106 -157
  194. data/test/plugin/test_in_object_space.rb +21 -5
  195. data/test/plugin/test_in_stream.rb +14 -13
  196. data/test/plugin/test_in_syslog.rb +30 -275
  197. data/test/plugin/test_in_tail.rb +95 -234
  198. data/test/plugin/test_in_tcp.rb +14 -0
  199. data/test/plugin/test_in_udp.rb +21 -13
  200. data/test/plugin/test_input.rb +122 -0
  201. data/test/plugin/test_multi_output.rb +180 -0
  202. data/test/plugin/test_out_buffered_null.rb +79 -0
  203. data/test/plugin/test_out_copy.rb +15 -2
  204. data/test/plugin/test_out_exec.rb +75 -25
  205. data/test/plugin/test_out_exec_filter.rb +74 -8
  206. data/test/plugin/test_out_file.rb +61 -7
  207. data/test/plugin/test_out_forward.rb +92 -15
  208. data/test/plugin/test_out_roundrobin.rb +1 -0
  209. data/test/plugin/test_out_stdout.rb +22 -13
  210. data/test/plugin/test_out_stream.rb +18 -0
  211. data/test/plugin/test_output.rb +515 -0
  212. data/test/plugin/test_output_as_buffered.rb +1540 -0
  213. data/test/plugin/test_output_as_buffered_overflow.rb +247 -0
  214. data/test/plugin/test_output_as_buffered_retries.rb +808 -0
  215. data/test/plugin/test_output_as_buffered_secondary.rb +776 -0
  216. data/test/plugin/test_output_as_standard.rb +362 -0
  217. data/test/plugin/test_owned_by.rb +35 -0
  218. data/test/plugin/test_storage.rb +167 -0
  219. data/test/plugin/test_storage_local.rb +8 -0
  220. data/test/plugin_helper/test_child_process.rb +599 -0
  221. data/test/plugin_helper/test_compat_parameters.rb +175 -0
  222. data/test/plugin_helper/test_event_emitter.rb +51 -0
  223. data/test/plugin_helper/test_event_loop.rb +52 -0
  224. data/test/plugin_helper/test_retry_state.rb +399 -0
  225. data/test/plugin_helper/test_storage.rb +411 -0
  226. data/test/plugin_helper/test_thread.rb +164 -0
  227. data/test/plugin_helper/test_timer.rb +100 -0
  228. data/test/scripts/exec_script.rb +0 -6
  229. data/test/scripts/fluent/plugin/out_test.rb +3 -0
  230. data/test/test_config.rb +13 -4
  231. data/test/test_event.rb +24 -13
  232. data/test/test_event_router.rb +8 -7
  233. data/test/test_event_time.rb +187 -0
  234. data/test/test_formatter.rb +13 -51
  235. data/test/test_input.rb +1 -1
  236. data/test/test_log.rb +239 -16
  237. data/test/test_mixin.rb +1 -1
  238. data/test/test_output.rb +53 -66
  239. data/test/test_parser.rb +105 -323
  240. data/test/test_plugin_helper.rb +81 -0
  241. data/test/test_root_agent.rb +4 -52
  242. data/test/test_supervisor.rb +272 -0
  243. data/test/test_unique_id.rb +47 -0
  244. metadata +180 -54
  245. data/lib/fluent/buffer.rb +0 -365
  246. data/lib/fluent/plugin/filter_parser.rb +0 -107
  247. data/lib/fluent/plugin/in_status.rb +0 -76
  248. data/lib/fluent/test/helpers.rb +0 -86
  249. data/test/plugin/data/log/foo/bar2 +0 -0
  250. data/test/plugin/test_filter_parser.rb +0 -744
  251. data/test/plugin/test_in_status.rb +0 -38
  252. data/test/test_buffer.rb +0 -624
@@ -35,19 +35,14 @@ module Fluent
35
35
  end
36
36
 
37
37
  class Proxy
38
- def initialize(name, arg, include_basepath = Dir.pwd)
38
+ def initialize(name, arg)
39
39
  @element = Element.new(name, arg, self)
40
- @include_basepath = include_basepath
41
40
  end
42
41
 
43
42
  def element
44
43
  @element
45
44
  end
46
45
 
47
- def include_basepath
48
- @include_basepath
49
- end
50
-
51
46
  def eval(source, source_path)
52
47
  @element.instance_eval(source, source_path)
53
48
  self
@@ -82,6 +77,10 @@ module Fluent
82
77
  @proxy = proxy
83
78
  end
84
79
 
80
+ def to_int
81
+ __id__
82
+ end
83
+
85
84
  def method_missing(name, *args, &block)
86
85
  ::Kernel.raise ::ArgumentError, "Configuration DSL Syntax Error: only one argument allowed" if args.size > 1
87
86
  value = args.first
@@ -101,18 +100,6 @@ module Fluent
101
100
  self
102
101
  end
103
102
 
104
- def include(*args)
105
- ::Kernel.raise ::ArgumentError, "#{name} block requires arguments for include path" if args.nil? || args.size != 1
106
- if args.first =~ /\.rb$/
107
- path = File.expand_path(args.first)
108
- data = File.read(path)
109
- self.instance_eval(data, path)
110
- else
111
- ss = StringScanner.new('')
112
- Config::V1Parser.new(ss, @proxy.include_basepath, '', nil).eval_include(@attrs, @elements, args.first)
113
- end
114
- end
115
-
116
103
  def source(&block)
117
104
  @proxy.add_element('source', nil, block)
118
105
  end
@@ -32,11 +32,36 @@ module Fluent
32
32
  @v1_config = false
33
33
  @corresponding_proxies = [] # some plugins use flat parameters, e.g. in_http doesn't provide <format> section for parser.
34
34
  @unused_in = false # if this element is not used in plugins, correspoing plugin name and parent element name is set, e.g. [source, plugin class].
35
+
36
+ # it's global logger, not plugin logger: deprecated message should be global warning, not plugin level.
37
+ @logger = defined?($log) ? $log : nil
35
38
  end
36
39
 
37
- attr_accessor :name, :arg, :elements, :unused, :v1_config, :corresponding_proxies, :unused_in
40
+ attr_accessor :name, :arg, :unused, :v1_config, :corresponding_proxies, :unused_in
41
+ attr_writer :elements
42
+
43
+ RESERVED_PARAMETERS_COMPAT = {
44
+ '@type' => 'type',
45
+ '@id' => 'id',
46
+ '@log_level' => 'log_level',
47
+ '@label' => nil,
48
+ }
49
+ RESERVED_PARAMETERS = RESERVED_PARAMETERS_COMPAT.keys
50
+
51
+ def elements(*names, name: nil, arg: nil)
52
+ raise ArgumentError, "name and names are exclusive" if name && !names.empty?
53
+ raise ArgumentError, "arg is available only with name" if arg && !name
54
+
55
+ if name
56
+ @elements.select{|e| e.name == name && (!arg || e.arg == arg) }
57
+ elsif !names.empty?
58
+ @elements.select{|e| names.include?(e.name) }
59
+ else
60
+ @elements
61
+ end
62
+ end
38
63
 
39
- def add_element(name, arg='')
64
+ def add_element(name, arg = '')
40
65
  e = Element.new(name, arg, {}, [])
41
66
  e.v1_config = @v1_config
42
67
  @elements << e
@@ -63,6 +88,7 @@ module Fluent
63
88
  e
64
89
  end
65
90
 
91
+ # no code in fluentd uses this method
66
92
  def each_element(*names, &block)
67
93
  if names.empty?
68
94
  @elements.each(&block)
@@ -84,6 +110,12 @@ module Fluent
84
110
  def [](key)
85
111
  @unused_in = false # ditto
86
112
  @unused.delete(key)
113
+
114
+ if RESERVED_PARAMETERS.include?(key) && !has_key?(key) && has_key?(RESERVED_PARAMETERS_COMPAT[key])
115
+ @logger.warn "'#{RESERVED_PARAMETERS_COMPAT[key]}' is deprecated parameter name. use '#{key}' instead." if @logger
116
+ return self[RESERVED_PARAMETERS_COMPAT[key]]
117
+ end
118
+
87
119
  super
88
120
  end
89
121
 
@@ -108,11 +140,7 @@ module Fluent
108
140
  out << "#{indent}<#{@name} #{@arg}>\n"
109
141
  end
110
142
  each_pair { |k, v|
111
- if secret_param?(k)
112
- out << "#{nindent}#{k} xxxxxx\n"
113
- else
114
- out << "#{nindent}#{k} #{v}\n"
115
- end
143
+ out << dump_value(k, v, indent, nindent)
116
144
  }
117
145
  @elements.each { |e|
118
146
  out << e.to_s(nest + 1)
@@ -124,6 +152,8 @@ module Fluent
124
152
  def to_masked_element
125
153
  new_elems = @elements.map { |e| e.to_masked_element }
126
154
  new_elem = Element.new(@name, @arg, {}, new_elems, @unused)
155
+ new_elem.v1_config = @v1_config
156
+ new_elem.corresponding_proxies = @corresponding_proxies
127
157
  each_pair { |k, v|
128
158
  new_elem[k] = secret_param?(k) ? 'xxxxxx' : v
129
159
  }
@@ -135,7 +165,7 @@ module Fluent
135
165
 
136
166
  param_key = key.to_sym
137
167
  @corresponding_proxies.each { |proxy|
138
- block, opts = proxy.params[param_key]
168
+ _block, opts = proxy.params[param_key]
139
169
  if opts && opts.has_key?(:secret)
140
170
  return opts[:secret]
141
171
  end
@@ -144,6 +174,40 @@ module Fluent
144
174
  false
145
175
  end
146
176
 
177
+ def param_type(key)
178
+ return nil if @corresponding_proxies.empty?
179
+
180
+ param_key = key.to_sym
181
+ proxy = @corresponding_proxies.detect do |_proxy|
182
+ _proxy.params.has_key?(param_key)
183
+ end
184
+ return nil unless proxy
185
+ _block, opts = proxy.params[param_key]
186
+ opts[:type]
187
+ end
188
+
189
+ def dump_value(k, v, indent, nindent)
190
+ if secret_param?(k)
191
+ "#{nindent}#{k} xxxxxx\n"
192
+ else
193
+ if @v1_config
194
+ case param_type(k)
195
+ when :string
196
+ "#{nindent}#{k} \"#{self.class.unescape_parameter(v)}\"\n"
197
+ when :enum, :integer, :float, :size, :bool, :time
198
+ "#{nindent}#{k} #{v}\n"
199
+ when :hash, :array
200
+ "#{nindent}#{k} #{v}\n"
201
+ else
202
+ # Unknown type
203
+ "#{nindent}#{k} #{v}\n"
204
+ end
205
+ else
206
+ "#{nindent}#{k} #{v}\n"
207
+ end
208
+ end
209
+ end
210
+
147
211
  def self.unescape_parameter(v)
148
212
  result = ''
149
213
  v.each_char { |c| result << LiteralParser.unescape_char(c) }
@@ -20,7 +20,4 @@ module Fluent
20
20
 
21
21
  class ConfigParseError < ConfigError
22
22
  end
23
-
24
- class ObsoletedParameterError < ConfigError
25
- end
26
23
  end
@@ -181,8 +181,6 @@ module Fluent
181
181
  "\f"
182
182
  when "b"
183
183
  "\b"
184
- when "0"
185
- "\0"
186
184
  when /[a-zA-Z0-9]/
187
185
  parse_error! "unexpected back-slash escape character '#{c}'"
188
186
  else # symbols
@@ -81,10 +81,10 @@ module Fluent
81
81
  pattern = path
82
82
  end
83
83
 
84
- Dir.glob(pattern).sort.each { |path|
85
- basepath = File.dirname(path)
86
- fname = File.basename(path)
87
- File.open(path) { |f|
84
+ Dir.glob(pattern).sort.each { |entry|
85
+ basepath = File.dirname(entry)
86
+ fname = File.basename(entry)
87
+ File.open(entry) { |f|
88
88
  Parser.new(basepath, f.each_line, fname).parse!(allow_include, nil, attrs, elems)
89
89
  }
90
90
  }
@@ -26,13 +26,26 @@ module Fluent
26
26
  'Fluent::Config::Section'
27
27
  end
28
28
 
29
- def initialize(params = {})
29
+ def initialize(params = {}, config_element = nil)
30
30
  @klass = 'Fluent::Config::Section'
31
31
  @params = params
32
+ @corresponding_config_element = config_element
32
33
  end
33
34
 
34
35
  alias :object_id :__id__
35
36
 
37
+ def corresponding_config_element
38
+ @corresponding_config_element
39
+ end
40
+
41
+ def class
42
+ Section
43
+ end
44
+
45
+ def to_s
46
+ inspect
47
+ end
48
+
36
49
  def inspect
37
50
  "<Fluent::Config::Section #{@params.to_json}>"
38
51
  end
@@ -62,6 +75,19 @@ module Fluent
62
75
  @params[key.to_sym]
63
76
  end
64
77
 
78
+ def respond_to?(symbol, include_all=false)
79
+ case symbol
80
+ when :inspect, :nil?, :to_h, :+, :instance_of?, :kind_of?, :[], :respond_to?, :respond_to_missing?
81
+ true
82
+ when :!, :!= , :==, :equal?, :instance_eval, :instance_exec
83
+ true
84
+ when :method_missing, :singleton_method_added, :singleton_method_removed, :singleton_method_undefined
85
+ include_all
86
+ else
87
+ false
88
+ end
89
+ end
90
+
65
91
  def respond_to_missing?(symbol, include_private)
66
92
  @params.has_key?(symbol)
67
93
  end
@@ -70,7 +96,7 @@ module Fluent
70
96
  if @params.has_key?(name)
71
97
  @params[name]
72
98
  else
73
- super
99
+ ::Kernel.raise ::NoMethodError, "undefined method `#{name}' for #{self.inspect}"
74
100
  end
75
101
  end
76
102
  end
@@ -88,7 +114,7 @@ module Fluent
88
114
 
89
115
  proxy.defaults.each_pair do |name, defval|
90
116
  varname = name.to_sym
91
- section_params[varname] = defval
117
+ section_params[varname] = (defval.dup rescue defval)
92
118
  end
93
119
 
94
120
  if proxy.argument
@@ -97,10 +123,9 @@ module Fluent
97
123
  section_params[key] = self.instance_exec(conf.arg, opts, name, &block)
98
124
  end
99
125
  unless section_params.has_key?(proxy.argument.first)
100
- logger.error "config error in:\n#{conf}"
126
+ logger.error "config error in:\n#{conf}" if logger # logger should exist, but somethimes it's nil (e.g, in tests)
101
127
  raise ConfigError, "'<#{proxy.name} ARG>' section requires argument" + section_stack
102
128
  end
103
- # argument should NOT be deprecated... (argument always has a value: '')
104
129
  end
105
130
 
106
131
  proxy.params.each_pair do |name, defval|
@@ -113,23 +138,9 @@ module Fluent
113
138
  conf[opts[:alias].to_s]
114
139
  end
115
140
  section_params[varname] = self.instance_exec(val, opts, name, &block)
116
-
117
- # Source of definitions of deprecated/obsoleted:
118
- # https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features
119
- #
120
- # Deprecated: These deprecated features can still be used, but should be used with caution
121
- # because they are expected to be removed entirely sometime in the future.
122
- # Obsoleted: These obsolete features have been entirely removed from JavaScript and can no longer be used.
123
- if opts[:deprecated]
124
- logger.warn "'#{name}' parameter is deprecated: #{opts[:deprecated]}"
125
- end
126
- if opts[:obsoleted]
127
- logger.error "config error in:\n#{conf}" if logger
128
- raise ObsoletedParameterError, "'#{name}' parameter is already removed: #{opts[:obsoleted]}" + section_stack
129
- end
130
141
  end
131
142
  unless section_params.has_key?(varname)
132
- logger.error "config error in:\n#{conf}"
143
+ logger.error "config error in:\n#{conf}" if logger
133
144
  raise ConfigError, "'#{name}' parameter is required" + section_stack
134
145
  end
135
146
  end
@@ -137,39 +148,39 @@ module Fluent
137
148
  check_unused_section(proxy, conf, plugin_class)
138
149
 
139
150
  proxy.sections.each do |name, subproxy|
140
- varname = subproxy.param_name.to_sym
151
+ varname = subproxy.variable_name
141
152
  elements = (conf.respond_to?(:elements) ? conf.elements : []).select{ |e| e.name == subproxy.name.to_s || e.name == subproxy.alias.to_s }
153
+ if elements.empty? && subproxy.init? && !subproxy.multi?
154
+ elements << Fluent::Config::Element.new(subproxy.name.to_s, '', {}, [])
155
+ end
156
+
142
157
  # set subproxy for secret option
143
158
  elements.each { |element|
144
159
  element.corresponding_proxies << subproxy
145
160
  }
146
161
 
147
162
  if subproxy.required? && elements.size < 1
148
- logger.error "config error in:\n#{conf}"
163
+ logger.error "config error in:\n#{conf}" if logger
149
164
  raise ConfigError, "'<#{subproxy.name}>' sections are required" + section_stack
150
165
  end
151
166
  if subproxy.multi?
152
167
  section_params[varname] = elements.map{ |e| generate(subproxy, e, logger, plugin_class, stack + [subproxy.name]) }
153
168
  else
154
169
  if elements.size > 1
155
- logger.error "config error in:\n#{conf}"
170
+ logger.error "config error in:\n#{conf}" if logger
156
171
  raise ConfigError, "'<#{subproxy.name}>' section cannot be written twice or more" + section_stack
157
172
  end
158
173
  section_params[varname] = generate(subproxy, elements.first, logger, plugin_class, stack + [subproxy.name])
159
174
  end
160
175
  end
161
176
 
162
- Section.new(section_params)
177
+ Section.new(section_params, conf)
163
178
  end
164
179
 
165
180
  def self.check_unused_section(proxy, conf, plugin_class)
166
181
  elems = conf.respond_to?(:elements) ? conf.elements : []
167
182
  elems.each { |e|
168
183
  next if plugin_class.nil? && Fluent::Config::V1Parser::ELEM_SYMBOLS.include?(e.name) # skip pre-defined non-plugin elements because it doens't have proxy section
169
- # In v0.12, buffer and output parameters are defined in same place.
170
- # It causes same configuration is used in different buffer / output
171
- # and buffer plugin's sections are always empty. It should be skipped.
172
- next if proxy.sections.empty?
173
184
 
174
185
  unless proxy.sections.any? { |name, subproxy| e.name == subproxy.name.to_s || e.name == subproxy.alias.to_s }
175
186
  parent_name = if conf.arg.empty?
@@ -17,7 +17,6 @@
17
17
  require 'json'
18
18
 
19
19
  require 'fluent/config/error'
20
- require 'fluent/configurable'
21
20
 
22
21
  module Fluent
23
22
  module Config
@@ -65,7 +64,7 @@ module Fluent
65
64
  end
66
65
  end
67
66
 
68
- STRING_TYPE = Proc.new { |val, opts| val.to_s.force_encoding(Encoding::UTF_8) }
67
+ STRING_TYPE = Proc.new { |val, opts| val }
69
68
  ENUM_TYPE = Proc.new { |val, opts|
70
69
  s = val.to_sym
71
70
  list = opts[:list]
@@ -86,7 +85,7 @@ module Fluent
86
85
  value
87
86
  else
88
87
  case type
89
- when :string then value.to_s.force_encoding(Encoding::UTF_8)
88
+ when :string then value.to_s
90
89
  when :integer then value.to_i
91
90
  when :float then value.to_f
92
91
  when :size then Config.size_value(value)
@@ -134,14 +133,4 @@ module Fluent
134
133
  end
135
134
  }
136
135
  end
137
-
138
- Configurable.register_type(:string, Config::STRING_TYPE)
139
- Configurable.register_type(:enum, Config::ENUM_TYPE)
140
- Configurable.register_type(:integer, Config::INTEGER_TYPE)
141
- Configurable.register_type(:float, Config::FLOAT_TYPE)
142
- Configurable.register_type(:size, Config::SIZE_TYPE)
143
- Configurable.register_type(:bool, Config::BOOL_TYPE)
144
- Configurable.register_type(:time, Config::TIME_TYPE)
145
- Configurable.register_type(:hash, Config::HASH_TYPE)
146
- Configurable.register_type(:array, Config::ARRAY_TYPE)
147
136
  end
@@ -148,9 +148,7 @@ module Fluent
148
148
 
149
149
  def eval_include(attrs, elems, uri)
150
150
  u = URI.parse(uri)
151
- if u.scheme == 'file' || (!u.scheme.nil? && u.scheme.length == 1) || u.path == uri # file path
152
- # When the Windows absolute path then u.scheme.length == 1
153
- # e.g. C:
151
+ if u.scheme == 'file' || u.path == uri # file path
154
152
  path = u.path
155
153
  if path[0] != ?/
156
154
  pattern = File.expand_path("#{@include_basepath}/#{path}")
@@ -19,7 +19,7 @@ require 'fluent/config/section'
19
19
  require 'fluent/config/error'
20
20
  require 'fluent/registry'
21
21
  require 'fluent/plugin'
22
- require 'fluent/mixin'
22
+ require 'fluent/config/types'
23
23
 
24
24
  module Fluent
25
25
  module Configurable
@@ -28,19 +28,22 @@ module Fluent
28
28
  end
29
29
 
30
30
  def initialize
31
+ super
31
32
  # to simulate implicit 'attr_accessor' by config_param / config_section and its value by config_set_default
32
33
  proxy = self.class.merged_configure_proxy
33
34
  proxy.params.keys.each do |name|
35
+ next if name.to_s.start_with?('@')
34
36
  if proxy.defaults.has_key?(name)
35
37
  instance_variable_set("@#{name}".to_sym, proxy.defaults[name])
36
38
  end
37
39
  end
38
40
  proxy.sections.keys.each do |name|
41
+ next if name.to_s.start_with?('@')
39
42
  subproxy = proxy.sections[name]
40
43
  if subproxy.multi?
41
- instance_variable_set("@#{subproxy.param_name}".to_sym, [])
44
+ instance_variable_set("@#{subproxy.variable_name}".to_sym, [])
42
45
  else
43
- instance_variable_set("@#{subproxy.param_name}".to_sym, nil)
46
+ instance_variable_set("@#{subproxy.variable_name}".to_sym, nil)
44
47
  end
45
48
  end
46
49
  end
@@ -48,18 +51,27 @@ module Fluent
48
51
  def configure(conf)
49
52
  @config = conf
50
53
 
51
- logger = self.respond_to?(:log) ? log : $log
54
+ logger = self.respond_to?(:log) ? log : (defined?($log) ? $log : nil)
52
55
  proxy = self.class.merged_configure_proxy
53
56
  conf.corresponding_proxies << proxy
54
57
 
58
+ if self.respond_to?(:owner) && self.owner
59
+ owner_proxy = owner.class.merged_configure_proxy
60
+ if proxy.configured_in_section
61
+ owner_proxy = owner_proxy.sections[proxy.configured_in_section]
62
+ end
63
+ proxy.overwrite_defaults(owner_proxy) if owner_proxy
64
+ end
65
+
55
66
  # In the nested section, can't get plugin class through proxies so get plugin class here
56
- plugin_class = Fluent::Plugin.lookup_name_from_class(proxy.name.to_s)
67
+ plugin_class = Fluent::Plugin.lookup_type_from_class(proxy.name.to_s)
57
68
  root = Fluent::Config::SectionGenerator.generate(proxy, conf, logger, plugin_class)
58
69
  @config_root_section = root
59
70
 
60
71
  root.instance_eval{ @params.keys }.each do |param_name|
72
+ next if param_name.to_s.start_with?('@')
61
73
  varname = "@#{param_name}".to_sym
62
- if (! root[param_name].nil?) || instance_variable_get(varname).nil?
74
+ if (! root[param_name].nil?) || (instance_variable_defined?(varname) && instance_variable_get(varname).nil?)
63
75
  instance_variable_set(varname, root[param_name])
64
76
  end
65
77
  end
@@ -82,6 +94,20 @@ module Fluent
82
94
  CONFIG_TYPE_REGISTRY.lookup(type)
83
95
  end
84
96
 
97
+ {
98
+ string: Config::STRING_TYPE,
99
+ enum: Config::ENUM_TYPE,
100
+ integer: Config::INTEGER_TYPE,
101
+ float: Config::FLOAT_TYPE,
102
+ size: Config::SIZE_TYPE,
103
+ bool: Config::BOOL_TYPE,
104
+ time: Config::TIME_TYPE,
105
+ hash: Config::HASH_TYPE,
106
+ array: Config::ARRAY_TYPE,
107
+ }.each do |name, type|
108
+ register_type(name, type)
109
+ end
110
+
85
111
  module ClassMethods
86
112
  def configure_proxy_map
87
113
  map = {}
@@ -92,15 +118,21 @@ module Fluent
92
118
  def configure_proxy(mod_name)
93
119
  map = configure_proxy_map
94
120
  unless map[mod_name]
95
- proxy = Fluent::Config::ConfigureProxy.new(mod_name, required: true, multi: false)
121
+ type_lookup = ->(type) { Fluent::Configurable.lookup_type(type) }
122
+ proxy = Fluent::Config::ConfigureProxy.new(mod_name, required: true, multi: false, type_lookup: type_lookup)
96
123
  map[mod_name] = proxy
97
124
  end
98
125
  map[mod_name]
99
126
  end
100
127
 
101
- def config_param(name, *args, &block)
102
- configure_proxy(self.name).config_param(name, *args, &block)
103
- attr_accessor name
128
+ def configured_in(section_name)
129
+ configure_proxy(self.name).configured_in(section_name)
130
+ end
131
+
132
+ def config_param(name, type = nil, **kwargs, &block)
133
+ configure_proxy(self.name).config_param(name, type, **kwargs, &block)
134
+ # reserved names '@foo' are invalid as attr_accessor name
135
+ attr_accessor(name) unless kwargs[:skip_accessor] || Fluent::Config::Element::RESERVED_PARAMETERS.include?(name.to_s)
104
136
  end
105
137
 
106
138
  def config_set_default(name, defval)
@@ -111,9 +143,12 @@ module Fluent
111
143
  configure_proxy(self.name).config_set_desc(name, desc)
112
144
  end
113
145
 
114
- def config_section(name, *args, &block)
115
- configure_proxy(self.name).config_section(name, *args, &block)
116
- attr_accessor configure_proxy(self.name).sections[name].param_name
146
+ def config_section(name, **kwargs, &block)
147
+ configure_proxy(self.name).config_section(name, **kwargs, &block)
148
+ variable_name = configure_proxy(self.name).sections[name].variable_name
149
+ unless self.respond_to?(variable_name)
150
+ attr_accessor variable_name
151
+ end
117
152
  end
118
153
 
119
154
  def desc(description)
@@ -137,7 +172,4 @@ module Fluent
137
172
  end
138
173
  end
139
174
  end
140
-
141
- # load default types
142
- require 'fluent/config/types'
143
175
  end