fluentd 0.10.57 → 0.10.58

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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -0
  3. data/ChangeLog +18 -0
  4. data/fluent.conf +26 -16
  5. data/fluentd.gemspec +1 -1
  6. data/lib/fluent/config.rb +1 -8
  7. data/lib/fluent/config/basic_parser.rb +1 -0
  8. data/lib/fluent/config/configure_proxy.rb +7 -7
  9. data/lib/fluent/config/types.rb +1 -0
  10. data/lib/fluent/config/v1_parser.rb +2 -1
  11. data/lib/fluent/engine.rb +0 -26
  12. data/lib/fluent/env.rb +1 -0
  13. data/lib/fluent/formatter.rb +96 -26
  14. data/lib/fluent/input.rb +4 -0
  15. data/lib/fluent/output.rb +7 -2
  16. data/lib/fluent/parser.rb +82 -88
  17. data/lib/fluent/plugin.rb +18 -0
  18. data/lib/fluent/plugin/buf_file.rb +3 -3
  19. data/lib/fluent/plugin/in_dummy.rb +103 -0
  20. data/lib/fluent/plugin/in_exec.rb +1 -1
  21. data/lib/fluent/plugin/in_forward.rb +3 -3
  22. data/lib/fluent/plugin/in_gc_stat.rb +1 -1
  23. data/lib/fluent/plugin/in_http.rb +49 -17
  24. data/lib/fluent/plugin/in_monitor_agent.rb +41 -10
  25. data/lib/fluent/plugin/in_object_space.rb +1 -1
  26. data/lib/fluent/plugin/in_status.rb +1 -1
  27. data/lib/fluent/plugin/in_stream.rb +3 -3
  28. data/lib/fluent/plugin/in_syslog.rb +5 -5
  29. data/lib/fluent/plugin/in_tail.rb +6 -6
  30. data/lib/fluent/plugin/out_copy.rb +1 -1
  31. data/lib/fluent/plugin/out_exec_filter.rb +1 -1
  32. data/lib/fluent/plugin/out_file.rb +3 -3
  33. data/lib/fluent/plugin/out_roundrobin.rb +1 -1
  34. data/lib/fluent/plugin/socket_util.rb +2 -2
  35. data/lib/fluent/supervisor.rb +21 -24
  36. data/lib/fluent/test/base.rb +14 -0
  37. data/lib/fluent/test/output_test.rb +7 -1
  38. data/lib/fluent/version.rb +1 -1
  39. data/test/config/test_config_parser.rb +6 -2
  40. data/test/config/test_configurable.rb +1 -1
  41. data/test/config/test_configure_proxy.rb +1 -1
  42. data/test/config/test_dsl.rb +1 -1
  43. data/test/config/test_literal_parser.rb +2 -2
  44. data/test/config/test_section.rb +1 -1
  45. data/test/config/test_system_config.rb +65 -15
  46. data/test/config/test_types.rb +63 -0
  47. data/test/plugin/test_in_dummy.rb +95 -0
  48. data/test/plugin/test_in_exec.rb +1 -1
  49. data/test/plugin/test_in_forward.rb +1 -2
  50. data/test/plugin/test_in_gc_stat.rb +1 -1
  51. data/test/plugin/test_in_http.rb +77 -2
  52. data/test/plugin/test_in_object_space.rb +1 -1
  53. data/test/plugin/test_in_status.rb +1 -1
  54. data/test/plugin/test_in_stream.rb +1 -2
  55. data/test/plugin/test_in_syslog.rb +1 -2
  56. data/test/plugin/test_in_tail.rb +1 -1
  57. data/test/plugin/test_in_tcp.rb +1 -2
  58. data/test/plugin/test_in_udp.rb +1 -2
  59. data/test/plugin/test_out_copy.rb +12 -1
  60. data/test/plugin/test_out_exec.rb +1 -1
  61. data/test/plugin/test_out_exec_filter.rb +1 -1
  62. data/test/plugin/test_out_file.rb +61 -7
  63. data/test/plugin/test_out_forward.rb +1 -2
  64. data/test/plugin/test_out_roundrobin.rb +12 -1
  65. data/test/plugin/test_out_stdout.rb +1 -1
  66. data/test/plugin/test_out_stream.rb +1 -2
  67. data/test/scripts/fluent/plugin/formatter_known.rb +4 -1
  68. data/{lib → test/scripts}/fluent/plugin/out_test.rb +0 -0
  69. data/test/scripts/fluent/plugin/parser_known.rb +2 -1
  70. data/test/test_config.rb +1 -1
  71. data/test/test_configdsl.rb +1 -2
  72. data/test/test_formatter.rb +172 -3
  73. data/test/test_input.rb +21 -0
  74. data/test/test_match.rb +1 -2
  75. data/test/test_mixin.rb +1 -1
  76. data/test/test_output.rb +25 -1
  77. data/test/test_parser.rb +124 -78
  78. metadata +12 -4
