fluentd 0.10.34 → 0.10.35

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,4 +1,13 @@
1
1
 
2
+ Release 0.10.35 - 2013/06/12
3
+
4
+ * Log: emits fluentd's log via background thread
5
+ * Log: use #inspect for non to_msgpack-able object in log event processing
6
+ * FailureDetector/out_forward: fixed wrong phi calculation
7
+ * in_stream: fixed unix domain connection leak when parsing json or msgpack failed
8
+ * buf_file/out_file: sets 0644 permission to each created file for preventing
9
+ File.umask(0) effect at daemonize mode
10
+
2
11
  Release 0.10.34 - 2013/06/03
3
12
 
4
13
  * fluentd: supports --emit-error-log-interval to suppress log messages with the
@@ -27,12 +27,18 @@ class EngineClass
27
27
  @started = []
28
28
  @default_loop = nil
29
29
 
30
+ @log_emit_thread = nil
31
+ @log_event_loop_stop = false
32
+ @log_event_queue = []
33
+
30
34
  @suppress_emit_error_log_interval = 0
31
35
  @next_emit_error_log_time = nil
32
36
  end
33
37
 
34
38
  MATCH_CACHE_SIZE = 1024
35
39
 
40
+ LOG_EMIT_INTERVAL = 0.1
41
+
36
42
  attr_reader :matches, :sources
37
43
 
38
44
  def init
@@ -155,12 +161,34 @@ class EngineClass
155
161
  Time.now.to_i
156
162
  end
157
163
 
164
+ def log_event_loop
165
+ $log.disable_events(Thread.current)
166
+
167
+ while sleep(LOG_EMIT_INTERVAL)
168
+ break if @log_event_loop_stop
169
+ next if @log_event_queue.empty?
170
+
171
+ # NOTE: thead-safe of slice! depends on GVL
172
+ events = @log_event_queue.slice!(0..-1)
173
+ next if events.empty?
174
+
175
+ events.each {|tag,time,record|
176
+ begin
177
+ Engine.emit(tag, time, record)
178
+ rescue
179
+ $log.error "failed to emit fluentd's log event", :tag => tag, :event => record, :error => $!
180
+ end
181
+ }
182
+ end
183
+ end
184
+
158
185
  def run
159
186
  begin
160
187
  start
161
188
 
162
189
  if match?($log.tag)
163
190
  $log.enable_event
191
+ @log_emit_thread = Thread.new(&method(:log_event_loop))
164
192
  end
165
193
 
166
194
  # for empty loop
@@ -173,12 +201,16 @@ class EngineClass
173
201
  $log.error "unexpected error", :error=>$!.to_s
174
202
  $log.error_backtrace
175
203
  ensure
204
+ $log.info "shutting down fluentd"
176
205
  shutdown
206
+ if @log_emit_thread
207
+ @log_event_loop_stop = true
208
+ @log_emit_thread.join
209
+ end
177
210
  end
178
211
  end
179
212
 
180
213
  def stop
181
- $log.info "shutting down fluentd"
182
214
  if @default_loop
183
215
  @default_loop.stop
184
216
  @default_loop = nil
@@ -186,6 +218,11 @@ class EngineClass
186
218
  nil
187
219
  end
188
220
 
221
+ def push_log_event(tag, time, record)
222
+ return if @log_emit_thread.nil?
223
+ @log_event_queue.push([tag, time, record])
224
+ end
225
+
189
226
  private
190
227
  def start
191
228
  @matches.each {|m|
@@ -3,4 +3,5 @@ DEFAULT_CONFIG_PATH = ENV['FLUENT_CONF'] || '/etc/fluent/fluent.conf'
3
3
  DEFAULT_PLUGIN_DIR = ENV['FLUENT_PLUGIN'] || '/etc/fluent/plugin'
4
4
  DEFAULT_SOCKET_PATH = ENV['FLUENT_SOCKET'] || '/var/run/fluent/fluent.sock'
5
5
  DEFAULT_LISTEN_PORT = 24224
6
+ DEFAULT_FILE_PERMISSION = 0644
6
7
  end
@@ -50,6 +50,8 @@ class Log
50
50
  @tag = 'fluent'
51
51
  @time_format = '%Y-%m-%d %H:%M:%S %z '
52
52
  enable_color out.tty?
53
+ # TODO: This variable name is unclear so we should change to better name.
54
+ @threads_exclude_events = []
53
55
  end
54
56
 
55
57
  attr_accessor :out
@@ -88,6 +90,12 @@ class Log
88
90
  self
89
91
  end
90
92
 
93
+ # If you want to suppress event emitting in specific thread, please use this method.
94
+ # Events in passed thread are never emitted.
95
+ def disable_events(thread)
96
+ @threads_exclude_events.push(thread) unless @threads_exclude_events.include?(thread)
97
+ end
98
+
91
99
  def on_trace(&block)
92
100
  return if @level > LEVEL_TRACE
93
101
  block.call if block
@@ -252,21 +260,13 @@ class Log
252
260
  end
253
261
  }
