fluentd 0.10.42 → 0.10.43
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 +9 -0
- data/README.rdoc +4 -1
- data/fluentd.gemspec +1 -0
- data/lib/fluent/input.rb +1 -1
- data/lib/fluent/load.rb +1 -0
- data/lib/fluent/log.rb +84 -9
- data/lib/fluent/output.rb +6 -2
- data/lib/fluent/parser.rb +9 -5
- data/lib/fluent/plugin/in_debug_agent.rb +1 -1
- data/lib/fluent/plugin/in_exec.rb +3 -3
- data/lib/fluent/plugin/in_forward.rb +14 -13
- data/lib/fluent/plugin/in_gc_stat.rb +7 -6
- data/lib/fluent/plugin/in_http.rb +17 -7
- data/lib/fluent/plugin/in_monitor_agent.rb +1 -1
- data/lib/fluent/plugin/in_object_space.rb +8 -7
- data/lib/fluent/plugin/in_status.rb +7 -6
- data/lib/fluent/plugin/in_stream.rb +14 -13
- data/lib/fluent/plugin/in_syslog.rb +17 -15
- data/lib/fluent/plugin/in_tail.rb +46 -19
- data/lib/fluent/plugin/out_copy.rb +1 -1
- data/lib/fluent/plugin/out_exec_filter.rb +14 -13
- data/lib/fluent/plugin/out_forward.rb +16 -15
- data/lib/fluent/plugin/out_roundrobin.rb +5 -1
- data/lib/fluent/plugin/out_stdout.rb +1 -0
- data/lib/fluent/version.rb +1 -1
- data/test/output.rb +61 -0
- data/test/parser.rb +7 -0
- data/test/plugin/in_http.rb +29 -1
- metadata +66 -27
- checksums.yaml +0 -7
data/ChangeLog
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
Release 0.10.43 - 2013/02/03
|
2
|
+
|
3
|
+
* Input/Output: Add 'log_level' option to plugins
|
4
|
+
* parser/in_tail: Fix RegexpParser forget to call configure method
|
5
|
+
* parser/in_tail: Improve type conversion performance
|
6
|
+
* in_http: Add add_http_headers option to add HTTP headers to record
|
7
|
+
* Buffer: Improve submit_buffer throughput using round-robin writer selection
|
8
|
+
* add sigdump gem to dump useful information via SIGCONT
|
9
|
+
|
1
10
|
Release 0.10.42 - 2013/12/25
|
2
11
|
|
3
12
|
* parser/in_tail: Add 'types' and related parameters to convert record value type
|
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= Fluentd
|
2
2
|
|
3
|
-
{<img src="https://travis-ci.org/fluent/fluentd.png" />}[https://travis-ci.org/fluent/fluentd]
|
3
|
+
{<img src="https://travis-ci.org/fluent/fluentd.png" />}[https://travis-ci.org/fluent/fluentd] {<img src="https://codeclimate.com/github/fluent/fluentd.png " />}[https://codeclimate.com/github/fluent/fluentd]
|
4
4
|
|
5
5
|
Fluentd is an event collector system. It is a generalized version of syslogd, which handles JSON objects for its log messages.
|
6
6
|
|
@@ -64,3 +64,6 @@ License:: Apache License, Version 2.0
|
|
64
64
|
== Contributors:
|
65
65
|
|
66
66
|
Patches contributed by {those people}[https://github.com/fluent/fluentd/contributors].
|
67
|
+
|
68
|
+
{<img src="https://ga-beacon.appspot.com/UA-24890265-6/fluent/fluentd" />}[https://github.com/fluent/fluentd]
|
69
|
+
|
data/fluentd.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |gem|
|
|
23
23
|
gem.add_runtime_dependency(%q<yajl-ruby>, ["~> 1.0"])
|
24
24
|
gem.add_runtime_dependency(%q<cool.io>, ["~> 1.1.1"])
|
25
25
|
gem.add_runtime_dependency(%q<http_parser.rb>, ["~> 0.5.1"])
|
26
|
+
gem.add_runtime_dependency(%q<sigdump>, ["~> 0.2.2"])
|
26
27
|
|
27
28
|
gem.add_development_dependency(%q<rake>, [">= 0.9.2"])
|
28
29
|
gem.add_development_dependency(%q<parallel_tests>, [">= 0.15.3"])
|
data/lib/fluent/input.rb
CHANGED
data/lib/fluent/load.rb
CHANGED
@@ -9,6 +9,7 @@ require 'json'
|
|
9
9
|
require 'yajl'
|
10
10
|
require 'uri'
|
11
11
|
require 'msgpack'
|
12
|
+
require 'sigdump/setup'
|
12
13
|
# I hate global variable but we suffer pain now for the sake of future.
|
13
14
|
# We will switch to MessagePack 0.5 and deprecate 0.4.
|
14
15
|
$use_msgpack_5 = defined?(MessagePack::Packer) ? true : false
|
data/lib/fluent/log.rb
CHANGED
@@ -15,6 +15,9 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
+
|
19
|
+
require 'forwardable'
|
20
|
+
|
18
21
|
module Fluent
|
19
22
|
class Log
|
20
23
|
module TTYColor
|
@@ -47,6 +50,7 @@ module Fluent
|
|
47
50
|
@self_event = false
|
48
51
|
@tag = 'fluent'
|
49
52
|
@time_format = '%Y-%m-%d %H:%M:%S %z '
|
53
|
+
@depth_offset = 1
|
50
54
|
enable_color out.tty?
|
51
55
|
# TODO: This variable name is unclear so we should change to better name.
|
52
56
|
@threads_exclude_events = []
|
@@ -71,6 +75,10 @@ module Fluent
|
|
71
75
|
self
|
72
76
|
end
|
73
77
|
|
78
|
+
def enable_color?
|
79
|
+
!@color_reset.empty?
|
80
|
+
end
|
81
|
+
|
74
82
|
def enable_color(b=true)
|
75
83
|
if b
|
76
84
|
@color_trace = TTYColor::BLUE
|
@@ -107,7 +115,7 @@ module Fluent
|
|
107
115
|
return if @level > LEVEL_TRACE
|
108
116
|
args << block.call if block
|
109
117
|
time, msg = event(:trace, args)
|
110
|
-
puts [@color_trace, caller_line(time,
|
118
|
+
puts [@color_trace, caller_line(time, @depth_offset, LEVEL_TRACE), msg, @color_reset].join
|
111
119
|
rescue
|
112
120
|
# logger should not raise an exception. This rescue prevents unexpected behaviour.
|
113
121
|
end
|
@@ -126,7 +134,7 @@ module Fluent
|
|
126
134
|
return if @level > LEVEL_DEBUG
|
127
135
|
args << block.call if block
|
128
136
|
time, msg = event(:debug, args)
|
129
|
-
puts [@color_debug, caller_line(time,
|
137
|
+
puts [@color_debug, caller_line(time, @depth_offset, LEVEL_DEBUG), msg, @color_reset].join
|
130
138
|
rescue
|
131
139
|
end
|
132
140
|
alias DEBUG debug
|
@@ -144,7 +152,7 @@ module Fluent
|
|
144
152
|
return if @level > LEVEL_INFO
|
145
153
|
args << block.call if block
|
146
154
|
time, msg = event(:info, args)
|
147
|
-
puts [@color_info, caller_line(time,
|
155
|
+
puts [@color_info, caller_line(time, @depth_offset, LEVEL_INFO), msg, @color_reset].join
|
148
156
|
rescue
|
149
157
|
end
|
150
158
|
alias INFO info
|
@@ -162,7 +170,7 @@ module Fluent
|
|
162
170
|
return if @level > LEVEL_WARN
|
163
171
|
args << block.call if block
|
164
172
|
time, msg = event(:warn, args)
|
165
|
-
puts [@color_warn, caller_line(time,
|
173
|
+
puts [@color_warn, caller_line(time, @depth_offset, LEVEL_WARN), msg, @color_reset].join
|
166
174
|
rescue
|
167
175
|
end
|
168
176
|
alias WARN warn
|
@@ -180,7 +188,7 @@ module Fluent
|
|
180
188
|
return if @level > LEVEL_ERROR
|
181
189
|
args << block.call if block
|
182
190
|
time, msg = event(:error, args)
|
183
|
-
puts [@color_error, caller_line(time,
|
191
|
+
puts [@color_error, caller_line(time, @depth_offset, LEVEL_ERROR), msg, @color_reset].join
|
184
192
|
rescue
|
185
193
|
end
|
186
194
|
alias ERROR error
|
@@ -198,7 +206,7 @@ module Fluent
|
|
198
206
|
return if @level > LEVEL_FATAL
|
199
207
|
args << block.call if block
|
200
208
|
time, msg = event(:fatal, args)
|
201
|
-
puts [@color_fatal, caller_line(time,
|
209
|
+
puts [@color_fatal, caller_line(time, @depth_offset, LEVEL_FATAL), msg, @color_reset].join
|
202
210
|
rescue
|
203
211
|
end
|
204
212
|
alias FATAL fatal
|
@@ -230,11 +238,12 @@ module Fluent
|
|
230
238
|
return if @level > level
|
231
239
|
|
232
240
|
time = Time.now
|
241
|
+
line = caller_line(time, 5, level)
|
233
242
|
if @suppress_repeated_stacktrace && (Thread.current[:last_repeated_stacktrace] == backtrace)
|
234
|
-
puts [" ",
|
243
|
+
puts [" ", line, 'suppressed same stacktrace'].join
|
235
244
|
else
|
236
245
|
backtrace.each { |msg|
|
237
|
-
puts [" ",
|
246
|
+
puts [" ", line, msg].join
|
238
247
|
}
|
239
248
|
Thread.current[:last_repeated_stacktrace] = backtrace if @suppress_repeated_stacktrace
|
240
249
|
end
|
@@ -286,5 +295,71 @@ module Fluent
|
|
286
295
|
return log_msg
|
287
296
|
end
|
288
297
|
end
|
289
|
-
end
|
290
298
|
|
299
|
+
|
300
|
+
# PluginLogger has own log level separated from global $log object.
|
301
|
+
# This class enables log_level option in each plugin.
|
302
|
+
#
|
303
|
+
# PluginLogger has same functionality as Log but some methods are forwarded to internal logger
|
304
|
+
# for keeping logging action consistency in the process, e.g. color, tag, event, etc.
|
305
|
+
class PluginLogger < Log
|
306
|
+
def initialize(logger)
|
307
|
+
@logger = logger
|
308
|
+
@level = @logger.level
|
309
|
+
@depth_offset = 2
|
310
|
+
@suppress_repeated_stacktrace = logger.instance_variable_get(:@suppress_repeated_stacktrace)
|
311
|
+
|
312
|
+
enable_color @logger.enable_color?
|
313
|
+
end
|
314
|
+
|
315
|
+
def level=(log_level_str)
|
316
|
+
@level = case log_level_str.downcase
|
317
|
+
when "trace" then LEVEL_TRACE
|
318
|
+
when "debug" then LEVEL_DEBUG
|
319
|
+
when "info" then LEVEL_INFO
|
320
|
+
when "warn" then LEVEL_WARN
|
321
|
+
when "error" then LEVEL_ERROR
|
322
|
+
when "fatal" then LEVEL_FATAL
|
323
|
+
else raise "Unknown log level: level = #{log_level_str}"
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
alias orig_enable_color enable_color
|
328
|
+
|
329
|
+
def enable_color(b = true)
|
330
|
+
orig_enable_color b
|
331
|
+
@logger.enable_color b
|
332
|
+
end
|
333
|
+
|
334
|
+
extend Forwardable
|
335
|
+
def_delegators '@logger', :enable_color?, :enable_debug, :enable_event,
|
336
|
+
:disable_events, :tag, :tag=, :time_format, :time_format=,
|
337
|
+
:event, :caller_line, :puts, :write, :flush
|
338
|
+
end
|
339
|
+
|
340
|
+
|
341
|
+
module PluginLoggerMixin
|
342
|
+
def self.included(klass)
|
343
|
+
klass.instance_eval {
|
344
|
+
config_param :log_level, :string, :default => nil
|
345
|
+
}
|
346
|
+
end
|
347
|
+
|
348
|
+
def initialize
|
349
|
+
super
|
350
|
+
|
351
|
+
@log = $log # Use $log object directly by default
|
352
|
+
end
|
353
|
+
|
354
|
+
attr_accessor :log
|
355
|
+
|
356
|
+
def configure(conf)
|
357
|
+
super
|
358
|
+
|
359
|
+
if @log_level
|
360
|
+
@log = PluginLogger.new($log)
|
361
|
+
@log.level = @log_level
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
data/lib/fluent/output.rb
CHANGED
@@ -59,6 +59,7 @@ module Fluent
|
|
59
59
|
class Output
|
60
60
|
include Configurable
|
61
61
|
include PluginId
|
62
|
+
include PluginLoggerMixin
|
62
63
|
|
63
64
|
def initialize
|
64
65
|
super
|
@@ -223,6 +224,8 @@ module Fluent
|
|
223
224
|
@buffer.start
|
224
225
|
@secondary.start if @secondary
|
225
226
|
@writers.each {|writer| writer.start }
|
227
|
+
@writer_current_position = 0
|
228
|
+
@writers_size = @writers.size
|
226
229
|
end
|
227
230
|
|
228
231
|
def shutdown
|
@@ -240,8 +243,9 @@ module Fluent
|
|
240
243
|
end
|
241
244
|
|
242
245
|
def submit_flush
|
243
|
-
#
|
244
|
-
@
|
246
|
+
# Without locks: it is rough but enough to select "next" writer selection
|
247
|
+
@writer_current_position = (@writer_current_position + 1) % @writers_size
|
248
|
+
@writers[@writer_current_position].submit_flush
|
245
249
|
end
|
246
250
|
|
247
251
|
def format_stream(tag, es)
|
data/lib/fluent/parser.rb
CHANGED
@@ -137,10 +137,14 @@ module Fluent
|
|
137
137
|
@mutex = Mutex.new
|
138
138
|
end
|
139
139
|
|
140
|
+
def configure(conf)
|
141
|
+
super
|
142
|
+
@time_parser = TimeParser.new(@time_format)
|
143
|
+
end
|
144
|
+
|
140
145
|
def call(text)
|
141
146
|
m = @regexp.match(text)
|
142
147
|
unless m
|
143
|
-
$log.warn "pattern not match: #{text.inspect}"
|
144
148
|
return nil, nil
|
145
149
|
end
|
146
150
|
|
@@ -198,7 +202,6 @@ module Fluent
|
|
198
202
|
|
199
203
|
return time, record
|
200
204
|
rescue Yajl::ParseError
|
201
|
-
$log.warn "pattern not match: #{text.inspect}: #{$!}"
|
202
205
|
return nil, nil
|
203
206
|
end
|
204
207
|
end
|
@@ -246,8 +249,10 @@ module Fluent
|
|
246
249
|
private
|
247
250
|
|
248
251
|
def convert_field_type!(record)
|
249
|
-
|
250
|
-
record[key]
|
252
|
+
@type_converters.each_key { |key|
|
253
|
+
if value = record[key]
|
254
|
+
record[key] = convert_type(key, value)
|
255
|
+
end
|
251
256
|
}
|
252
257
|
end
|
253
258
|
end
|
@@ -320,7 +325,6 @@ module Fluent
|
|
320
325
|
def call(text)
|
321
326
|
m = REGEXP.match(text)
|
322
327
|
unless m
|
323
|
-
$log.warn "pattern not match: #{text.inspect}"
|
324
328
|
return nil, nil
|
325
329
|
end
|
326
330
|
|
@@ -41,7 +41,7 @@ module Fluent
|
|
41
41
|
else
|
42
42
|
uri = "druby://#{@bind}:#{@port}"
|
43
43
|
end
|
44
|
-
|
44
|
+
log.info "listening dRuby", :uri => uri, :object => @object
|
45
45
|
obj = eval(@object)
|
46
46
|
@server = DRb::DRbServer.new(uri, obj)
|
47
47
|
end
|
@@ -124,8 +124,8 @@ module Fluent
|
|
124
124
|
@parser.call(io)
|
125
125
|
Process.waitpid(io.pid)
|
126
126
|
rescue
|
127
|
-
|
128
|
-
|
127
|
+
log.error "exec failed to run or shutdown child process", :error => $!.to_s, :error_class => $!.class.to_s
|
128
|
+
log.warn_backtrace $!.backtrace
|
129
129
|
end
|
130
130
|
end
|
131
131
|
end
|
@@ -147,7 +147,7 @@ module Fluent
|
|
147
147
|
|
148
148
|
Engine.emit(tag, time, record)
|
149
149
|
rescue => e
|
150
|
-
|
150
|
+
log.error "exec failed to emit", :error => e.to_s, :error_class => e.class.to_s, :tag => tag, :record => Yajl.dump(record)
|
151
151
|
end
|
152
152
|
end
|
153
153
|
end
|
@@ -61,8 +61,8 @@ module Fluent
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def listen
|
64
|
-
|
65
|
-
s = Coolio::TCPServer.new(@bind, @port, Handler, method(:on_message))
|
64
|
+
log.info "listening fluent socket on #{@bind}:#{@port}"
|
65
|
+
s = Coolio::TCPServer.new(@bind, @port, Handler, log, method(:on_message))
|
66
66
|
s.listen(@backlog) unless @backlog.nil?
|
67
67
|
s
|
68
68
|
end
|
@@ -73,15 +73,15 @@ module Fluent
|
|
73
73
|
# File.unlink(@path)
|
74
74
|
# end
|
75
75
|
# FileUtils.mkdir_p File.dirname(@path)
|
76
|
-
#
|
76
|
+
# log.debug "listening fluent socket on #{@path}"
|
77
77
|
# Coolio::UNIXServer.new(@path, Handler, method(:on_message))
|
78
78
|
#end
|
79
79
|
|
80
80
|
def run
|
81
81
|
@loop.run
|
82
82
|
rescue => e
|
83
|
-
|
84
|
-
|
83
|
+
log.error "unexpected error", :error => e, :error_class => e.class
|
84
|
+
log.error_backtrace
|
85
85
|
end
|
86
86
|
|
87
87
|
protected
|
@@ -143,14 +143,15 @@ module Fluent
|
|
143
143
|
end
|
144
144
|
|
145
145
|
class Handler < Coolio::Socket
|
146
|
-
def initialize(io, on_message)
|
146
|
+
def initialize(io, log, on_message)
|
147
147
|
super(io)
|
148
148
|
if io.is_a?(TCPSocket)
|
149
149
|
opt = [1, @timeout.to_i].pack('I!I!') # { int l_onoff; int l_linger; }
|
150
150
|
io.setsockopt(Socket::SOL_SOCKET, Socket::SO_LINGER, opt)
|
151
151
|
end
|
152
|
-
$log.trace { "accepted fluent socket object_id=#{self.object_id}" }
|
153
152
|
@on_message = on_message
|
153
|
+
@log = log
|
154
|
+
@log.trace { "accepted fluent socket object_id=#{self.object_id}" }
|
154
155
|
end
|
155
156
|
|
156
157
|
def on_connect
|
@@ -176,21 +177,21 @@ module Fluent
|
|
176
177
|
def on_read_json(data)
|
177
178
|
@y << data
|
178
179
|
rescue => e
|
179
|
-
|
180
|
-
|
180
|
+
@log.error "forward error", :error => e, :error_class => e.class
|
181
|
+
@log.error_backtrace
|
181
182
|
close
|
182
183
|
end
|
183
184
|
|
184
185
|
def on_read_msgpack(data)
|
185
186
|
@u.feed_each(data, &@on_message)
|
186
187
|
rescue => e
|
187
|
-
|
188
|
-
|
188
|
+
@log.error "forward error", :error => e, :error_class => e.class
|
189
|
+
@log.error_backtrace
|
189
190
|
close
|
190
191
|
end
|
191
192
|
|
192
193
|
def on_close
|
193
|
-
|
194
|
+
@log.trace { "closed fluent socket object_id=#{self.object_id}" }
|
194
195
|
end
|
195
196
|
end
|
196
197
|
|
@@ -216,7 +217,7 @@ module Fluent
|
|
216
217
|
end
|
217
218
|
|
218
219
|
def on_heartbeat_request(host, port, msg)
|
219
|
-
|
220
|
+
#log.trace "heartbeat request from #{host}:#{port}"
|
220
221
|
begin
|
221
222
|
@usock.send "\0", 0, host, port
|
222
223
|
rescue Errno::EAGAIN, Errno::EWOULDBLOCK, Errno::EINTR
|
@@ -27,8 +27,9 @@ module Fluent
|
|
27
27
|
config_param :tag, :string
|
28
28
|
|
29
29
|
class TimerWatcher < Coolio::TimerWatcher
|
30
|
-
def initialize(interval, repeat, &callback)
|
30
|
+
def initialize(interval, repeat, log, &callback)
|
31
31
|
@callback = callback
|
32
|
+
@log = log
|
32
33
|
super(interval, repeat)
|
33
34
|
end
|
34
35
|
|
@@ -36,8 +37,8 @@ module Fluent
|
|
36
37
|
@callback.call
|
37
38
|
rescue
|
38
39
|
# TODO log?
|
39
|
-
|
40
|
-
|
40
|
+
@log.error $!.to_s
|
41
|
+
@log.error_backtrace
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
@@ -47,7 +48,7 @@ module Fluent
|
|
47
48
|
|
48
49
|
def start
|
49
50
|
@loop = Coolio::Loop.new
|
50
|
-
@timer = TimerWatcher.new(@emit_interval, true, &method(:on_timer))
|
51
|
+
@timer = TimerWatcher.new(@emit_interval, true, log, &method(:on_timer))
|
51
52
|
@loop.attach(@timer)
|
52
53
|
@thread = Thread.new(&method(:run))
|
53
54
|
end
|
@@ -61,8 +62,8 @@ module Fluent
|
|
61
62
|
def run
|
62
63
|
@loop.run
|
63
64
|
rescue
|
64
|
-
|
65
|
-
|
65
|
+
log.error "unexpected error", :error=>$!.to_s
|
66
|
+
log.error_backtrace
|
66
67
|
end
|
67
68
|
|
68
69
|
def on_timer
|