fluentd 0.12.17 → 0.12.18

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/ChangeLog +25 -0
  4. data/lib/fluent/buffer.rb +2 -0
  5. data/lib/fluent/config/configure_proxy.rb +2 -2
  6. data/lib/fluent/configurable.rb +2 -2
  7. data/lib/fluent/log.rb +1 -0
  8. data/lib/fluent/plugin/buf_file.rb +2 -0
  9. data/lib/fluent/plugin/buf_memory.rb +1 -0
  10. data/lib/fluent/plugin/exec_util.rb +21 -0
  11. data/lib/fluent/plugin/filter_record_transformer.rb +6 -0
  12. data/lib/fluent/plugin/filter_stdout.rb +1 -0
  13. data/lib/fluent/plugin/in_exec.rb +33 -22
  14. data/lib/fluent/plugin/in_forward.rb +5 -0
  15. data/lib/fluent/plugin/in_http.rb +9 -0
  16. data/lib/fluent/plugin/in_stream.rb +2 -0
  17. data/lib/fluent/plugin/in_syslog.rb +6 -0
  18. data/lib/fluent/plugin/in_tail.rb +16 -1
  19. data/lib/fluent/plugin/in_tcp.rb +1 -0
  20. data/lib/fluent/plugin/out_copy.rb +1 -0
  21. data/lib/fluent/plugin/out_exec.rb +6 -0
  22. data/lib/fluent/plugin/out_exec_filter.rb +15 -0
  23. data/lib/fluent/plugin/out_file.rb +5 -0
  24. data/lib/fluent/plugin/out_forward.rb +15 -0
  25. data/lib/fluent/plugin/out_stdout.rb +1 -0
  26. data/lib/fluent/plugin/socket_util.rb +5 -0
  27. data/lib/fluent/process.rb +19 -9
  28. data/lib/fluent/supervisor.rb +19 -1
  29. data/lib/fluent/test.rb +2 -0
  30. data/lib/fluent/test/formatter_test.rb +60 -0
  31. data/lib/fluent/test/parser_test.rb +66 -0
  32. data/lib/fluent/version.rb +1 -1
  33. data/test/config/test_configure_proxy.rb +1 -10
  34. data/test/plugin/test_in_exec.rb +31 -3
  35. data/test/plugin/test_out_forward.rb +6 -0
  36. data/test/scripts/exec_script.rb +6 -0
  37. data/test/test_formatter.rb +35 -2
  38. data/test/test_parser.rb +43 -19
  39. data/test/test_process.rb +47 -0
  40. metadata +7 -3
@@ -25,33 +25,44 @@ module Fluent
25
25
  require 'fluent/timezone'
26
26
  end
27
27
 
28
+ desc 'The command (program) to execute.'
28
29
  config_param :command, :string
29
30
 
30
31
  config_param :remove_prefix, :string, :default => nil
31
32
  config_param :add_prefix, :string, :default => nil
32
33
 
34
+ desc "The format used to map the incoming event to the program input.(#{ExecUtil::SUPPORTED_FORMAT.keys.join(',')})"
33
35
  config_param :in_format, :default => :tsv do |val|
34
36
  f = ExecUtil::SUPPORTED_FORMAT[val]
35
37
  raise ConfigError, "Unsupported in_format '#{val}'" unless f
36
38
  f
37
39
  end
40
+ desc 'Specify comma-separated values for tsv format.'
38
41
  config_param :in_keys, :default => [] do |val|
39
42
  val.split(',')
40
43
  end
44
+ desc 'The name of the key to use as the event tag.'
41
45
  config_param :in_tag_key, :default => nil
46
+ desc 'The name of the key to use as the event time.'
42
47
  config_param :in_time_key, :default => nil
48
+ desc 'The format for event time used when the in_time_key parameter is specified.(Defauls is UNIX time)'
43
49
  config_param :in_time_format, :default => nil
44
50
 
51
+ desc "The format used to process the program output.(#{ExecUtil::SUPPORTED_FORMAT.keys.join(',')})"
45
52
  config_param :out_format, :default => :tsv do |val|
46
53
  f = ExecUtil::SUPPORTED_FORMAT[val]
47
54
  raise ConfigError, "Unsupported out_format '#{val}'" unless f
48
55
  f
