fluentd 0.10.33 → 0.10.34
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 +19 -2
- data/lib/fluent/command/fluentd.rb +4 -0
- data/lib/fluent/engine.rb +16 -2
- data/lib/fluent/event.rb +41 -16
- data/lib/fluent/load.rb +3 -1
- data/lib/fluent/log.rb +15 -7
- data/lib/fluent/mixin.rb +3 -2
- data/lib/fluent/output.rb +5 -5
- data/lib/fluent/parser.rb +4 -3
- data/lib/fluent/plugin/in_forward.rb +1 -1
- data/lib/fluent/plugin/in_stream.rb +1 -1
- data/lib/fluent/plugin/in_tail.rb +1 -1
- data/lib/fluent/plugin/out_exec_filter.rb +18 -2
- data/lib/fluent/plugin/out_forward.rb +7 -5
- data/lib/fluent/process.rb +1 -1
- data/lib/fluent/supervisor.rb +44 -4
- data/lib/fluent/test/base.rb +1 -1
- data/lib/fluent/version.rb +1 -1
- data/test/helper.rb +5 -0
- data/test/mixin.rb +22 -6
- data/test/parser.rb +14 -14
- data/test/plugin/out_copy.rb +37 -0
- metadata +2 -2
data/ChangeLog
CHANGED
@@ -1,10 +1,27 @@
|
|
1
1
|
|
2
|
+
Release 0.10.34 - 2013/06/03
|
3
|
+
|
4
|
+
* fluentd: supports --emit-error-log-interval to suppress log messages with the
|
5
|
+
same message for a certain seconds
|
6
|
+
* BufferedOutput: fixed warning messages so that errors with the same meaning
|
7
|
+
use the same message
|
8
|
+
* Log: ignores ThreadError which could happen in signal handler
|
9
|
+
* Engine: prevents signal handlers from calling stop() method of plugins twice
|
10
|
+
* MessagePackEventStream/in_forward: doesn't cache MessagePack::Unpacker (if
|
11
|
+
it uses msgpack-0.5.5 which doesn't cause performance impact) to not cause
|
12
|
+
problems with out_copy
|
13
|
+
* TextParser/in_tail,in_syslog: 'json' format type removes time key from records
|
14
|
+
* TextParser/in_tail,in_syslog: raises exception if time_format is set while
|
15
|
+
time_key is not set
|
16
|
+
* in_tail: fixed minor bugs
|
17
|
+
|
18
|
+
|
2
19
|
Release 0.10.33 - 2013/03/28
|
3
20
|
|
4
|
-
*
|
21
|
+
* added in_monitor_agent
|
5
22
|
* switched from jeweler to bundler
|
6
23
|
* updated dependency for msgpack from '~> 0.4.4' to '~> 0.4.4 OR ~> 0.5.4'
|
7
|
-
*
|
24
|
+
* added PluginId module so that in_monitor_agent can search plugins by id
|
8
25
|
* BufferedOutput: added queued_chunk_flush_interval option to insert delay
|
9
26
|
time before flushing queued chunks
|
10
27
|
* BufferedOutput: randomize retry interval to prevent multiple servers from
|
@@ -35,6 +35,7 @@ opts = {
|
|
35
35
|
:setup_path => nil,
|
36
36
|
:chuser => nil,
|
37
37
|
:chgroup => nil,
|
38
|
+
:suppress_interval => 0,
|
38
39
|
}
|
39
40
|
|
40
41
|
op.on('-s', "--setup [DIR=#{File.dirname(Fluent::DEFAULT_CONFIG_PATH)}]", "install sample configuration file to the directory") {|s|
|
@@ -77,6 +78,9 @@ op.on('-i', '--inline-config CONFIG_STRING', "inline config which is appended to
|
|
77
78
|
opts[:inline_config] = s
|
78
79
|
}
|
79
80
|
|
81
|
+
op.on('--emit-error-log-interval SECONDS', "suppress interval seconds of emit error logs") {|s|
|
82
|
+
opts[:suppress_interval] = s.to_i
|
83
|
+
}
|
80
84
|
|
81
85
|
op.on('-v', '--verbose', "increase verbose level (-v: debug, -vv: trace)", TrueClass) {|b|
|
82
86
|
if b
|
data/lib/fluent/engine.rb
CHANGED
@@ -26,6 +26,9 @@ class EngineClass
|
|
26
26
|
@match_cache_keys = []
|
27
27
|
@started = []
|
28
28
|
@default_loop = nil
|
29
|
+
|
30
|
+
@suppress_emit_error_log_interval = 0
|
31
|
+
@next_emit_error_log_time = nil
|
29
32
|
end
|
30
33
|
|
31
34
|
MATCH_CACHE_SIZE = 1024
|
@@ -42,6 +45,11 @@ class EngineClass
|
|
42
45
|
self
|
43
46
|
end
|
44
47
|
|
48
|
+
def suppress_interval(interval_time)
|
49
|
+
@suppress_emit_error_log_interval = interval_time
|
50
|
+
@next_emit_error_log_time = Time.now.to_i
|
51
|
+
end
|
52
|
+
|
45
53
|
def read_config(path)
|
46
54
|
$log.info "reading config file", :path=>path
|
47
55
|
File.open(path) {|io|
|
@@ -119,8 +127,14 @@ class EngineClass
|
|
119
127
|
end
|
120
128
|
target.emit(tag, es)
|
121
129
|
rescue
|
122
|
-
|
123
|
-
|
130
|
+
if @suppress_emit_error_log_interval == 0 || now > @next_emit_error_log_time
|
131
|
+
$log.warn "emit transaction failed ", :error=>$!.to_s
|
132
|
+
$log.warn_backtrace
|
133
|
+
# $log.debug "current next_emit_error_log_time: #{Time.at(@next_emit_error_log_time)}"
|
134
|
+
@next_emit_error_log_time = Time.now.to_i + @suppress_emit_error_log_interval
|
135
|
+
# $log.debug "next emit failure log suppressed"
|
136
|
+
# $log.debug "next logged time is #{Time.at(@next_emit_error_log_time)}"
|
137
|
+
end
|
124
138
|
raise
|
125
139
|
end
|
126
140
|
|
data/lib/fluent/event.rb
CHANGED
@@ -110,29 +110,54 @@ class MultiEventStream < EventStream
|
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
113
|
+
if $use_msgpack_5
|
113
114
|
|
114
|
-
class MessagePackEventStream < EventStream
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
end
|
115
|
+
class MessagePackEventStream < EventStream
|
116
|
+
def initialize(data, cached_unpacker=nil)
|
117
|
+
@data = data
|
118
|
+
end
|
119
119
|
|
120
|
-
|
121
|
-
|
122
|
-
|
120
|
+
def repeatable?
|
121
|
+
true
|
122
|
+
end
|
123
123
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
124
|
+
def each(&block)
|
125
|
+
# TODO format check
|
126
|
+
unpacker = MessagePack::Unpacker.new
|
127
|
+
unpacker.feed_each(@data, &block)
|
128
|
+
nil
|
129
|
+
end
|
130
|
+
|
131
|
+
def to_msgpack_stream
|
132
|
+
@data
|
133
|
+
end
|
129
134
|
end
|
130
135
|
|
131
|
-
|
132
|
-
|
136
|
+
else # for 0.4.x. Will be removed after 0.5.x is stable
|
137
|
+
|
138
|
+
class MessagePackEventStream < EventStream
|
139
|
+
def initialize(data, cached_unpacker=nil)
|
140
|
+
@data = data
|
141
|
+
@unpacker = cached_unpacker || MessagePack::Unpacker.new
|
142
|
+
end
|
143
|
+
|
144
|
+
def repeatable?
|
145
|
+
true
|
146
|
+
end
|
147
|
+
|
148
|
+
def each(&block)
|
149
|
+
@unpacker.reset
|
150
|
+
# TODO format check
|
151
|
+
@unpacker.feed_each(@data, &block)
|
152
|
+
nil
|
153
|
+
end
|
154
|
+
|
155
|
+
def to_msgpack_stream
|
156
|
+
@data
|
157
|
+
end
|
133
158
|
end
|
134
|
-
end
|
135
159
|
|
160
|
+
end
|
136
161
|
|
137
162
|
#class IoEventStream < EventStream
|
138
163
|
# def initialize(io, num)
|
data/lib/fluent/load.rb
CHANGED
@@ -9,8 +9,10 @@ require 'json'
|
|
9
9
|
require 'yajl'
|
10
10
|
require 'uri'
|
11
11
|
require 'msgpack'
|
12
|
+
# I hate global variable but we suffer pain now for the sake of future.
|
13
|
+
# We will switch to MessagePack 0.5 and deprecate 0.4.
|
14
|
+
$use_msgpack_5 = defined?(MessagePack::Packer) ? true : false
|
12
15
|
require 'cool.io'
|
13
|
-
require 'cool.io/eventmachine'
|
14
16
|
require 'fluent/env'
|
15
17
|
require 'fluent/version'
|
16
18
|
require 'fluent/log'
|
data/lib/fluent/log.rb
CHANGED
@@ -241,11 +241,11 @@ class Log
|
|
241
241
|
def event(level, args)
|
242
242
|
time = Time.now
|
243
243
|
message = ''
|
244
|
-
|
244
|
+
map = {}
|
245
245
|
args.each {|a|
|
246
246
|
if a.is_a?(Hash)
|
247
247
|
a.each_pair {|k,v|
|
248
|
-
|
248
|
+
map[k.to_s] = v
|
249
249
|
}
|
250
250
|
else
|
251
251
|
message << a.to_s
|
@@ -255,14 +255,22 @@ class Log
|
|
255
255
|
if @self_event
|
256
256
|
c = caller
|
257
257
|
if c.count(c.shift) <= 0
|
258
|
-
|
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.
|
259
269
|
end
|
260
270
|
end
|
261
271
|
|
262
|
-
|
263
|
-
|
264
|
-
message << " #{k}=#{v.inspect}"
|
265
|
-
end
|
272
|
+
map.each_pair {|k,v|
|
273
|
+
message << " #{k}=#{v.inspect}"
|
266
274
|
}
|
267
275
|
|
268
276
|
return time, message
|
data/lib/fluent/mixin.rb
CHANGED
@@ -93,8 +93,9 @@ module RecordFilterMixin
|
|
93
93
|
def format_stream(tag, es)
|
94
94
|
out = ''
|
95
95
|
es.each {|time,record|
|
96
|
-
|
97
|
-
|
96
|
+
tag_temp = tag.dup
|
97
|
+
filter_record(tag_temp, time, record)
|
98
|
+
out << format(tag_temp, time, record)
|
98
99
|
}
|
99
100
|
out
|
100
101
|
end
|
data/lib/fluent/output.rb
CHANGED
@@ -324,20 +324,20 @@ class BufferedOutput < Output
|
|
324
324
|
end
|
325
325
|
|
326
326
|
if error_count < @retry_limit
|
327
|
-
$log.warn "temporarily failed to flush the buffer,
|
327
|
+
$log.warn "temporarily failed to flush the buffer.", :next_retry=>Time.at(@next_retry_time), :error_class=>e.class.to_s, :error=>e.to_s, :instance=>object_id
|
328
328
|
$log.warn_backtrace e.backtrace
|
329
329
|
|
330
330
|
elsif @secondary
|
331
331
|
if error_count == @retry_limit
|
332
|
-
$log.warn "failed to flush the buffer.", :error=>e.to_s, :instance=>object_id
|
332
|
+
$log.warn "failed to flush the buffer.", :error_class=>e.class.to_s, :error=>e.to_s, :instance=>object_id
|
333
333
|
$log.warn "retry count exceededs limit. falling back to secondary output."
|
334
334
|
$log.warn_backtrace e.backtrace
|
335
335
|
retry # retry immediately
|
336
336
|
elsif error_count <= @retry_limit + @secondary_limit
|
337
|
-
$log.warn "failed to flush the buffer, next retry will be with secondary output
|
337
|
+
$log.warn "failed to flush the buffer, next retry will be with secondary output.", :next_retry=>Time.at(@next_retry_time), :error_class=>e.class.to_s, :error=>e.to_s, :instance=>object_id
|
338
338
|
$log.warn_backtrace e.backtrace
|
339
339
|
else
|
340
|
-
$log.warn "failed to flush the buffer.", :error=>e.to_s, :instance=>object_id
|
340
|
+
$log.warn "failed to flush the buffer.", :error_class=>e.class, :error=>e.to_s, :instance=>object_id
|
341
341
|
$log.warn "secondary retry count exceededs limit."
|
342
342
|
$log.warn_backtrace e.backtrace
|
343
343
|
write_abort
|
@@ -345,7 +345,7 @@ class BufferedOutput < Output
|
|
345
345
|
end
|
346
346
|
|
347
347
|
else
|
348
|
-
$log.warn "failed to flush the buffer.", :error=>e.to_s, :instance=>object_id
|
348
|
+
$log.warn "failed to flush the buffer.", :error_class=>e.class.to_s, :error=>e.to_s, :instance=>object_id
|
349
349
|
$log.warn "retry count exceededs limit."
|
350
350
|
$log.warn_backtrace e.backtrace
|
351
351
|
write_abort
|
data/lib/fluent/parser.rb
CHANGED
@@ -106,7 +106,7 @@ class TextParser
|
|
106
106
|
end
|
107
107
|
|
108
108
|
if @time_format && !@time_key
|
109
|
-
|
109
|
+
raise ConfigError, "time_format parameter is ignored because time_key parameter is not set. at #{conf.inspect}"
|
110
110
|
end
|
111
111
|
end
|
112
112
|
|
@@ -114,7 +114,7 @@ class TextParser
|
|
114
114
|
record = Hash[keys.zip(values)]
|
115
115
|
|
116
116
|
if @time_key
|
117
|
-
value = record
|
117
|
+
value = record.delete(@time_key)
|
118
118
|
if @time_format
|
119
119
|
time = Time.strptime(value, @time_format).to_i
|
120
120
|
else
|
@@ -139,9 +139,10 @@ class TextParser
|
|
139
139
|
class LabeledTSVParser < ValuesParser
|
140
140
|
config_param :delimiter, :string, :default => "\t"
|
141
141
|
config_param :label_delimiter, :string, :default => ":"
|
142
|
+
config_param :time_key, :string, :default => "time"
|
142
143
|
|
143
144
|
def configure(conf)
|
144
|
-
conf['keys'] = conf['time_key'] || ''
|
145
|
+
conf['keys'] = conf['time_key'] || 'time'
|
145
146
|
super(conf)
|
146
147
|
end
|
147
148
|
|
@@ -71,6 +71,9 @@ class ExecFilterOutput < BufferedOutput
|
|
71
71
|
# nil, 'none' or 0: no respawn, 'inf' or -1: infinite times, positive integer: try to respawn specified times only
|
72
72
|
config_param :child_respawn, :string, :default => nil
|
73
73
|
|
74
|
+
# 0: output logs for all of messages to emit
|
75
|
+
config_param :suppress_error_log_interval, :time, :default => 0
|
76
|
+
|
74
77
|
config_set_default :flush_interval, 1
|
75
78
|
|
76
79
|
def configure(conf)
|
@@ -166,6 +169,9 @@ class ExecFilterOutput < BufferedOutput
|
|
166
169
|
else
|
167
170
|
raise ConfigError, "child_respawn option argument invalid: none(or 0), inf(or -1) or positive number"
|
168
171
|
end
|
172
|
+
|
173
|
+
@suppress_error_log_interval ||= 0
|
174
|
+
@next_log_time = Time.now.to_i
|
169
175
|
end
|
170
176
|
|
171
177
|
def start
|
@@ -187,6 +193,10 @@ class ExecFilterOutput < BufferedOutput
|
|
187
193
|
|
188
194
|
def before_shutdown
|
189
195
|
super
|
196
|
+
$log.debug "out_exec_filter#before_shutdown called"
|
197
|
+
@children.each {|c|
|
198
|
+
c.finished = true
|
199
|
+
}
|
190
200
|
sleep 0.5 # TODO wait time before killing child process
|
191
201
|
end
|
192
202
|
|
@@ -227,12 +237,15 @@ class ExecFilterOutput < BufferedOutput
|
|
227
237
|
end
|
228
238
|
|
229
239
|
class ChildProcess
|
240
|
+
attr_accessor :finished
|
241
|
+
|
230
242
|
def initialize(parser,respawns=0)
|
231
243
|
@pid = nil
|
232
244
|
@thread = nil
|
233
245
|
@parser = parser
|
234
246
|
@respawns = respawns
|
235
247
|
@mutex = Mutex.new
|
248
|
+
@finished = nil
|
236
249
|
end
|
237
250
|
|
238
251
|
def start(command)
|
@@ -372,8 +385,11 @@ class ExecFilterOutput < BufferedOutput
|
|
372
385
|
Engine.emit(tag, time, record)
|
373
386
|
|
374
387
|
rescue
|
375
|
-
|
376
|
-
|
388
|
+
if @suppress_error_log_interval == 0 || Time.now.to_i > @next_log_time
|
389
|
+
$log.error "exec_filter failed to emit", :error=>$!.to_s, :error_class=>$!.class.to_s, :record=>Yajl.dump(record)
|
390
|
+
$log.warn_backtrace $!.backtrace
|
391
|
+
@next_log_time = Time.now.to_i + @suppress_error_log_interval
|
392
|
+
end
|
377
393
|
end
|
378
394
|
|
379
395
|
class Parser
|
@@ -128,7 +128,9 @@ class ForwardOutput < ObjectBufferedOutput
|
|
128
128
|
$log.error_backtrace
|
129
129
|
end
|
130
130
|
|
131
|
-
def write_objects(tag,
|
131
|
+
def write_objects(tag, chunk)
|
132
|
+
return if chunk.empty?
|
133
|
+
|
132
134
|
error = nil
|
133
135
|
|
134
136
|
wlen = @weight_array.length
|
@@ -138,7 +140,7 @@ class ForwardOutput < ObjectBufferedOutput
|
|
138
140
|
|
139
141
|
if node.available?
|
140
142
|
begin
|
141
|
-
send_data(node, tag,
|
143
|
+
send_data(node, tag, chunk)
|
142
144
|
return
|
143
145
|
rescue
|
144
146
|
# for load balancing during detecting crashed servers
|
@@ -217,7 +219,7 @@ class ForwardOutput < ObjectBufferedOutput
|
|
217
219
|
end
|
218
220
|
end
|
219
221
|
|
220
|
-
def send_data(node, tag,
|
222
|
+
def send_data(node, tag, chunk)
|
221
223
|
sock = connect(node)
|
222
224
|
begin
|
223
225
|
opt = [1, @send_timeout.to_i].pack('I!I!') # { int l_onoff; int l_linger; }
|
@@ -233,7 +235,7 @@ class ForwardOutput < ObjectBufferedOutput
|
|
233
235
|
sock.write tag.to_msgpack # tag
|
234
236
|
|
235
237
|
# beginRaw(size)
|
236
|
-
sz =
|
238
|
+
sz = chunk.size
|
237
239
|
#if sz < 32
|
238
240
|
# # FixRaw
|
239
241
|
# sock.write [0xa0 | sz].pack('C')
|
@@ -246,7 +248,7 @@ class ForwardOutput < ObjectBufferedOutput
|
|
246
248
|
#end
|
247
249
|
|
248
250
|
# writeRawBody(packed_es)
|
249
|
-
|
251
|
+
chunk.write_to(sock)
|
250
252
|
|
251
253
|
node.heartbeat(false)
|
252
254
|
ensure
|
data/lib/fluent/process.rb
CHANGED
@@ -180,7 +180,7 @@ class DetachProcessManager
|
|
180
180
|
|
181
181
|
def read_event_stream(r, &block)
|
182
182
|
u = MessagePack::Unpacker.new(r)
|
183
|
-
cached_unpacker = MessagePack::Unpacker.new
|
183
|
+
cached_unpacker = $use_msgpack_5 ? nil : MessagePack::Unpacker.new
|
184
184
|
begin
|
185
185
|
#buf = ''
|
186
186
|
#map = {}
|
data/lib/fluent/supervisor.rb
CHANGED
@@ -67,6 +67,7 @@ class Supervisor
|
|
67
67
|
@libs = opt[:libs]
|
68
68
|
@plugin_dirs = opt[:plugin_dirs]
|
69
69
|
@inline_config = opt[:inline_config]
|
70
|
+
@suppress_interval = opt[:suppress_interval]
|
70
71
|
|
71
72
|
@log = LoggerInitializer.new(@log_path, @log_level, @chuser, @chgroup)
|
72
73
|
@finished = false
|
@@ -90,6 +91,7 @@ class Supervisor
|
|
90
91
|
run_engine
|
91
92
|
exit 0
|
92
93
|
end
|
94
|
+
$log.error "fluentd main process died unexpectedly. restarting." unless @finished
|
93
95
|
end
|
94
96
|
end
|
95
97
|
|
@@ -203,30 +205,50 @@ class Supervisor
|
|
203
205
|
|
204
206
|
def install_supervisor_signal_handlers
|
205
207
|
trap :INT do
|
208
|
+
$log.debug "fluentd supervisor process get SIGINT"
|
206
209
|
@finished = true
|
207
210
|
if pid = @main_pid
|
208
|
-
|
211
|
+
# kill processes only still exists
|
212
|
+
unless Process.waitpid(pid, Process::WNOHANG)
|
213
|
+
begin
|
214
|
+
Process.kill(:INT, pid)
|
215
|
+
rescue Errno::ESRCH
|
216
|
+
# ignore processes already died
|
217
|
+
end
|
218
|
+
end
|
209
219
|
end
|
210
220
|
end
|
211
221
|
|
212
222
|
trap :TERM do
|
223
|
+
$log.debug "fluentd supervisor process get SIGTERM"
|
213
224
|
@finished = true
|
214
225
|
if pid = @main_pid
|
215
|
-
|
226
|
+
# kill processes only still exists
|
227
|
+
unless Process.waitpid(pid, Process::WNOHANG)
|
228
|
+
begin
|
229
|
+
Process.kill(:TERM, pid)
|
230
|
+
rescue Errno::ESRCH
|
231
|
+
# ignore processes already died
|
232
|
+
end
|
233
|
+
end
|
216
234
|
end
|
217
235
|
end
|
218
236
|
|
219
237
|
trap :HUP do
|
238
|
+
$log.debug "fluentd supervisor process get SIGHUP"
|
220
239
|
$log.info "restarting"
|
221
240
|
if pid = @main_pid
|
222
241
|
Process.kill(:TERM, pid)
|
242
|
+
# don't resuce Erro::ESRSH here (invalid status)
|
223
243
|
end
|
224
244
|
end
|
225
245
|
|
226
246
|
trap :USR1 do
|
247
|
+
$log.debug "fluentd supervisor process get SIGUSR1"
|
227
248
|
@log.reopen!
|
228
249
|
if pid = @main_pid
|
229
250
|
Process.kill(:USR1, pid)
|
251
|
+
# don't resuce Erro::ESRSH here (invalid status)
|
230
252
|
end
|
231
253
|
end
|
232
254
|
end
|
@@ -281,6 +303,9 @@ class Supervisor
|
|
281
303
|
def init_engine
|
282
304
|
require 'fluent/load'
|
283
305
|
Fluent::Engine.init
|
306
|
+
if @suppress_interval
|
307
|
+
Fluent::Engine.suppress_interval(@suppress_interval)
|
308
|
+
end
|
284
309
|
|
285
310
|
@libs.each {|lib|
|
286
311
|
require lib
|
@@ -295,19 +320,34 @@ class Supervisor
|
|
295
320
|
end
|
296
321
|
|
297
322
|
def install_main_process_signal_handlers
|
323
|
+
# Strictly speaking, these signal handling is not thread safe.
|
324
|
+
# But enough safe to limit twice call of Fluent::Engine.stop.
|
325
|
+
|
298
326
|
trap :INT do
|
299
|
-
|
327
|
+
$log.debug "fluentd main process get SIGINT"
|
328
|
+
unless @finished
|
329
|
+
@finished = true
|
330
|
+
$log.debug "getting start to shutdown main process"
|
331
|
+
Fluent::Engine.stop
|
332
|
+
end
|
300
333
|
end
|
301
334
|
|
302
335
|
trap :TERM do
|
303
|
-
|
336
|
+
$log.debug "fluentd main process get SIGTERM"
|
337
|
+
unless @finished
|
338
|
+
@finished = true
|
339
|
+
$log.debug "getting start to shutdown main process"
|
340
|
+
Fluent::Engine.stop
|
341
|
+
end
|
304
342
|
end
|
305
343
|
|
306
344
|
trap :HUP do
|
307
345
|
# TODO
|
346
|
+
$log.debug "fluentd main process get SIGHUP"
|
308
347
|
end
|
309
348
|
|
310
349
|
trap :USR1 do
|
350
|
+
$log.debug "fluentd main process get SIGUSR1"
|
311
351
|
$log.info "force flushing buffered events"
|
312
352
|
@log.reopen!
|
313
353
|
Fluent::Engine.flush!
|
data/lib/fluent/test/base.rb
CHANGED
data/lib/fluent/version.rb
CHANGED
data/test/helper.rb
CHANGED
data/test/mixin.rb
CHANGED
@@ -35,7 +35,7 @@ module MixinTest
|
|
35
35
|
mock(Checker).format_check(tagname, @time.to_i, hash)
|
36
36
|
end
|
37
37
|
|
38
|
-
def create_driver(include_klass, conf = '')
|
38
|
+
def create_driver(include_klass, conf = '', tag = "test")
|
39
39
|
register_output_name = create_register_output_name
|
40
40
|
include_klasses = [include_klass].flatten
|
41
41
|
|
@@ -51,7 +51,7 @@ module MixinTest
|
|
51
51
|
def write(chunk); end
|
52
52
|
}
|
53
53
|
|
54
|
-
Fluent::Test::BufferedOutputTestDriver.new(klass) {
|
54
|
+
Fluent::Test::BufferedOutputTestDriver.new(klass, tag) {
|
55
55
|
}.configure("type #{register_output_name}" + conf)
|
56
56
|
end
|
57
57
|
end
|
@@ -164,6 +164,9 @@ module MixinTest
|
|
164
164
|
format_check({
|
165
165
|
'a' => 1
|
166
166
|
}, 'tag_prefix.test')
|
167
|
+
format_check({
|
168
|
+
'a' => 2
|
169
|
+
}, 'tag_prefix.test')
|
167
170
|
|
168
171
|
d = create_driver(Fluent::HandleTagNameMixin, %[
|
169
172
|
add_tag_prefix tag_prefix.
|
@@ -171,6 +174,7 @@ module MixinTest
|
|
171
174
|
])
|
172
175
|
|
173
176
|
d.emit({'a' => 1})
|
177
|
+
d.emit({'a' => 2})
|
174
178
|
d.run
|
175
179
|
end
|
176
180
|
|
@@ -178,6 +182,9 @@ module MixinTest
|
|
178
182
|
format_check({
|
179
183
|
'a' => 1
|
180
184
|
}, 'test.test_suffix')
|
185
|
+
format_check({
|
186
|
+
'a' => 2
|
187
|
+
}, 'test.test_suffix')
|
181
188
|
|
182
189
|
d = create_driver(Fluent::HandleTagNameMixin, %[
|
183
190
|
add_tag_suffix .test_suffix
|
@@ -185,34 +192,43 @@ module MixinTest
|
|
185
192
|
])
|
186
193
|
|
187
194
|
d.emit({'a' => 1})
|
195
|
+
d.emit({'a' => 2})
|
188
196
|
d.run
|
189
197
|
end
|
190
198
|
|
191
199
|
def test_remove_tag_prefix
|
192
200
|
format_check({
|
193
201
|
'a' => 1
|
194
|
-
}, '
|
202
|
+
}, 'test')
|
203
|
+
format_check({
|
204
|
+
'a' => 2
|
205
|
+
}, 'test')
|
195
206
|
|
196
207
|
d = create_driver(Fluent::HandleTagNameMixin, %[
|
197
208
|
remove_tag_prefix te
|
198
209
|
include_tag_key true
|
199
|
-
])
|
210
|
+
], "tetest")
|
200
211
|
|
201
212
|
d.emit({'a' => 1})
|
213
|
+
d.emit({'a' => 2})
|
202
214
|
d.run
|
203
215
|
end
|
204
216
|
|
205
217
|
def test_remove_tag_suffix
|
206
218
|
format_check({
|
207
219
|
'a' => 1
|
208
|
-
}, '
|
220
|
+
}, 'test')
|
221
|
+
format_check({
|
222
|
+
'a' => 2
|
223
|
+
}, 'test')
|
209
224
|
|
210
225
|
d = create_driver(Fluent::HandleTagNameMixin, %[
|
211
226
|
remove_tag_suffix st
|
212
227
|
include_tag_key true
|
213
|
-
])
|
228
|
+
], "testst")
|
214
229
|
|
215
230
|
d.emit({'a' => 1})
|
231
|
+
d.emit({'a' => 2})
|
216
232
|
d.run
|
217
233
|
end
|
218
234
|
|
data/test/parser.rb
CHANGED
@@ -151,12 +151,12 @@ module ParserTest
|
|
151
151
|
|
152
152
|
def test_call
|
153
153
|
parser = TextParser::LabeledTSVParser.new
|
154
|
-
time, record = parser.call("time:
|
154
|
+
time, record = parser.call("time:2013/02/28 12:00:00\thost:192.168.0.1\treq_id:111")
|
155
155
|
|
156
|
+
assert_equal(str2time('2013/02/28 12:00:00', '%Y/%m/%d %H:%M:%S'), time)
|
156
157
|
assert_equal({
|
157
|
-
'
|
158
|
-
'
|
159
|
-
'req' => 'GET /list HTTP/1.1',
|
158
|
+
'host' => '192.168.0.1',
|
159
|
+
'req_id' => '111',
|
160
160
|
}, record)
|
161
161
|
end
|
162
162
|
|
@@ -166,27 +166,27 @@ module ParserTest
|
|
166
166
|
'delimiter' => ',',
|
167
167
|
'label_delimiter' => '=',
|
168
168
|
)
|
169
|
-
time, record = parser.call('time=
|
169
|
+
time, record = parser.call('time=2013/02/28 12:00:00,host=192.168.0.1,req_id=111')
|
170
170
|
|
171
|
+
assert_equal(str2time('2013/02/28 12:00:00', '%Y/%m/%d %H:%M:%S'), time)
|
171
172
|
assert_equal({
|
172
|
-
'
|
173
|
-
'
|
174
|
-
'req' => 'GET /list HTTP/1.1',
|
173
|
+
'host' => '192.168.0.1',
|
174
|
+
'req_id' => '111',
|
175
175
|
}, record)
|
176
176
|
end
|
177
177
|
|
178
178
|
def test_call_with_customized_time_format
|
179
179
|
parser = TextParser::LabeledTSVParser.new
|
180
180
|
parser.configure(
|
181
|
-
'time_key' => '
|
182
|
-
'time_format' => '
|
181
|
+
'time_key' => 'mytime',
|
182
|
+
'time_format' => '%d/%b/%Y:%H:%M:%S %z',
|
183
183
|
)
|
184
|
-
time, record = parser.call("
|
184
|
+
time, record = parser.call("mytime:28/Feb/2013:12:00:00 +0900\thost:192.168.0.1\treq_id:111")
|
185
185
|
|
186
|
+
assert_equal(str2time('28/Feb/2013:12:00:00 +0900', '%d/%b/%Y:%H:%M:%S %z'), time)
|
186
187
|
assert_equal({
|
187
|
-
'
|
188
|
-
'
|
189
|
-
'req' => 'GET /list HTTP/1.1',
|
188
|
+
'host' => '192.168.0.1',
|
189
|
+
'req_id' => '111',
|
190
190
|
}, record)
|
191
191
|
end
|
192
192
|
end
|
data/test/plugin/out_copy.rb
CHANGED
@@ -51,5 +51,42 @@ class CopyOutputTest < Test::Unit::TestCase
|
|
51
51
|
], o.events
|
52
52
|
}
|
53
53
|
end
|
54
|
+
|
55
|
+
def test_msgpack_es_emit_bug
|
56
|
+
d = Fluent::Test::OutputTestDriver.new(Fluent::CopyOutput)
|
57
|
+
|
58
|
+
outputs = %w(p1 p2).map do |pname|
|
59
|
+
p = Fluent::Plugin.new_output('test')
|
60
|
+
p.configure('name' => pname)
|
61
|
+
p.define_singleton_method(:emit) do |tag, es, chain|
|
62
|
+
es.each do |time, record|
|
63
|
+
super(tag, [[time, record]], chain)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
p
|
67
|
+
end
|
68
|
+
|
69
|
+
d.instance.instance_eval { @outputs = outputs }
|
70
|
+
|
71
|
+
es = if defined?(MessagePack::Packer)
|
72
|
+
time = Time.parse("2013-05-26 06:37:22 UTC").to_i
|
73
|
+
packer = MessagePack::Packer.new
|
74
|
+
packer.pack([time, {"a" => 1}])
|
75
|
+
packer.pack([time, {"a" => 2}])
|
76
|
+
Fluent::MessagePackEventStream.new(packer.to_s)
|
77
|
+
else
|
78
|
+
events = "#{[time, {"a" => 1}].to_msgpack}#{[time, {"a" => 2}].to_msgpack}"
|
79
|
+
Fluent::MessagePackEventStream.new(events)
|
80
|
+
end
|
81
|
+
|
82
|
+
d.instance.emit('test', es, Fluent::NullOutputChain.instance)
|
83
|
+
|
84
|
+
d.instance.outputs.each { |o|
|
85
|
+
assert_equal [
|
86
|
+
[time, {"a"=>1}],
|
87
|
+
[time, {"a"=>2}],
|
88
|
+
], o.events
|
89
|
+
}
|
90
|
+
end
|
54
91
|
end
|
55
92
|
|
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.
|
4
|
+
version: 0.10.34
|
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-03
|
12
|
+
date: 2013-06-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: msgpack
|