254
262
 
255
- if @self_event
256
- c = caller
257
- if c.count(c.shift) <= 0
258
- record = map.dup
259
- record['message'] = message.dup
260
- ### In signal trap context, 'Engine.emit' cannot get Monitor lock (Thread level lock),
261
- ### and ThreadError will be raised
262
- begin
263
- Engine.emit("#{@tag}.#{level}", time.to_i, record)
264
- rescue ThreadError # message: can't be called from trap context
265
- # ignore
266
- end
267
- # TODO: We should check 'GET_THREAD()->interrupt_mask & TRAP_INTERRUPT_MASK'
268
- # for replacement of begin-rescue if any methods exists.
269
- end
263
+ unless @threads_exclude_events.include?(Thread.current)
264
+ record = map.dup
265
+ record.keys.each {|key|
266
+ record[key] = record[key].inspect unless record[key].respond_to?(:to_msgpack)
267
+ }
268
+ record['message'] = message.dup
269
+ Engine.push_log_event("#{@tag}.#{level}", time.to_i, record)
270
270
  end
271
271
 
272
272
  map.each_pair {|k,v|
@@ -23,7 +23,7 @@ class FileBufferChunk < BufferChunk
23
23
  super(key)
24
24
  @path = path
25
25
  @unique_id = unique_id
26
- @file = File.open(@path, mode)
26
+ @file = File.open(@path, mode, DEFAULT_FILE_PERMISSION)
27
27
  @file.sync = true
28
28
  @size = @file.stat.size
29
29
  end
@@ -135,10 +135,18 @@ class StreamInput < Input
135
135
 
136
136
  def on_read_json(data)
137
137
  @y << data
138
+ rescue
139
+ $log.error "unexpected error", :error=>$!.to_s
140
+ $log.error_backtrace
141
+ close
138
142
  end
139
143
 
140
144
  def on_read_msgpack(data)
141
145
  @u.feed_each(data, &@on_message)
146
+ rescue
147
+ $log.error "unexpected error", :error=>$!.to_s
148
+ $log.error_backtrace
149
+ close
142
150
  end
143
151
 
144
152
  def on_close
@@ -42,7 +42,7 @@ class TailInput < Input
42
42
  end
43
43
 
44
44
  if @pos_file
45
- @pf_file = File.open(@pos_file, File::RDWR|File::CREAT)
45
+ @pf_file = File.open(@pos_file, File::RDWR|File::CREAT, DEFAULT_FILE_PERMISSION)
46
46
  @pf_file.sync = true
47
47
  @pf = PositionFile.parse(@pf_file)
48
48
  else
@@ -89,7 +89,7 @@ class FileOutput < TimeSlicedOutput
89
89
 
90
90
  case @compress
91
91
  when nil
92
- File.open(path, "a") {|f|
92
+ File.open(path, "a", DEFAULT_FILE_PERMISSION) {|f|
93
93
  chunk.write_to(f)
94
94
  }
95
95
  when :gz
@@ -380,7 +380,7 @@ class ForwardOutput < ObjectBufferedOutput
380
380
 
381
381
  def resolve_dns!
382
382
  @sockaddr = Socket.pack_sockaddr_in(@port, @host)
383
- port, resolved_host = Socket.unpack_sockaddr_in(sockaddr)
383
+ port, resolved_host = Socket.unpack_sockaddr_in(@sockaddr)
384
384
  return resolved_host
385
385
  end
386
386
  private :resolve_dns!
@@ -480,7 +480,7 @@ class ForwardOutput < ObjectBufferedOutput
480
480
  mean = (mean_usec.to_f / 1e6) - @heartbeat_interval + 1
481
481
 
482
482
  # Calculate phi of the phi accrual failure detector
483
- t = now - @last
483
+ t = now - @last - @heartbeat_interval + 1
484
484
  phi = PHI_FACTOR * t / mean
485
485
 
486
486
  return phi
@@ -1,5 +1,5 @@
1
1
  module Fluent
2
2
 
3
- VERSION = '0.10.34'
3
+ VERSION = '0.10.35'
4
4
 
5
5
  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.34
4
+ version: 0.10.35
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-06-03 00:00:00.000000000 Z
12
+ date: 2013-06-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: msgpack
@@ -284,6 +284,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
284
284
  - - ! '>='
285
285
  - !ruby/object:Gem::Version
286
286
  version: '0'
287
+ segments:
288
+ - 0
289
+ hash: 748399488166287607
287
290
  requirements: []
288
291
  rubyforge_project:
289
292
  rubygems_version: 1.8.23
@@ -313,4 +316,3 @@ test_files:
313
316
  - test/plugin/out_roundrobin.rb
314
317
  - test/plugin/out_stdout.rb
315
318
  - test/plugin/out_stream.rb
316
- has_rdoc: false