49
56
  end
57
+ desc 'Specify comma-separated values for tsv format.'
50
58
  config_param :out_keys, :default => [] do |val| # for tsv format
51
59
  val.split(',')
52
60
  end
61
+ desc 'The name of the key to use as the event tag.'
53
62
  config_param :out_tag_key, :default => nil
63
+ desc 'The name of the key to use as the event time.'
54
64
  config_param :out_time_key, :default => nil
65
+ desc 'The format for event time used when the in_time_key parameter is specified.(Defauls is UNIX time)'
55
66
  config_param :out_time_format, :default => nil
56
67
 
57
68
  config_param :tag, :string, :default => nil
@@ -59,10 +70,14 @@ module Fluent
59
70
  config_param :time_key, :string, :default => nil
60
71
  config_param :time_format, :string, :default => nil
61
72
 
73
+ desc 'If true, use localtime with in_time_format.'
62
74
  config_param :localtime, :bool, :default => true
75
+ desc 'If true, use timezone with in_time_format.'
63
76
  config_param :timezone, :string, :default => nil
77
+ desc 'The number of spawned process for command.'
64
78
  config_param :num_children, :integer, :default => 1
65
79
 
80
+ desc 'Respawn command when command exit.'
66
81
  # nil, 'none' or 0: no respawn, 'inf' or -1: infinite times, positive integer: try to respawn specified times only
67
82
  config_param :child_respawn, :string, :default => nil
68
83
 
@@ -23,9 +23,13 @@ module Fluent
23
23
  'gzip' => :gz,
24
24
  }
25
25
 
26
+ desc "The Path of the file."
26
27
  config_param :path, :string
28
+ desc "The format of the file content. The default is out_file."
27
29
  config_param :format, :string, :default => 'out_file'
30
+ desc "The flushed chunk is appended to existence file or not."
28
31
  config_param :append, :bool, :default => false
32
+ desc "Compress flushed file."
29
33
  config_param :compress, :default => nil do |val|
30
34
  c = SUPPORTED_COMPRESS[val]
31
35
  unless c
@@ -33,6 +37,7 @@ module Fluent
33
37
  end
34
38
  c
35
39
  end
40
+ desc "Create symlink to temporary buffered file when buffer_type is file."
36
41
  config_param :symlink_path, :string, :default => nil
37
42
 
38
43
  def initialize
@@ -36,7 +36,9 @@ module Fluent
36
36
  @nodes = [] #=> [Node]
37
37
  end
38
38
 
39
+ desc 'The timeout time when sending event logs.'
39
40
  config_param :send_timeout, :time, :default => 60
41
+ desc 'The transport protocol to use for heartbeats.(udp,tcp,none)'
40
42
  config_param :heartbeat_type, :default => :udp do |val|
41
43
  case val.downcase
42
44
  when 'tcp'
@@ -49,19 +51,28 @@ module Fluent
49
51
  raise ConfigError, "forward output heartbeat type should be 'tcp', 'udp', or 'none'"
50
52
  end
51
53
  end
54
+ desc 'The interval of the heartbeat packer.'
52
55
  config_param :heartbeat_interval, :time, :default => 1
56
+ desc 'The wait time before accepting a server fault recovery.'
53
57
  config_param :recover_wait, :time, :default => 10
58
+ desc 'The hard timeout used to detect server failure.'
54
59
  config_param :hard_timeout, :time, :default => 60
60
+ desc 'Set TTL to expire DNS cache in seconds.'
55
61
  config_param :expire_dns_cache, :time, :default => nil # 0 means disable cache
62
+ desc 'The threshold parameter used to detect server faults.'
56
63
  config_param :phi_threshold, :integer, :default => 16
64
+ desc 'Use the "Phi accrual failure detector" to detect server failure.'
57
65
  config_param :phi_failure_detector, :bool, :default => true
58
66
 
59
67
  # if any options added that requires extended forward api, fix @extend_internal_protocol
60
68
 
69
+ desc 'Change the protocol to at-least-once.'
61
70
  config_param :require_ack_response, :bool, :default => false # require in_forward to respond with ack
71
+ desc 'This option is used when require_ack_response is true.'
62
72
  config_param :ack_response_timeout, :time, :default => 190 # 0 means do not wait for ack responses