@@ -84,9 +84,9 @@ module Fluent
84
84
  def configure(conf)
85
85
  super
86
86
 
87
- parser = TextParser.new
88
- if parser.configure(conf, false)
89
- @parser = parser
87
+ if conf.has_key?('format')
88
+ @parser = Plugin.new_parser(conf['format'])
89
+ @parser.configure(conf)
90
90
  else
91
91
  conf['with_priority'] = true
92
92
  @parser = TextParser::SyslogParser.new
@@ -157,7 +157,7 @@ module Fluent
157
157
  end
158
158
 
159
159
  def receive_data(data, addr)
160
- @parser.call(data) { |time, record|
160
+ @parser.parse(data) { |time, record|
161
161
  unless time && record
162
162
  log.warn "invalid syslog message", :data => data
163
163
  return
@@ -192,7 +192,7 @@ module Fluent
192
192
 
193
193
  tag = "#{@tag}.#{facility}.#{priority}"
194
194
 
195
- Engine.emit(tag, time, record)
195
+ router.emit(tag, time, record)
196
196
  rescue => e
197
197
  log.error "syslog failed to emit", :error => e.to_s, :error_class => e.class.to_s, :tag => tag, :record => Yajl.dump(record)
198
198
  end
@@ -59,7 +59,7 @@ module Fluent
59
59
  end
60
60
 
61
61
  def configure_parser(conf)
62
- @parser = TextParser.new
62
+ @parser = Plugin.new_parser(conf['format'])
63
63
  @parser.configure(conf)
64
64
  end
65
65
 
@@ -200,7 +200,7 @@ module Fluent
200
200
  else
201
201
  @tag
202
202
  end
203
- Engine.emit(tag, time, record)
203
+ router.emit(tag, time, record)
204
204
  else
205
205
  log.warn "got incomplete line at shutdown from #{tw.path}: #{lb.inspect}"
206
206
  end
@@ -224,7 +224,7 @@ module Fluent
224
224
  @tag
225
225
  end
226
226
  begin
227
- Engine.emit_stream(tag, es)
227
+ router.emit_stream(tag, es)
228
228
  rescue
229
229
  # ignore errors. Engine shows logs and backtraces.
230
230
  end
@@ -258,9 +258,9 @@ module Fluent
258
258
  def parse_multilines(lines, tail_watcher)
259
259
  lb = tail_watcher.line_buffer
260
260
  es = MultiEventStream.new
261
- if @parser.parser.has_firstline?
261
+ if @parser.has_firstline?
262
262
  lines.each { |line|
263
- if @parser.parser.firstline?(line)
263
+ if @parser.firstline?(line)
264
264
  if lb
265
265
  convert_line_to_event(lb, es)
266
266
  end
@@ -790,7 +790,7 @@ module Fluent
790
790
 
791
791
  unless es.empty?
792
792
  begin
793
- Engine.emit_stream(@tag, es)
793
+ router.emit_stream(@tag, es)
794
794
  rescue
795
795
  # ignore errors. Engine shows logs and backtraces.
796
796
  end
@@ -33,7 +33,7 @@ module Fluent
33
33
  conf.elements.select {|e|
34
34
  e.name == 'store'
35
35
  }.each {|e|
36
- type = e['type']
36
+ type = e['@type'] || e['type']
37
37
  unless type
38
38
  raise ConfigError, "Missing 'type' parameter on <store> directive"
39
39
  end
@@ -353,7 +353,7 @@ module Fluent
353
353
  tag = @tag
354
354
  end
355
355
 
356
- Engine.emit(tag, time, record)
356
+ router.emit(tag, time, record)
357
357
 
358
358
  rescue
359
359
  if @suppress_error_log_interval == 0 || Time.now.to_i > @next_log_time
@@ -62,8 +62,8 @@ module Fluent
62
62
 
63
63
  super
64
64
 
65
- conf['format'] = @format
66
- @formatter = TextFormatter.create(conf)
65
+ @formatter = Plugin.new_formatter(@format)
66
+ @formatter.configure(conf)
67
67
 
68
68
  @buffer.symlink_path = @symlink_path if @symlink_path
69
69
  end
@@ -74,7 +74,7 @@ module Fluent
74
74
 
75
75
  def write(chunk)
76
76
  path = generate_path(chunk)
77
- FileUtils.mkdir_p File.dirname(path)
77
+ FileUtils.mkdir_p File.dirname(path), :mode => DEFAULT_DIR_PERMISSION
78
78
 
79
79
  case @compress
80
80
  when nil
@@ -35,7 +35,7 @@ module Fluent
35
35
  conf.elements.select {|e|
36
36
  e.name == 'store'
37
37
  }.each {|e|
38
- type = e['type']
38
+ type = e['@type'] || e['type']
39
39
  unless type
40
40
  raise ConfigError, "Missing 'type' parameter on <store> directive"
41
41
  end
@@ -87,7 +87,7 @@ module Fluent
87
87
  def configure(conf)
88
88
  super
89
89
 
90
- @parser = TextParser.new
90
+ @parser = Plugin.new_parser(@format)
91
91
  @parser.configure(conf)
92
92
  end
93
93
 
@@ -130,7 +130,7 @@ module Fluent
130
130
  end
131
131
 
132
132
  record[@source_host_key] = addr[3] if @source_host_key
133
- Engine.emit(@tag, time, record)
133
+ router.emit(@tag, time, record)
134
134
  }
135
135
  rescue => e
136
136
  log.error msg.dump, :error => e, :error_class => e.class, :host => addr[3]
@@ -73,6 +73,11 @@ module Fluent
73
73
  end
74
74
  self
75
75
  end
76
+
77
+ def level=(level)
78
+ @level = level
79
+ $log.level = level
80
+ end
76
81
  end
77
82
 
78
83
  def self.default_options
@@ -107,8 +112,6 @@ module Fluent
107
112
  @chgroup = opt[:chgroup]
108
113
  @chuser = opt[:chuser]
109
114
 
110
- apply_system_config(opt)
111
-
112
115
  @log_level = opt[:log_level]
113
116
  @suppress_interval = opt[:suppress_interval]
114
117
  @suppress_config_dump = opt[:suppress_config_dump]
@@ -122,6 +125,8 @@ module Fluent
122
125
 
123
126
  def start
124
127
  @log.init
128
+ read_config
129
+ apply_system_config
125
130
 
126
131
  dry_run if @dry_run
127
132
  start_daemonize if @daemonize
@@ -129,7 +134,6 @@ module Fluent
129
134
  install_supervisor_signal_handlers
130
135
  until @finished
131
136
  supervise do
132
- read_config
133
137
  change_privilege
134
138
  init_engine
135
139
  install_main_process_signal_handlers
@@ -143,7 +147,6 @@ module Fluent
143
147
  else
144
148
  $log.info "starting fluentd-#{Fluent::VERSION} without supervision"
145
149
  main_process do
146
- read_config
147
150
  change_privilege
148
151
  init_engine
149
152
  install_main_process_signal_handlers
@@ -169,7 +172,6 @@ module Fluent
169
172
  def dry_run
170
173
  $log.info "starting fluentd-#{Fluent::VERSION} as dry run mode"
171
174
 
172
- read_config
173
175
  change_privilege
174
176
  init_engine
175
177
  install_main_process_signal_handlers
@@ -347,6 +349,7 @@ module Fluent
347
349
  elsif @inline_config
348
350
  @config_data << "\n" << @inline_config.gsub("\\n","\n")
349
351
  end
352
+ @conf = Fluent::Config.parse(@config_data, @config_fname, @config_basedir, @use_v1_config)
350
353
  end
351
354
 
352
355
  class SystemConfig
@@ -365,37 +368,31 @@ module Fluent
365
368
  configure(conf)
366
369
  end
367
370
 
368
- def to_opt
369
- opt = {}
370
- opt[:log_level] = @log_level unless @log_level.nil?
371
- opt[:suppress_interval] = @emit_error_log_interval unless @emit_error_log_interval.nil?
372
- opt[:suppress_config_dump] = @suppress_config_dump unless @suppress_config_dump.nil?
373
- opt[:suppress_repeated_stacktrace] = @suppress_repeated_stacktrace unless @suppress_repeated_stacktrace.nil?
374
- opt[:without_source] = @without_source unless @without_source.nil?
375
- opt
371
+ def apply(supervisor)
372
+ system = self
373
+ supervisor.instance_eval {
374
+ @log.level = @log_level = system.log_level unless system.log_level.nil?
375
+ @suppress_interval = system.emit_error_log_interval unless system.emit_error_log_interval.nil?
376
+ @suppress_config_dump = system.suppress_config_dump unless system.suppress_config_dump.nil?
377
+ @suppress_repeated_stacktrace = system.suppress_repeated_stacktrace unless system.suppress_repeated_stacktrace.nil?
378
+ @without_source = system.without_source unless system.without_source.nil?
379
+ }
376
380
  end
377
381
  end
378
382
 
379
383
  # TODO: this method should be moved to SystemConfig class method
380
- def apply_system_config(opt)
381
- # Create NULL file to avoid $log uninitialized problem before call @log.init
382
- file = File.open(File::NULL)
383
- $log = Fluent::Log.new(file, Log::LEVEL_INFO)
384
- read_config
385
- systems = Fluent::Config.parse(@config_data, @config_fname, @config_basedir, @use_v1_config).elements.select { |e|
384
+ def apply_system_config
385
+ systems = @conf.elements.select { |e|
386
386
  e.name == 'system'
387
387
  }
388
388
  return if systems.empty?
389
389
  raise ConfigError, "<system> is duplicated. <system> should be only one" if systems.size > 1
390
390
 
391
- opt.merge!(SystemConfig.new(systems.first).to_opt)
392
- ensure
393
- file.close
391
+ SystemConfig.new(systems.first).apply(self)
394
392
  end
395
393
 
396
394
  def run_configure
397
- conf = Fluent::Config.parse(@config_data, @config_fname, @config_basedir, @use_v1_config)
398
- Fluent::Engine.run_configure(conf)
395
+ Fluent::Engine.run_configure(@conf)
399
396
  end
400
397
 
401
398
  def change_privilege
@@ -17,6 +17,20 @@
17
17
  #
18
18
  module Fluent
19
19
  module Test
20
+ def self.setup
21
+ Fluent.__send__(:remove_const, :Engine)
22
+ engine = Fluent.const_set(:Engine, EngineClass.new).init
23
+
24
+ engine.define_singleton_method(:now=) {|n|
25
+ @now = n.to_i
26
+ }
27
+ engine.define_singleton_method(:now) {
28
+ @now || super()
29
+ }
30
+
31
+ nil
32
+ end
33
+
20
34
  class TestDriver
21
35
  include ::Test::Unit::Assertions
22
36
 
@@ -78,7 +78,13 @@ module Fluent
78
78
  assert_equal(@expected_buffer, buffer)
79
79
  end
80
80
 
81
- chunk = MemoryBufferChunk.new('', buffer)
81
+ key = ''
82
+ if @instance.respond_to?(:time_slicer)
83
+ # this block is only for test_out_file
84
+ time, record = @entries.first
85
+ key = @instance.time_slicer.call(time)
86
+ end
87
+ chunk = MemoryBufferChunk.new(key, buffer)
82
88
  result = @instance.write(chunk)
83
89
  }
84
90
  result
@@ -1,5 +1,5 @@
1
1
  module Fluent
2
2
 
3
- VERSION = '0.10.57'
3
+ VERSION = '0.10.58'
4
4
 
5
5
  end
@@ -1,6 +1,6 @@
1
- require 'helper'
1
+ require_relative '../helper'
2
+ require_relative "assertions"
2
3
  require "json"
3
- require "config/assertions"
4
4
  require "fluent/config/error"
5
5
  require "fluent/config/basic_parser"
6
6
  require "fluent/config/literal_parser"
@@ -229,6 +229,10 @@ module Fluent::Config
229
229
  "ignores spacing around element argument" => [root(e("test", "a")), %[
230
230
  <test a >
231
231
  </test>
232
+ ]],
233
+ "accepts spacing inside element argument (for multiple tags)" => [root(e("test", "a.** b.**")), %[
234
+ <test a.** b.** >
235
+ </test>
232
236
  ]])
233
237
  def test_parse_element(data)
234
238
  expected, target = data
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative '../helper'
2
2
  require 'fluent/configurable'
3
3
  require 'fluent/config/element'
4
4
  require 'fluent/config/section'
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative '../helper'
2
2
  require 'fluent/config/configure_proxy'
3
3
 
4
4
  module Fluent::Config
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative '../helper'
2
2
  require 'fluent/config/element'
3
3
  require "fluent/config/dsl"
4
4
 
@@ -1,5 +1,5 @@
1
- require "helper"
2
- require 'config/assertions'
1
+ require_relative "../helper"
2
+ require_relative 'assertions'
3
3
  require "fluent/config/error"
4
4
  require "fluent/config/literal_parser"
5
5
  require "fluent/config/v1_parser"
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative '../helper'
2
2
  require 'fluent/config/section'
3
3
 
4
4
  module Fluent::Config
@@ -1,49 +1,99 @@
1
- require 'helper'
1
+ require_relative '../helper'
2
2
  require 'fluent/configurable'
3
3
  require 'fluent/config/element'
4
4
  require 'fluent/config/section'
5
5
  require 'fluent/supervisor'
6
6
 
7
7
  module Fluent::Config
8
+ class FakeLoggerInitializer
9
+ attr_accessor :level
10
+ def initalize
11
+ @level = nil
12
+ end
13
+ end
14
+
15
+ class FakeSupervisor
16
+ def initialize
17
+ @log = FakeLoggerInitializer.new
18
+ @log_level = nil
19
+ @suppress_interval = nil
20
+ @suppress_config_dump = nil
21
+ @suppress_repeated_stacktrace = nil
22
+ @without_source = nil
23
+ end
24
+ end
25
+
8
26
  class TestSystemConfig < ::Test::Unit::TestCase
27
+
9
28
  def parse_text(text)
10
29
  basepath = File.expand_path(File.dirname(__FILE__) + '/../../')
11
30
  Fluent::Config.parse(text, '(test)', basepath, true).elements.find { |e| e.name == 'system' }
12
31
  end
13
32
 
14
33
  test 'should not override default configurations when no parameters' do
15
- conf = parse_text(<<EOS)
16
- <system>
17
- </system>
18
- EOS
34
+ conf = parse_text(<<-EOS)
35
+ <system>
36
+ </system>
37
+ EOS
38
+ s = FakeSupervisor.new
19
39
  sc = Fluent::Supervisor::SystemConfig.new(conf)
40
+ sc.apply(s)
20
41
  assert_nil(sc.log_level)
21
42
  assert_nil(sc.suppress_repeated_stacktrace)
22
43
  assert_nil(sc.emit_error_log_interval)
23
44
  assert_nil(sc.suppress_config_dump)
24
45
  assert_nil(sc.without_source)
25
- assert_empty(sc.to_opt)
46
+ assert_nil(s.instance_variable_get(:@log_level))
47
+ assert_nil(s.instance_variable_get(:@suppress_repeated_stacktrace))
48
+ assert_nil(s.instance_variable_get(:@emit_error_log_interval))
49
+ assert_nil(s.instance_variable_get(:@suppress_config_dump))
50
+ assert_nil(s.instance_variable_get(:@without_source))
26
51
  end
27
52
 
28
- {'log_level' => 'error', 'suppress_repeated_stacktrace' => true, 'emit_error_log_interval' => 60, 'suppress_config_dump' => true, 'without_source' => true}.each { |k, v|
53
+ {'log_level' => 'error',
54
+ 'suppress_repeated_stacktrace' => true,
55
+ 'emit_error_log_interval' => 60,
56
+ 'suppress_config_dump' => true,
57
+ 'without_source' => true,
58
+ }.each { |k, v|
29
59
  test "accepts #{k} parameter" do
30
- conf = parse_text(<<EOS)
31
- <system>
32
- #{k} #{v}
33
- </system>
34
- EOS
60
+ conf = parse_text(<<-EOS)
61
+ <system>
62
+ #{k} #{v}
63
+ </system>
64
+ EOS
65
+ s = FakeSupervisor.new
35
66
  sc = Fluent::Supervisor::SystemConfig.new(conf)
67
+ sc.apply(s)
36
68
  assert_not_nil(sc.instance_variable_get("@#{k}"))
37
- key = (k == 'emit_error_log_interval' ? :suppress_interval : k.to_sym)
38
- assert_include(sc.to_opt, key)
69
+ key = (k == 'emit_error_log_interval' ? 'suppress_interval' : k)
70
+ assert_not_nil(s.instance_variable_get("@#{key}"))
39
71
  end
40
72
  }
41
73
 
42
74
  {'foo' => 'bar', 'hoge' => 'fuga'}.each { |k, v|
43
75
  test "should not affect settable parameters with unknown #{k} parameter" do
76
+ s = FakeSupervisor.new
44
77
  sc = Fluent::Supervisor::SystemConfig.new({k => v})
45
- assert_empty(sc.to_opt)
78
+ sc.apply(s)
79
+ assert_nil(s.instance_variable_get(:@log_level))
80
+ assert_nil(s.instance_variable_get(:@suppress_repeated_stacktrace))
81
+ assert_nil(s.instance_variable_get(:@emit_error_log_interval))
82
+ assert_nil(s.instance_variable_get(:@suppress_config_dump))
83
+ assert_nil(s.instance_variable_get(:@without_source))
46
84
  end
47
85
  }
86
+
87
+ test 'log_level' do
88
+ conf = parse_text(<<-EOS)
89
+ <system>
90
+ log_level warn
91
+ </system>
92
+ EOS
93
+ s = FakeSupervisor.new
94
+ sc = Fluent::Supervisor::SystemConfig.new(conf)
95
+ sc.apply(s)
96
+ assert_equal(Fluent::Log::LEVEL_WARN, s.instance_variable_get("@log").level)
97
+ end
48
98
  end
49
99
  end