fluentd 0.10.40 → 0.10.41

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.

data/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ Release 0.10.41 - 2013/12/05
2
+
3
+ * BufferedOutput: Add 'max_retry_wait' to limit retry interval
4
+ * in_exec/object_space/syslog: Improve emit error message
5
+ * Log: Add --suppress-repeated-stacktrace option to prevent log size explosion
6
+
1
7
  Release 0.10.40 - 2013/11/08
2
8
 
3
9
  * Dump gem version of fluent-plugin-xxx and fluent-mixin-xxx
@@ -1,5 +1,7 @@
1
1
  = Fluentd
2
2
 
3
+ {<img src="https://travis-ci.org/fluent/fluentd.png" />}[https://travis-ci.org/fluent/fluentd]
4
+
3
5
  Fluentd is an event collector system. It is a generalized version of syslogd, which handles JSON objects for its log messages.
4
6
 
5
7
  == Architecture
@@ -36,6 +36,7 @@ opts = {
36
36
  :chuser => nil,
37
37
  :chgroup => nil,
38
38
  :suppress_interval => 0,
39
+ :suppress_repeated_stacktrace => false,
39
40
  }
40
41
 
41
42
  op.on('-s', "--setup [DIR=#{File.dirname(Fluent::DEFAULT_CONFIG_PATH)}]", "install sample configuration file to the directory") {|s|
@@ -86,6 +87,10 @@ op.on('--emit-error-log-interval SECONDS', "suppress interval seconds of emit er
86
87
  opts[:suppress_interval] = s.to_i
87
88
  }
88
89
 
90
+ op.on('--suppress-repeated-stacktrace', "suppress repeated stacktrace", TrueClass) {|b|
91
+ opts[:suppress_repeated_stacktrace] = b
92
+ }
93
+
89
94
  op.on('-v', '--verbose', "increase verbose level (-v: debug, -vv: trace)", TrueClass) {|b|
90
95
  if b
91
96
  opts[:log_level] = [opts[:log_level] - 1, Fluent::Log::LEVEL_TRACE].max
@@ -40,7 +40,7 @@ module Fluent
40
40
 
41
41
  LEVEL_TEXT = %w(trace debug info warn error fatal)
42
42
 
43
- def initialize(out=STDERR, level=LEVEL_TRACE)
43
+ def initialize(out=STDERR, level=LEVEL_TRACE, opts={})
44
44
  @out = out
45
45
  @level = level
46
46
  @debug_mode = false
@@ -50,6 +50,10 @@ module Fluent
50
50
  enable_color out.tty?
51
51
  # TODO: This variable name is unclear so we should change to better name.
52
52
  @threads_exclude_events = []
53
+
54
+ if opts.has_key?(:suppress_repeated_stacktrace)
55
+ @suppress_repeated_stacktrace = opts[:suppress_repeated_stacktrace]
56
+ end
53
57
  end
54
58
 
55
59
  attr_accessor :out
@@ -110,12 +114,7 @@ module Fluent
110
114
  alias TRACE trace
111
115
 
112
116
  def trace_backtrace(backtrace=$!.backtrace)
113
- return if @level > LEVEL_TRACE
114
- time = Time.now
115
- backtrace.each {|msg|
116
- puts [" ", caller_line(time, 4, LEVEL_TRACE), msg].join
117
- }
118
- nil
117
+ dump_stacktrace(backtrace, LEVEL_TRACE)
119
118
  end
120
119
 
121
120
  def on_debug(&block)
@@ -133,12 +132,7 @@ module Fluent
133
132
  alias DEBUG debug
134
133
 
135
134
  def debug_backtrace(backtrace=$!.backtrace)
136
- return if @level > LEVEL_DEBUG
137
- time = Time.now
138
- backtrace.each {|msg|
139
- puts [" ", caller_line(time, 4, LEVEL_DEBUG), msg].join
140
- }
141
- nil
135
+ dump_stacktrace(backtrace, LEVEL_DEBUG)
142
136
  end
143
137
 
144
138
  def on_info(&block)
@@ -156,12 +150,7 @@ module Fluent
156
150
  alias INFO info
157
151
 
158
152
  def info_backtrace(backtrace=$!.backtrace)
159
- return if @level > LEVEL_INFO
160
- time = Time.now
161
- backtrace.each {|msg|
162
- puts [" ", caller_line(time, 4, LEVEL_INFO), msg].join
163
- }
164
- nil
153
+ dump_stacktrace(backtrace, LEVEL_INFO)
165
154
  end
166
155
 
167
156
  def on_warn(&block)
@@ -179,12 +168,7 @@ module Fluent
179
168
  alias WARN warn
180
169
 
181
170
  def warn_backtrace(backtrace=$!.backtrace)
182
- return if @level > LEVEL_WARN
183
- time = Time.now
184
- backtrace.each {|msg|
185
- puts [" ", caller_line(time, 4, LEVEL_WARN), msg].join
186
- }
187
- nil
171
+ dump_stacktrace(backtrace, LEVEL_WARN)
188
172
  end
189
173
 
190
174
  def on_error(&block)
@@ -202,12 +186,7 @@ module Fluent
202
186
  alias ERROR error
203
187
 
204
188
  def error_backtrace(backtrace=$!.backtrace)
205
- return if @level > LEVEL_ERROR
206
- time = Time.now
207
- backtrace.each {|msg|
208
- puts [" ", caller_line(time, 4, LEVEL_ERROR), msg].join
209
- }
210
- nil
189
+ dump_stacktrace(backtrace, LEVEL_ERROR)
211
190
  end
212
191
 
213
192
  def on_fatal(&block)
@@ -225,12 +204,7 @@ module Fluent
225
204
  alias FATAL fatal
226
205
 
227
206
  def fatal_backtrace(backtrace=$!.backtrace)
228
- return if @level > LEVEL_FATAL
229
- time = Time.now
230
- backtrace.each {|msg|
231
- puts [" ", caller_line(time, 4, LEVEL_FATAL), msg].join
232
- }
233
- nil
207
+ dump_stacktrace(backtrace, LEVEL_FATAL)
234
208
  end
235
209
 
236
210
  def puts(msg)
@@ -251,6 +225,23 @@ module Fluent
251
225
  end
252
226
 
253
227
  private
228
+
229
+ def dump_stacktrace(backtrace, level)
230
+ return if @level > level
231
+
232
+ time = Time.now
233
+ if @suppress_repeated_stacktrace && (Thread.current[:last_repeated_stacktrace] == backtrace)
234
+ puts [" ", caller_line(time, 5, level), 'suppressed same stacktrace'].join
235
+ else
236
+ backtrace.each { |msg|
237
+ puts [" ", caller_line(time, 5, level), msg].join
238
+ }
239
+ Thread.current[:last_repeated_stacktrace] = backtrace if @suppress_repeated_stacktrace
240
+ end
241
+
242
+ nil
243
+ end
244
+
254
245
  def event(level, args)
255
246
  time = Time.now
256
247
  message = ''
@@ -282,9 +273,9 @@ module Fluent
282
273
  end
283
274
 
284
275
  def caller_line(time, depth, level)
285
- line = caller(depth+1)[0]
286
276
  log_msg = "#{time.strftime(@time_format)}[#{LEVEL_TEXT[level]}]: "
287
277
  if @debug_mode
278
+ line = caller(depth+1)[0]
288
279
  if match = /^(.+?):(\d+)(?::in `(.*)')?/.match(line)
289
280
  file = match[1].split('/')[-2,2].join('/')
290
281
  line = match[2]
@@ -174,6 +174,7 @@ module Fluent
174
174
  config_param :flush_interval, :time, :default => 60
175
175
  config_param :retry_limit, :integer, :default => 17
176
176
  config_param :retry_wait, :time, :default => 1.0
177
+ config_param :max_retry_wait, :time, :default => nil
177
178
  config_param :num_threads, :integer, :default => 1
178
179
  config_param :queued_chunk_flush_interval, :time, :default => 1
179
180
 
@@ -388,7 +389,8 @@ module Fluent
388
389
  # secondary retry
389
390
  @retry_wait * (2 ** (@error_history.size-2-@retry_limit))
390
391
  end
391
- wait + (rand * (wait / 4.0) - (wait / 8.0))
392
+ retry_wait = wait + (rand * (wait / 4.0) - (wait / 8.0))
393
+ @max_retry_wait ? [retry_wait, @max_retry_wait].min : retry_wait
392
394
  end
393
395
 
394
396
  def write_abort
@@ -133,22 +133,21 @@ module Fluent
133
133
  private
134
134
 
135
135
  def on_message(record)
136
- if val = record.delete(@time_key)
137
- time = @time_parse_proc.call(val)
138
- else
139
- time = Engine.now
140
- end
141
-
142
136
  if val = record.delete(@tag_key)
143
137
  tag = val
144
138
  else
145
139
  tag = @tag
146
140
  end
147
141
 
142
+ if val = record.delete(@time_key)
143
+ time = @time_parse_proc.call(val)
144
+ else
145
+ time = Engine.now
146
+ end
147
+
148
148
  Engine.emit(tag, time, record)
149
- rescue
150
- $log.error "exec failed to emit", :error => $!.to_s, :error_class => $!.class.to_s, :record => Yajl.dump(record)
151
- $log.warn_backtrace $!.backtrace
149
+ rescue => e
150
+ $log.error "exec failed to emit", :error => e.to_s, :error_class => e.class.to_s, :tag => tag, :record => Yajl.dump(record)
152
151
  end
153
152
  end
154
153
  end
@@ -109,6 +109,8 @@ module Fluent
109
109
  }
110
110
 
111
111
  Engine.emit(@tag, now, record)
112
+ rescue => e
113
+ $log.error "object space failed to emit", :error => e.to_s, :error_class => e.class.to_s, :tag => @tag, :record => Yajl.dump(record)
112
114
  end
113
115
  end
114
116
  end
@@ -177,6 +177,8 @@ module Fluent
177
177
  tag = "#{@tag}.#{facility}.#{priority}"
178
178
 
179
179
  Engine.emit(tag, time, record)
180
+ rescue => e
181
+ $log.error "syslog failed to emit", :error => e.to_s, :error_class => e.class.to_s, :tag => tag, :record => Yajl.dump(record)
180
182
  end
181
183
 
182
184
  class UdpHandler < Coolio::IO
@@ -18,11 +18,12 @@
18
18
  module Fluent
19
19
  class Supervisor
20
20
  class LoggerInitializer
21
- def initialize(path, level, chuser, chgroup)
21
+ def initialize(path, level, chuser, chgroup, opts)
22
22
  @path = path
23
23
  @level = level
24
24
  @chuser = chuser
25
25
  @chgroup = chgroup
26
+ @opts = opts
26
27
  end
27
28
 
28
29
  def init
@@ -37,7 +38,7 @@ module Fluent
37
38
  @io = STDOUT
38
39
  end
39
40
 
40
- $log = Fluent::Log.new(@io, @level)
41
+ $log = Fluent::Log.new(@io, @level, @opts)
41
42
 
42
43
  $log.enable_color(false) if @path
43
44
  $log.enable_debug if @level <= Fluent::Log::LEVEL_DEBUG
@@ -69,7 +70,8 @@ module Fluent
69
70
  @dry_run = opt[:dry_run]
70
71
  @suppress_config_dump = opt[:suppress_config_dump]
71
72
 
72
- @log = LoggerInitializer.new(@log_path, @log_level, @chuser, @chgroup)
73
+ log_opts = {:suppress_repeated_stacktrace => opt[:suppress_repeated_stacktrace]}
74
+ @log = LoggerInitializer.new(@log_path, @log_level, @chuser, @chgroup, log_opts)
73
75
  @finished = false
74
76
  @main_pid = nil
75
77
  end
@@ -1,5 +1,5 @@
1
1
  module Fluent
2
2
 
3
- VERSION = '0.10.40'
3
+ VERSION = '0.10.41'
4
4
 
5
5
  end
@@ -0,0 +1,55 @@
1
+ require 'helper'
2
+ require 'fluent/test'
3
+ require 'fluent/output'
4
+
5
+ module FluentOutputTest
6
+ include Fluent
7
+
8
+ class BufferedOutputTest < ::Test::Unit::TestCase
9
+ include FluentOutputTest
10
+
11
+ def setup
12
+ Fluent::Test.setup
13
+ end
14
+
15
+ CONFIG = %[]
16
+
17
+ def create_driver(conf=CONFIG)
18
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::BufferedOutput) do
19
+ def write(chunk)
20
+ chunk.read
21
+ end
22
+ end.configure(conf)
23
+ end
24
+
25
+ def test_configure
26
+ # default
27
+ d = create_driver
28
+ assert_equal 'memory', d.instance.buffer_type
29
+ assert_equal 60, d.instance.flush_interval
30
+ assert_equal 17, d.instance.retry_limit
31
+ assert_equal 1.0, d.instance.retry_wait
32
+ assert_equal nil, d.instance.max_retry_wait
33
+ assert_equal 1.0, d.instance.retry_wait
34
+ assert_equal 1, d.instance.num_threads
35
+ assert_equal 1, d.instance.queued_chunk_flush_interval
36
+
37
+ # max_retry_wait
38
+ d = create_driver(CONFIG + %[max_retry_wait 4])
39
+ assert_equal 4, d.instance.max_retry_wait
40
+ end
41
+
42
+ def test_calc_retry_wait
43
+ # default
44
+ d = create_driver
45
+ d.instance.retry_limit.times { d.instance.instance_variable_get(:@error_history) << Engine.now }
46
+ wait = d.instance.retry_wait * (2 ** (d.instance.retry_limit - 1))
47
+ assert( d.instance.calc_retry_wait > wait - wait / 8.0 )
48
+
49
+ # max_retry_wait
50
+ d = create_driver(CONFIG + %[max_retry_wait 4])
51
+ d.instance.retry_limit.times { d.instance.instance_variable_get(:@error_history) << Engine.now }
52
+ assert_equal 4, d.instance.calc_retry_wait
53
+ end
54
+ end
55
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluentd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.40
4
+ version: 0.10.41
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-11-08 00:00:00.000000000 Z
12
+ date: 2013-12-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: msgpack
@@ -268,6 +268,7 @@ files:
268
268
  - test/helper.rb
269
269
  - test/match.rb
270
270
  - test/mixin.rb
271
+ - test/output.rb
271
272
  - test/parser.rb
272
273
  - test/plugin/in_exec.rb
273
274
  - test/plugin/in_forward.rb
@@ -307,7 +308,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
307
308
  version: '0'
308
309
  segments:
309
310
  - 0
310
- hash: -2484756068667475409
311
+ hash: -602194787130919488
311
312
  requirements: []
312
313
  rubyforge_project:
313
314
  rubygems_version: 1.8.23
@@ -320,6 +321,7 @@ test_files:
320
321
  - test/helper.rb
321
322
  - test/match.rb
322
323
  - test/mixin.rb
324
+ - test/output.rb
323
325
  - test/parser.rb
324
326
  - test/plugin/in_exec.rb
325
327
  - test/plugin/in_forward.rb