63
73
  # Linux default tcp_syn_retries is 5 (in many environment)
64
74
  # 3 + 6 + 12 + 24 + 48 + 96 -> 189 (sec)
75
+ desc 'Enable client-side DNS round robin.'
65
76
  config_param :dns_round_robin, :bool, :default => false # heartbeat_type 'udp' is not available for this
66
77
 
67
78
  attr_reader :nodes
@@ -129,6 +140,10 @@ module Fluent
129
140
  end
130
141
  log.info "adding forwarding server '#{name}'", :host=>host, :port=>port, :weight=>weight, :plugin_id=>plugin_id
131
142
  }
143
+
144
+ if @nodes.empty?
145
+ raise ConfigError, "forward output plugin requires at least one <server> is required"
146
+ end
132
147
  end
133
148
 
134
149
  def start
@@ -18,6 +18,7 @@ module Fluent
18
18
  class StdoutOutput < Output
19
19
  Plugin.register_output('stdout', self)
20
20
 
21
+ desc 'Output format.(json,hash)'
21
22
  config_param :output_type, :default => 'json'
22
23
 
23
24
  def configure(conf)
@@ -94,10 +94,15 @@ module Fluent
94
94
  require 'fluent/parser'
95
95
  end
96
96
 
97
+ desc 'Tag of output events.'
97
98
  config_param :tag, :string
99
+ desc 'The format of the payload.'
98
100
  config_param :format, :string
101
+ desc 'The port to listen to.'
99
102
  config_param :port, :integer, :default => 5150
103
+ desc 'The bind address to listen to.'
100
104
  config_param :bind, :string, :default => '0.0.0.0'
105
+ desc "The field name of the client's hostname."
101
106
  config_param :source_host_key, :string, :default => nil
102
107
  config_param :blocking_timeout, :time, :default => 0.5
103
108
 
@@ -232,26 +232,36 @@ module Fluent
232
232
  @w = w
233
233
  @interval = interval
234
234
  @buffer = {}
235
+ @mutex = Mutex.new
235
236
  Thread.new(&method(:run))
236
237
  end
237
238
 
238
239
  def emit(tag, es)
239
- if ms = @buffer[tag]
240
- ms << es.to_msgpack_stream
241
- else
242
- @buffer[tag] = es.to_msgpack_stream
240
+ stream = es.to_msgpack_stream
241
+ @mutex.synchronize do
242
+ if @buffer[tag]
243
+ @buffer[tag] << stream
244
+ else
245
+ @buffer[tag] = stream
246
+ end
243
247
  end
244
248
  end
245
249
 
246
250
  def run
247
251
  while true
248
252
  sleep @interval
249
- @buffer.keys.each {|tag|
250
- if ms = @buffer.delete(tag)
251
- [tag, ms].to_msgpack(@w)
252
- #@w.write [tag, ms].to_msgpack
253
+
254
+ pairs = []
255
+ @mutex.synchronize do
256
+ @buffer.keys.each do |tag|
257
+ if ms = @buffer.delete(tag)
258
+ pairs << [tag, ms]
259
+ end
253
260
  end
254
- }
261
+ end
262
+ pairs.each do |pair|
263
+ pair.to_msgpack(@w)
264
+ end
255
265
  end
256
266
  rescue
257
267
  $log.error "error on forwerder thread", :error=>$!.to_s
@@ -111,6 +111,7 @@ module Fluent
111
111
  @chgroup = opt[:chgroup]
112
112
  @chuser = opt[:chuser]
113
113
  @rpc_server = nil
114
+ @process_name = nil
114
115
 
115
116
  @log_level = opt[:log_level]
116
117
  @suppress_interval = opt[:suppress_interval]
@@ -193,7 +194,19 @@ module Fluent
193
194
  $log.info "Show config for #{@show_plugin_config}"
194
195
  name, type = @show_plugin_config.split(":")
195
196
  plugin = Plugin.__send__("new_#{name}", type)
196
- $log.info plugin.class.dump
197
+ dumped_config = "\n"
198
+ level = 0
199
+ plugin.class.ancestors.reverse_each do |plugin_class|
200
+ if plugin_class.respond_to?(:dump)
201
+ $log.on_debug do
202
+ dumped_config << plugin_class.name
203
+ dumped_config << "\n"
204
+ level = 1
205
+ end
206
+ dumped_config << plugin_class.dump(level)
207
+ end
208
+ end
209
+ $log.info dumped_config
197
210
  exit 0
198
211
  rescue => e
199
212
  $log.error "show config failed: #{e}"
@@ -306,6 +319,7 @@ module Fluent
306
319
  def supervise(&block)
307
320
  start_time = Time.now
308
321
 
322
+ Process.setproctitle("supervisor:#{@process_name}") if @process_name
309
323
  $log.info "starting fluentd-#{Fluent::VERSION}"
310
324
  @main_pid = fork do
311
325
  main_process(&block)
@@ -332,6 +346,8 @@ module Fluent
332
346
  end
333
347
 
334
348
  def main_process(&block)
349
+ Process.setproctitle("worker:#{@process_name}") if @process_name
350
+
335
351
  begin
336
352
  block.call
337
353
 
@@ -462,6 +478,7 @@ module Fluent
462
478
  config_param :without_source, :bool, :default => nil
463
479
  config_param :rpc_endpoint, :string, :default => nil
464
480
  config_param :enable_get_dump, :bool, :default => nil
481
+ config_param :process_name, :default => nil
465
482
 
466
483
  def initialize(conf)
467
484
  super()
@@ -478,6 +495,7 @@ module Fluent
478
495
  @without_source = system.without_source unless system.without_source.nil?
479
496
  @rpc_endpoint = system.rpc_endpoint unless system.rpc_endpoint.nil?
480
497
  @enable_get_dump = system.enable_get_dump unless system.enable_get_dump.nil?
498
+ @process_name = system.process_name unless system.process_name.nil?
481
499
  }
482
500
  end
483
501
  end
@@ -20,5 +20,7 @@ require 'fluent/test/base'
20
20
  require 'fluent/test/input_test'
21
21
  require 'fluent/test/output_test'
22
22
  require 'fluent/test/filter_test'
23
+ require 'fluent/test/parser_test'
24
+ require 'fluent/test/formatter_test'
23
25
 
24
26
  $log ||= Fluent::Log.new(Fluent::Test::DummyLogDevice.new)
@@ -0,0 +1,60 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Fluent
18
+ module Test
19
+ class FormatterTestDriver
20
+ def initialize(klass_or_str, proc=nil, &block)
21
+ if klass_or_str.is_a?(Class)
22
+ if block
23
+ # Create new class for test w/ overwritten methods
24
+ # klass.dup is worse because its ancestors does NOT include original class name
25
+ klass_or_str = Class.new(klass_or_str)
26
+ klass_or_str.module_eval(&block)
27
+ end
28
+ @instance = klass_or_str.new
29
+ elsif klass_or_str.is_a?(String)
30
+ @instance = TextFormatter::TEMPLATE_REGISTRY.lookup(klass_or_str).call
31
+ else
32
+ @instance = klass_or_str
33
+ end
34
+ @config = Config.new
35
+ end
36
+
37
+ attr_reader :instance, :config
38
+
39
+ def configure(conf)
40
+ case conf
41
+ when Fluent::Config::Element
42
+ @config = conf
43
+ when String
44
+ io = StringIO.new(conf)
45
+ @config = Config::Parser.parse(io, 'fluent.conf')
46
+ when Hash
47
+ @config = Config::Element.new('ROOT', '', conf, [])
48
+ else
49
+ raise "Unknown type... #{conf}"
50
+ end
51
+ @instance.configure(@config)
52
+ self
53
+ end
54
+
55
+ def format(tag, time, record)
56
+ @instance.format(tag, time, record)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,66 @@
1
+ #
2
+ # Fluentd
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Fluent
18
+ module Test
19
+ class ParserTestDriver
20
+ def initialize(klass_or_str, format=nil, conf={}, &block)
21
+ if klass_or_str.is_a?(Class)
22
+ if block
23
+ # Create new class for test w/ overwritten methods
24
+ # klass.dup is worse because its ancestors does NOT include original class name
25
+ klass_or_str = Class.new(klass_or_str)
26
+ klass_or_str.module_eval(&block)
27
+ end
28
+ case klass_or_str.instance_method(:initialize).arity
29
+ when 0
30
+ @instance = klass_or_str.new
31
+ when -2
32
+ # for RegexpParser
33
+ @instance = klass_or_str.new(format, conf)
34
+ end
35
+ elsif klass_or_str.is_a?(String)
36
+ @instance = TextParser::TEMPLATE_REGISTRY.lookup(klass_or_str).call
37
+ else
38
+ @instance = klass_or_str
39
+ end
40
+ @config = Config.new
41
+ end
42
+
43
+ attr_reader :instance, :config
44
+
45
+ def configure(conf)
46
+ case conf
47
+ when Fluent::Config::Element
48
+ @config = conf
49
+ when String
50
+ io = StringIO.new(conf)
51
+ @config = Config::Parser.parse(io, 'fluent.conf')
52
+ when Hash
53
+ @config = Config::Element.new('ROOT', '', conf, [])
54
+ else
55
+ raise "Unknown type... #{conf}"
56
+ end
57
+ @instance.configure(@config)
58
+ self
59
+ end
60
+
61
+ def parse(text, &block)
62
+ @instance.parse(text, &block)
63
+ end
64
+ end
65
+ end
66
+ end
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '0.12.17'
19
+ VERSION = '0.12.18'
20
20
 
21
21
  end
@@ -138,13 +138,12 @@ module Fluent::Config
138
138
  end
139
139
 
140
140
  test 'empty proxy' do
141
- assert_equal("\n", @proxy.dump)
141
+ assert_equal("", @proxy.dump)
142
142
  end
143
143
 
144
144
  test 'plain proxy w/o default value' do
145
145
  @proxy.config_param(:name, :string)
146
146
  assert_equal(<<CONFIG, @proxy.dump)
147
-
148
147
  name: string: <nil>
149
148
  CONFIG
150
149
  end
@@ -152,7 +151,6 @@ CONFIG
152
151
  test 'plain proxy w/ default value' do
153
152
  @proxy.config_param(:name, :string, default: "name1")
154
153
  assert_equal(<<CONFIG, @proxy.dump)
155
-
156
154
  name: string: <"name1">
157
155
  CONFIG
158
156
  end
@@ -161,7 +159,6 @@ CONFIG
161
159
  @proxy.config_param(:name, :string)
162
160
  @proxy.config_set_default(:name, "name1")
163
161
  assert_equal(<<CONFIG, @proxy.dump)
164
-
165
162
  name: string: <"name1">
166
163
  CONFIG
167
164
  end
@@ -171,7 +168,6 @@ CONFIG
171
168
  config_param(:name, :string, default: "name1")
172
169
  end
173
170
  assert_equal(<<CONFIG, @proxy.dump)
174
-
175
171
  sub
176
172
  name: string: <"name1">
177
173
  CONFIG
@@ -187,7 +183,6 @@ CONFIG
187
183
  end
188
184
  end
189
185
  assert_equal(<<CONFIG, @proxy.dump)
190
-
191
186
  sub
192
187
  name1: string: <"name1">
193
188
  name2: string: <"name2">
@@ -201,7 +196,6 @@ CONFIG
201
196
  test 'single proxy' do
202
197
  @proxy.config_param(:name, :string, desc: "description for name")
203
198
  assert_equal(<<CONFIG, @proxy.dump)
204
-
205
199
  name: string: <nil> # description for name
206
200
  CONFIG
207
201
  end
@@ -210,7 +204,6 @@ CONFIG
210
204
  @proxy.config_param(:name, :string)
211
205
  @proxy.config_set_desc(:name, "description for name")
212
206
  assert_equal(<<CONFIG, @proxy.dump)
213
-
214
207
  name: string: <nil> # description for name
215
208
  CONFIG
216
209
  end
@@ -225,7 +218,6 @@ CONFIG
225
218
  end
226
219
  end
227
220
  assert_equal(<<CONFIG, @proxy.dump)
228
-
229
221
  sub
230
222
  name1: string: <"name1"> # desc1
231
223
  name2: string: <"name2"> # desc2
@@ -247,7 +239,6 @@ CONFIG
247
239
  end
248
240
  end
249
241
  assert_equal(<<CONFIG, @proxy.dump)
250
-
251
242
  sub
252
243
  name1: string: <"name1"> # desc1
253
244
  name2: string: <"name2"> # desc2