fluentd 0.10.62 → 0.12.0.pre.1
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -2
- data/.travis.yml +0 -4
- data/ChangeLog +0 -72
- data/Gemfile +0 -6
- data/Rakefile +12 -3
- data/example/in_http.conf +14 -0
- data/example/in_syslog.conf +15 -0
- data/example/in_tail.conf +14 -0
- data/example/in_tcp.conf +13 -0
- data/example/in_udp.conf +13 -0
- data/example/out_copy.conf +20 -0
- data/example/out_file.conf +13 -0
- data/example/out_forward.conf +30 -0
- data/fluent.conf +2 -12
- data/fluentd.gemspec +8 -11
- data/lib/fluent/agent.rb +180 -0
- data/lib/fluent/buffer.rb +6 -12
- data/lib/fluent/command/cat.rb +1 -3
- data/lib/fluent/command/debug.rb +1 -3
- data/lib/fluent/command/fluentd.rb +0 -10
- data/lib/fluent/config.rb +9 -3
- data/lib/fluent/config/basic_parser.rb +1 -6
- data/lib/fluent/config/configure_proxy.rb +25 -61
- data/lib/fluent/config/dsl.rb +16 -0
- data/lib/fluent/config/element.rb +21 -2
- data/lib/fluent/config/error.rb +16 -0
- data/lib/fluent/config/literal_parser.rb +9 -27
- data/lib/fluent/config/parser.rb +16 -0
- data/lib/fluent/config/section.rb +16 -2
- data/lib/fluent/config/types.rb +16 -1
- data/lib/fluent/config/v1_parser.rb +4 -12
- data/lib/fluent/configurable.rb +16 -0
- data/lib/fluent/engine.rb +43 -163
- data/lib/fluent/env.rb +16 -1
- data/lib/fluent/event.rb +20 -48
- data/lib/fluent/event_router.rb +187 -0
- data/lib/fluent/filter.rb +32 -0
- data/lib/fluent/formatter.rb +29 -101
- data/lib/fluent/input.rb +6 -4
- data/lib/fluent/label.rb +18 -0
- data/lib/fluent/load.rb +1 -3
- data/lib/fluent/log.rb +1 -3
- data/lib/fluent/match.rb +12 -19
- data/lib/fluent/mixin.rb +9 -25
- data/lib/fluent/output.rb +27 -45
- data/lib/fluent/parser.rb +93 -99
- data/lib/fluent/plugin.rb +22 -48
- data/lib/fluent/plugin/buf_file.rb +10 -7
- data/lib/fluent/plugin/buf_memory.rb +2 -3
- data/lib/fluent/plugin/buf_zfile.rb +75 -0
- data/lib/fluent/plugin/exec_util.rb +16 -0
- data/lib/fluent/plugin/in_debug_agent.rb +2 -3
- data/lib/fluent/plugin/in_exec.rb +2 -9
- data/lib/fluent/plugin/in_forward.rb +4 -22
- data/lib/fluent/plugin/in_gc_stat.rb +2 -3
- data/lib/fluent/plugin/in_http.rb +19 -59
- data/lib/fluent/plugin/in_monitor_agent.rb +21 -47
- data/lib/fluent/plugin/in_object_space.rb +2 -3
- data/lib/fluent/plugin/in_status.rb +2 -3
- data/lib/fluent/plugin/in_stream.rb +6 -16
- data/lib/fluent/plugin/in_syslog.rb +8 -17
- data/lib/fluent/plugin/in_tail.rb +17 -24
- data/lib/fluent/plugin/in_tcp.rb +16 -0
- data/lib/fluent/plugin/in_udp.rb +16 -0
- data/lib/fluent/plugin/out_copy.rb +3 -4
- data/lib/fluent/plugin/out_exec.rb +2 -4
- data/lib/fluent/plugin/out_exec_filter.rb +2 -13
- data/lib/fluent/plugin/out_file.rb +5 -6
- data/lib/fluent/plugin/out_forward.rb +4 -5
- data/lib/fluent/plugin/out_null.rb +2 -3
- data/lib/fluent/plugin/out_relabel.rb +26 -0
- data/lib/fluent/plugin/out_roundrobin.rb +3 -4
- data/lib/fluent/plugin/out_stdout.rb +2 -3
- data/lib/fluent/plugin/out_stream.rb +2 -3
- data/{test/scripts → lib}/fluent/plugin/out_test.rb +2 -3
- data/lib/fluent/plugin/socket_util.rb +19 -10
- data/lib/fluent/process.rb +4 -6
- data/lib/fluent/registry.rb +16 -0
- data/lib/fluent/root_agent.rb +212 -0
- data/lib/fluent/status.rb +2 -3
- data/lib/fluent/supervisor.rb +33 -54
- data/lib/fluent/test.rb +16 -0
- data/lib/fluent/test/base.rb +3 -17
- data/lib/fluent/test/input_test.rb +52 -7
- data/lib/fluent/test/output_test.rb +4 -20
- data/lib/fluent/version.rb +17 -1
- data/spec/config/config_parser_spec.rb +314 -0
- data/spec/config/configurable_spec.rb +524 -0
- data/spec/config/configure_proxy_spec.rb +96 -0
- data/spec/config/dsl_spec.rb +239 -0
- data/spec/config/helper.rb +49 -0
- data/spec/config/literal_parser_spec.rb +222 -0
- data/spec/config/section_spec.rb +97 -0
- data/spec/config/system_config_spec.rb +49 -0
- data/test/helper.rb +0 -25
- data/test/plugin/test_in_exec.rb +1 -1
- data/test/plugin/test_in_forward.rb +2 -1
- data/test/plugin/test_in_gc_stat.rb +1 -1
- data/test/plugin/test_in_http.rb +3 -78
- data/test/plugin/test_in_object_space.rb +1 -1
- data/test/plugin/test_in_status.rb +1 -1
- data/test/plugin/test_in_stream.rb +2 -1
- data/test/plugin/test_in_syslog.rb +2 -1
- data/test/plugin/test_in_tail.rb +6 -11
- data/test/plugin/test_in_tcp.rb +2 -1
- data/test/plugin/test_in_udp.rb +2 -1
- data/test/plugin/test_out_copy.rb +1 -12
- data/test/plugin/test_out_exec.rb +1 -1
- data/test/plugin/test_out_exec_filter.rb +1 -1
- data/test/plugin/test_out_file.rb +7 -96
- data/test/plugin/test_out_forward.rb +2 -1
- data/test/plugin/test_out_roundrobin.rb +1 -12
- data/test/plugin/test_out_stdout.rb +1 -1
- data/test/plugin/test_out_stream.rb +2 -1
- data/test/scripts/fluent/plugin/formatter_known.rb +1 -4
- data/test/scripts/fluent/plugin/parser_known.rb +1 -2
- data/test/test_config.rb +1 -1
- data/test/test_configdsl.rb +2 -1
- data/test/test_formatter.rb +3 -395
- data/test/test_match.rb +2 -1
- data/test/test_mixin.rb +3 -75
- data/test/test_output.rb +1 -112
- data/test/test_parser.rb +85 -152
- metadata +58 -167
- data/example/v1_literal_example.conf +0 -36
- data/lib/fluent/plugin/in_dummy.rb +0 -103
- data/lib/fluent/timezone.rb +0 -131
- data/test/config/assertions.rb +0 -42
- data/test/config/test_config_parser.rb +0 -389
- data/test/config/test_configurable.rb +0 -652
- data/test/config/test_configure_proxy.rb +0 -99
- data/test/config/test_dsl.rb +0 -237
- data/test/config/test_literal_parser.rb +0 -295
- data/test/config/test_section.rb +0 -112
- data/test/config/test_system_config.rb +0 -99
- data/test/config/test_types.rb +0 -63
- data/test/plugin/test_in_dummy.rb +0 -95
- data/test/test_event.rb +0 -168
- data/test/test_input.rb +0 -21
data/lib/fluent/input.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
#
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# Copyright (C) 2011 FURUHASHI Sadayuki
|
2
|
+
# Fluentd
|
5
3
|
#
|
6
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
5
|
# you may not use this file except in compliance with the License.
|
@@ -15,6 +13,7 @@
|
|
15
13
|
# See the License for the specific language governing permissions and
|
16
14
|
# limitations under the License.
|
17
15
|
#
|
16
|
+
|
18
17
|
module Fluent
|
19
18
|
class Input
|
20
19
|
include Configurable
|
@@ -30,7 +29,10 @@ module Fluent
|
|
30
29
|
def configure(conf)
|
31
30
|
super
|
32
31
|
|
33
|
-
|
32
|
+
if label_name = conf['@label']
|
33
|
+
label = Engine.root_agent.find_label(label_name)
|
34
|
+
@router = label.event_router
|
35
|
+
end
|
34
36
|
end
|
35
37
|
|
36
38
|
def start
|
data/lib/fluent/label.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Fluent
|
2
|
+
require 'fluent/agent'
|
3
|
+
|
4
|
+
class Label < Agent
|
5
|
+
def initialize(name, opts = {})
|
6
|
+
super(opts)
|
7
|
+
|
8
|
+
@context = name
|
9
|
+
@root_agent = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor :root_agent
|
13
|
+
|
14
|
+
def handle_emits_error(tag, es, e)
|
15
|
+
@root_agent.handle_emits_error(tag, es, e)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/fluent/load.rb
CHANGED
@@ -14,9 +14,6 @@ begin
|
|
14
14
|
rescue
|
15
15
|
# ignore setup error on Win or similar platform which doesn't support signal
|
16
16
|
end
|
17
|
-
# I hate global variable but we suffer pain now for the sake of future.
|
18
|
-
# We will switch to MessagePack 0.5 and deprecate 0.4.
|
19
|
-
$use_msgpack_5 = defined?(MessagePack::Packer) ? true : false
|
20
17
|
require 'cool.io'
|
21
18
|
require 'fluent/env'
|
22
19
|
require 'fluent/version'
|
@@ -33,4 +30,5 @@ require 'fluent/event'
|
|
33
30
|
require 'fluent/buffer'
|
34
31
|
require 'fluent/input'
|
35
32
|
require 'fluent/output'
|
33
|
+
require 'fluent/filter'
|
36
34
|
require 'fluent/match'
|
data/lib/fluent/log.rb
CHANGED
data/lib/fluent/match.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
#
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# Copyright (C) 2011 FURUHASHI Sadayuki
|
2
|
+
# Fluentd
|
5
3
|
#
|
6
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
5
|
# you may not use this file except in compliance with the License.
|
@@ -15,6 +13,7 @@
|
|
15
13
|
# See the License for the specific language governing permissions and
|
16
14
|
# limitations under the License.
|
17
15
|
#
|
16
|
+
|
18
17
|
module Fluent
|
19
18
|
class Match
|
20
19
|
def initialize(pattern_str, output)
|
@@ -52,26 +51,21 @@ module Fluent
|
|
52
51
|
end
|
53
52
|
end
|
54
53
|
|
55
|
-
|
56
54
|
class MatchPattern
|
57
55
|
def self.create(str)
|
58
|
-
|
56
|
+
if str == '**'
|
57
|
+
AllMatchPattern.new
|
58
|
+
else
|
59
|
+
GlobMatchPattern.new(str)
|
60
|
+
end
|
59
61
|
end
|
60
|
-
|
61
|
-
#def match(str)
|
62
|
-
#end
|
63
62
|
end
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
#
|
71
|
-
# def match(str)
|
72
|
-
# @regex.match(str) != nil
|
73
|
-
# end
|
74
|
-
#end
|
64
|
+
class AllMatchPattern < MatchPattern
|
65
|
+
def match(str)
|
66
|
+
true
|
67
|
+
end
|
68
|
+
end
|
75
69
|
|
76
70
|
class GlobMatchPattern < MatchPattern
|
77
71
|
def initialize(pat)
|
@@ -171,7 +165,6 @@ module Fluent
|
|
171
165
|
end
|
172
166
|
end
|
173
167
|
|
174
|
-
|
175
168
|
class OrMatchPattern < MatchPattern
|
176
169
|
def initialize(patterns)
|
177
170
|
@patterns = patterns
|
data/lib/fluent/mixin.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
#
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# Copyright (C) 2011 FURUHASHI Sadayuki
|
2
|
+
# Fluentd
|
5
3
|
#
|
6
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
5
|
# you may not use this file except in compliance with the License.
|
@@ -15,23 +13,15 @@
|
|
15
13
|
# See the License for the specific language governing permissions and
|
16
14
|
# limitations under the License.
|
17
15
|
#
|
16
|
+
|
18
17
|
module Fluent
|
19
18
|
class TimeFormatter
|
20
|
-
|
21
|
-
|
22
|
-
def initialize(format, localtime, timezone = nil)
|
19
|
+
def initialize(format, localtime)
|
23
20
|
@tc1 = 0
|
24
21
|
@tc1_str = nil
|
25
22
|
@tc2 = 0
|
26
23
|
@tc2_str = nil
|
27
24
|
|
28
|
-
if formatter = Fluent::Timezone.formatter(timezone, format)
|
29
|
-
define_singleton_method(:format_nocache) {|time|
|
30
|
-
formatter.call(time)
|
31
|
-
}
|
32
|
-
return
|
33
|
-
end
|
34
|
-
|
35
25
|
if format
|
36
26
|
if localtime
|
37
27
|
define_singleton_method(:format_nocache) {|time|
|
@@ -122,16 +112,15 @@ module Fluent
|
|
122
112
|
end
|
123
113
|
|
124
114
|
module SetTimeKeyMixin
|
125
|
-
require 'fluent/timezone'
|
126
115
|
include RecordFilterMixin
|
127
116
|
|
128
|
-
attr_accessor :include_time_key, :time_key, :localtime
|
117
|
+
attr_accessor :include_time_key, :time_key, :localtime
|
129
118
|
|
130
119
|
def configure(conf)
|
131
|
-
@include_time_key = false
|
132
|
-
|
133
120
|
super
|
134
121
|
|
122
|
+
@include_time_key = false
|
123
|
+
|
135
124
|
if s = conf['include_time_key']
|
136
125
|
include_time_key = Config.bool_value(s)
|
137
126
|
raise ConfigError, "Invalid boolean expression '#{s}' for include_time_key parameter" if include_time_key.nil?
|
@@ -149,12 +138,7 @@ module Fluent
|
|
149
138
|
@localtime = false
|
150
139
|
end
|
151
140
|
|
152
|
-
|
153
|
-
@timezone = conf['timezone']
|
154
|
-
Fluent::Timezone.validate!(@timezone)
|
155
|
-
end
|
156
|
-
|
157
|
-
@timef = TimeFormatter.new(@time_format, @localtime, @timezone)
|
141
|
+
@timef = TimeFormatter.new(@time_format, @localtime)
|
158
142
|
end
|
159
143
|
end
|
160
144
|
|
@@ -171,10 +155,10 @@ module Fluent
|
|
171
155
|
attr_accessor :include_tag_key, :tag_key
|
172
156
|
|
173
157
|
def configure(conf)
|
174
|
-
@include_tag_key = false
|
175
|
-
|
176
158
|
super
|
177
159
|
|
160
|
+
@include_tag_key = false
|
161
|
+
|
178
162
|
if s = conf['include_tag_key']
|
179
163
|
include_tag_key = Config.bool_value(s)
|
180
164
|
raise ConfigError, "Invalid boolean expression '#{s}' for include_tag_key parameter" if include_tag_key.nil?
|
data/lib/fluent/output.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
#
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# Copyright (C) 2011 FURUHASHI Sadayuki
|
2
|
+
# Fluentd
|
5
3
|
#
|
6
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
5
|
# you may not use this file except in compliance with the License.
|
@@ -15,6 +13,7 @@
|
|
15
13
|
# See the License for the specific language governing permissions and
|
16
14
|
# limitations under the License.
|
17
15
|
#
|
16
|
+
|
18
17
|
module Fluent
|
19
18
|
class OutputChain
|
20
19
|
def initialize(array, tag, es, chain=NullOutputChain.instance)
|
@@ -70,7 +69,10 @@ module Fluent
|
|
70
69
|
def configure(conf)
|
71
70
|
super
|
72
71
|
|
73
|
-
|
72
|
+
if label_name = conf['@label']
|
73
|
+
label = Engine.root_agent.find_label(label_name)
|
74
|
+
@router = label.event_router
|
75
|
+
end
|
74
76
|
end
|
75
77
|
|
76
78
|
def start
|
@@ -94,7 +96,7 @@ module Fluent
|
|
94
96
|
def initialize(output)
|
95
97
|
@output = output
|
96
98
|
@finish = false
|
97
|
-
@next_time =
|
99
|
+
@next_time = Engine.now + 1.0
|
98
100
|
end
|
99
101
|
|
100
102
|
def configure(conf)
|
@@ -128,7 +130,7 @@ module Fluent
|
|
128
130
|
@mutex.lock
|
129
131
|
begin
|
130
132
|
until @finish
|
131
|
-
time =
|
133
|
+
time = Engine.now
|
132
134
|
|
133
135
|
if @next_time <= time
|
134
136
|
@mutex.unlock
|
@@ -137,7 +139,7 @@ module Fluent
|
|
137
139
|
ensure
|
138
140
|
@mutex.lock
|
139
141
|
end
|
140
|
-
next_wait = @next_time -
|
142
|
+
next_wait = @next_time - Engine.now
|
141
143
|
else
|
142
144
|
next_wait = @next_time - time
|
143
145
|
end
|
@@ -188,7 +190,6 @@ module Fluent
|
|
188
190
|
def configure(conf)
|
189
191
|
super
|
190
192
|
|
191
|
-
@retry_wait = @retry_wait.to_f # converted to Float for calc_retry_wait
|
192
193
|
@buffer = Plugin.new_buffer(@buffer_type)
|
193
194
|
@buffer.configure(conf)
|
194
195
|
|
@@ -207,7 +208,7 @@ module Fluent
|
|
207
208
|
}
|
208
209
|
|
209
210
|
if sconf = conf.elements.select {|e| e.name == 'secondary' }.first
|
210
|
-
type = sconf['
|
211
|
+
type = sconf['type'] || conf['type']
|
211
212
|
@secondary = Plugin.new_output(type)
|
212
213
|
@secondary.configure(sconf)
|
213
214
|
|
@@ -226,7 +227,7 @@ module Fluent
|
|
226
227
|
end
|
227
228
|
|
228
229
|
def start
|
229
|
-
@next_flush_time =
|
230
|
+
@next_flush_time = Engine.now + @flush_interval
|
230
231
|
@buffer.start
|
231
232
|
@secondary.start if @secondary
|
232
233
|
@writers.each {|writer| writer.start }
|
@@ -268,17 +269,17 @@ module Fluent
|
|
268
269
|
#def write(chunk)
|
269
270
|
#end
|
270
271
|
|
271
|
-
def enqueue_buffer
|
272
|
+
def enqueue_buffer
|
272
273
|
@buffer.keys.each {|key|
|
273
274
|
@buffer.push(key)
|
274
275
|
}
|
275
276
|
end
|
276
277
|
|
277
278
|
def try_flush
|
278
|
-
time =
|
279
|
+
time = Engine.now
|
279
280
|
|
280
281
|
empty = @buffer.queue_size == 0
|
281
|
-
if empty && @next_flush_time < (now =
|
282
|
+
if empty && @next_flush_time < (now = Engine.now)
|
282
283
|
@buffer.synchronize do
|
283
284
|
if @next_flush_time < now
|
284
285
|
enqueue_buffer
|
@@ -321,11 +322,11 @@ module Fluent
|
|
321
322
|
@num_errors = 0
|
322
323
|
# Note: don't notify to other threads to prevent
|
323
324
|
# burst to recovered server
|
324
|
-
$log.warn "retry succeeded.", :
|
325
|
+
$log.warn "retry succeeded.", :instance=>object_id
|
325
326
|
end
|
326
327
|
|
327
328
|
if has_next
|
328
|
-
return
|
329
|
+
return Engine.now + @queued_chunk_flush_interval
|
329
330
|
else
|
330
331
|
return time + @try_flush_interval
|
331
332
|
end
|
@@ -346,20 +347,20 @@ module Fluent
|
|
346
347
|
end
|
347
348
|
|
348
349
|
if @disable_retry_limit || error_count < @retry_limit
|
349
|
-
$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, :
|
350
|
+
$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
|
350
351
|
$log.warn_backtrace e.backtrace
|
351
352
|
|
352
353
|
elsif @secondary
|
353
354
|
if error_count == @retry_limit
|
354
|
-
$log.warn "failed to flush the buffer.", :error_class=>e.class.to_s, :error=>e.to_s, :
|
355
|
+
$log.warn "failed to flush the buffer.", :error_class=>e.class.to_s, :error=>e.to_s, :instance=>object_id
|
355
356
|
$log.warn "retry count exceededs limit. falling back to secondary output."
|
356
357
|
$log.warn_backtrace e.backtrace
|
357
358
|
retry # retry immediately
|
358
359
|
elsif error_count <= @retry_limit + @secondary_limit
|
359
|
-
$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, :
|
360
|
+
$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
|
360
361
|
$log.warn_backtrace e.backtrace
|
361
362
|
else
|
362
|
-
$log.warn "failed to flush the buffer.", :error_class=>e.class, :error=>e.to_s, :
|
363
|
+
$log.warn "failed to flush the buffer.", :error_class=>e.class, :error=>e.to_s, :instance=>object_id
|
363
364
|
$log.warn "secondary retry count exceededs limit."
|
364
365
|
$log.warn_backtrace e.backtrace
|
365
366
|
write_abort
|
@@ -367,7 +368,7 @@ module Fluent
|
|
367
368
|
end
|
368
369
|
|
369
370
|
else
|
370
|
-
$log.warn "failed to flush the buffer.", :error_class=>e.class.to_s, :error=>e.to_s, :
|
371
|
+
$log.warn "failed to flush the buffer.", :error_class=>e.class.to_s, :error=>e.to_s, :instance=>object_id
|
371
372
|
$log.warn "retry count exceededs limit."
|
372
373
|
$log.warn_backtrace e.backtrace
|
373
374
|
write_abort
|
@@ -379,10 +380,7 @@ module Fluent
|
|
379
380
|
end
|
380
381
|
|
381
382
|
def force_flush
|
382
|
-
|
383
|
-
@next_retry_time = Time.now.to_f - 1
|
384
|
-
end
|
385
|
-
enqueue_buffer(true)
|
383
|
+
enqueue_buffer
|
386
384
|
submit_flush
|
387
385
|
end
|
388
386
|
|
@@ -403,7 +401,7 @@ module Fluent
|
|
403
401
|
# secondary retry
|
404
402
|
@retry_wait * (2 ** (@num_errors - 2 - @retry_limit))
|
405
403
|
end
|
406
|
-
retry_wait = wait
|
404
|
+
retry_wait = wait + (rand * (wait / 4.0) - (wait / 8.0))
|
407
405
|
@max_retry_wait ? [retry_wait, @max_retry_wait].min : retry_wait
|
408
406
|
end
|
409
407
|
|
@@ -461,8 +459,6 @@ module Fluent
|
|
461
459
|
|
462
460
|
|
463
461
|
class TimeSlicedOutput < BufferedOutput
|
464
|
-
require 'fluent/timezone'
|
465
|
-
|
466
462
|
def initialize
|
467
463
|
super
|
468
464
|
@localtime = true
|
@@ -471,31 +467,23 @@ module Fluent
|
|
471
467
|
|
472
468
|
config_param :time_slice_format, :string, :default => '%Y%m%d'
|
473
469
|
config_param :time_slice_wait, :time, :default => 10*60
|
474
|
-
config_param :timezone, :string, :default => nil
|
475
470
|
config_set_default :buffer_type, 'file' # overwrite default buffer_type
|
476
471
|
config_set_default :buffer_chunk_limit, 256*1024*1024 # overwrite default buffer_chunk_limit
|
477
472
|
config_set_default :flush_interval, nil
|
478
473
|
|
479
474
|
attr_accessor :localtime
|
480
|
-
attr_reader :time_slicer # for test
|
481
475
|
|
482
476
|
def configure(conf)
|
483
477
|
super
|
484
478
|
|
479
|
+
# TODO timezone
|
485
480
|
if conf['utc']
|
486
481
|
@localtime = false
|
487
482
|
elsif conf['localtime']
|
488
483
|
@localtime = true
|
489
484
|
end
|
490
485
|
|
491
|
-
if
|
492
|
-
@timezone = conf['timezone']
|
493
|
-
Fluent::Timezone.validate!(@timezone)
|
494
|
-
end
|
495
|
-
|
496
|
-
if @timezone
|
497
|
-
@time_slicer = Timezone.formatter(@timezone, @time_slice_format)
|
498
|
-
elsif @localtime
|
486
|
+
if @localtime
|
499
487
|
@time_slicer = Proc.new {|time|
|
500
488
|
Time.at(time).strftime(@time_slice_format)
|
501
489
|
}
|
@@ -550,14 +538,8 @@ module Fluent
|
|
550
538
|
}
|
551
539
|
end
|
552
540
|
|
553
|
-
def enqueue_buffer
|
554
|
-
|
555
|
-
@buffer.keys.each {|key|
|
556
|
-
@buffer.push(key)
|
557
|
-
}
|
558
|
-
else
|
559
|
-
@enqueue_buffer_proc.call
|
560
|
-
end
|
541
|
+
def enqueue_buffer
|
542
|
+
@enqueue_buffer_proc.call
|
561
543
|
end
|
562
544
|
|
563
545
|
#def format(tag, event)
|
data/lib/fluent/parser.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
#
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# Copyright (C) 2011 FURUHASHI Sadayuki
|
2
|
+
# Fluentd
|
5
3
|
#
|
6
4
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
5
|
# you may not use this file except in compliance with the License.
|
@@ -15,42 +13,11 @@
|
|
15
13
|
# See the License for the specific language governing permissions and
|
16
14
|
# limitations under the License.
|
17
15
|
#
|
16
|
+
|
18
17
|
module Fluent
|
19
18
|
require 'fluent/registry'
|
20
19
|
|
21
|
-
class ParserError < StandardError
|
22
|
-
end
|
23
|
-
|
24
|
-
class Parser
|
25
|
-
include Configurable
|
26
|
-
|
27
|
-
# SET false BEFORE CONFIGURE, to return nil when time not parsed
|
28
|
-
# 'configure()' may raise errors for unexpected configurations
|
29
|
-
attr_accessor :estimate_current_event
|
30
|
-
|
31
|
-
def initialize
|
32
|
-
super
|
33
|
-
@estimate_current_event = true
|
34
|
-
end
|
35
|
-
|
36
|
-
def configure(conf)
|
37
|
-
super
|
38
|
-
end
|
39
|
-
|
40
|
-
def parse(text)
|
41
|
-
raise NotImplementedError, "Implement this method in child class"
|
42
|
-
end
|
43
|
-
|
44
|
-
# Keep backward compatibility for existing plugins
|
45
|
-
def call(*a, &b)
|
46
|
-
parse(*a, &b)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
20
|
class TextParser
|
51
|
-
# Keep backward compatibility for existing plugins
|
52
|
-
ParserError = ::Fluent::ParserError
|
53
|
-
|
54
21
|
class TimeParser
|
55
22
|
def initialize(time_format)
|
56
23
|
@cache1_key = nil
|
@@ -67,7 +34,7 @@ module Fluent
|
|
67
34
|
|
68
35
|
def parse(value)
|
69
36
|
unless value.is_a?(String)
|
70
|
-
raise
|
37
|
+
raise ArgumentError, "Value must be string: #{value}"
|
71
38
|
end
|
72
39
|
|
73
40
|
if @cache1_key == value
|
@@ -75,11 +42,7 @@ module Fluent
|
|
75
42
|
elsif @cache2_key == value
|
76
43
|
return @cache2_time
|
77
44
|
else
|
78
|
-
|
79
|
-
time = @parser.call(value).to_i
|
80
|
-
rescue => e
|
81
|
-
raise ParserError, "invalid time format: value = #{value}, error_class = #{e.class.name}, error = #{e.message}"
|
82
|
-
end
|
45
|
+
time = @parser.call(value).to_i
|
83
46
|
@cache1_key = @cache2_key
|
84
47
|
@cache1_time = @cache2_time
|
85
48
|
@cache2_key = value
|
@@ -158,11 +121,16 @@ module Fluent
|
|
158
121
|
end
|
159
122
|
end
|
160
123
|
|
161
|
-
class RegexpParser
|
124
|
+
class RegexpParser
|
125
|
+
include Configurable
|
162
126
|
include TypeConverter
|
163
127
|
|
164
128
|
config_param :time_format, :string, :default => nil
|
165
129
|
|
130
|
+
# SET false BEFORE CONFIGURE, to return nil when time not parsed
|
131
|
+
# 'configure()' may raise errors for unexpected configurations
|
132
|
+
attr_accessor :estimate_current_event
|
133
|
+
|
166
134
|
def initialize(regexp, conf={})
|
167
135
|
super()
|
168
136
|
@regexp = regexp
|
@@ -171,6 +139,7 @@ module Fluent
|
|
171
139
|
end
|
172
140
|
|
173
141
|
@time_parser = TimeParser.new(@time_format)
|
142
|
+
@estimate_current_event = true
|
174
143
|
@mutex = Mutex.new
|
175
144
|
end
|
176
145
|
|
@@ -183,7 +152,7 @@ module Fluent
|
|
183
152
|
{'format' => @regexp, 'time_format' => @time_format}
|
184
153
|
end
|
185
154
|
|
186
|
-
def
|
155
|
+
def call(text)
|
187
156
|
m = @regexp.match(text)
|
188
157
|
unless m
|
189
158
|
if block_given?
|
@@ -224,10 +193,21 @@ module Fluent
|
|
224
193
|
end
|
225
194
|
end
|
226
195
|
|
227
|
-
class JSONParser
|
196
|
+
class JSONParser
|
197
|
+
include Configurable
|
198
|
+
|
228
199
|
config_param :time_key, :string, :default => 'time'
|
229
200
|
config_param :time_format, :string, :default => nil
|
230
201
|
|
202
|
+
# SET false BEFORE CONFIGURE, to return nil when time not parsed
|
203
|
+
# 'configure()' may raise errors for unexpected configurations
|
204
|
+
attr_accessor :estimate_current_event
|
205
|
+
|
206
|
+
def initialize
|
207
|
+
super
|
208
|
+
@estimate_current_event = true
|
209
|
+
end
|
210
|
+
|
231
211
|
def configure(conf)
|
232
212
|
super
|
233
213
|
|
@@ -237,18 +217,14 @@ module Fluent
|
|
237
217
|
end
|
238
218
|
end
|
239
219
|
|
240
|
-
def
|
220
|
+
def call(text)
|
241
221
|
record = Yajl.load(text)
|
242
222
|
|
243
223
|
if value = record.delete(@time_key)
|
244
224
|
if @time_format
|
245
225
|
time = @mutex.synchronize { @time_parser.parse(value) }
|
246
226
|
else
|
247
|
-
|
248
|
-
time = value.to_i
|
249
|
-
rescue => e
|
250
|
-
raise ParserError, "invalid time value: value = #{value}, error_class = #{e.class.name}, error = #{e.message}"
|
251
|
-
end
|
227
|
+
time = value.to_i
|
252
228
|
end
|
253
229
|
else
|
254
230
|
if @estimate_current_event
|
@@ -272,13 +248,21 @@ module Fluent
|
|
272
248
|
end
|
273
249
|
end
|
274
250
|
|
275
|
-
class ValuesParser
|
251
|
+
class ValuesParser
|
252
|
+
include Configurable
|
276
253
|
include TypeConverter
|
277
254
|
|
278
255
|
config_param :keys, :string
|
279
256
|
config_param :time_key, :string, :default => nil
|
280
257
|
config_param :time_format, :string, :default => nil
|
281
258
|
|
259
|
+
attr_accessor :estimate_current_event
|
260
|
+
|
261
|
+
def initialize
|
262
|
+
super
|
263
|
+
@estimate_current_event = true
|
264
|
+
end
|
265
|
+
|
282
266
|
def configure(conf)
|
283
267
|
super
|
284
268
|
|
@@ -335,16 +319,11 @@ module Fluent
|
|
335
319
|
class TSVParser < ValuesParser
|
336
320
|
config_param :delimiter, :string, :default => "\t"
|
337
321
|
|
338
|
-
def
|
339
|
-
super
|
340
|
-
@key_num = @keys.length
|
341
|
-
end
|
342
|
-
|
343
|
-
def parse(text)
|
322
|
+
def call(text)
|
344
323
|
if block_given?
|
345
|
-
yield values_map(text.split(@delimiter
|
324
|
+
yield values_map(text.split(@delimiter))
|
346
325
|
else
|
347
|
-
return values_map(text.split(@delimiter
|
326
|
+
return values_map(text.split(@delimiter))
|
348
327
|
end
|
349
328
|
end
|
350
329
|
end
|
@@ -359,7 +338,7 @@ module Fluent
|
|
359
338
|
super(conf)
|
360
339
|
end
|
361
340
|
|
362
|
-
def
|
341
|
+
def call(text)
|
363
342
|
@keys = []
|
364
343
|
values = []
|
365
344
|
|
@@ -383,7 +362,7 @@ module Fluent
|
|
383
362
|
require 'csv'
|
384
363
|
end
|
385
364
|
|
386
|
-
def
|
365
|
+
def call(text)
|
387
366
|
if block_given?
|
388
367
|
yield values_map(CSV.parse_line(text))
|
389
368
|
else
|
@@ -392,10 +371,19 @@ module Fluent
|
|
392
371
|
end
|
393
372
|
end
|
394
373
|
|
395
|
-
class NoneParser
|
374
|
+
class NoneParser
|
375
|
+
include Configurable
|
376
|
+
|
396
377
|
config_param :message_key, :string, :default => 'message'
|
397
378
|
|
398
|
-
|
379
|
+
attr_accessor :estimate_current_event
|
380
|
+
|
381
|
+
def initialize
|
382
|
+
super
|
383
|
+
@estimate_current_event = true
|
384
|
+
end
|
385
|
+
|
386
|
+
def call(text)
|
399
387
|
record = {}
|
400
388
|
record[@message_key] = text
|
401
389
|
time = @estimate_current_event ? Engine.now : nil
|
@@ -407,12 +395,13 @@ module Fluent
|
|
407
395
|
end
|
408
396
|
end
|
409
397
|
|
410
|
-
class ApacheParser
|
411
|
-
|
398
|
+
class ApacheParser
|
399
|
+
include Configurable
|
400
|
+
|
401
|
+
REGEXP = /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^ ]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
|
412
402
|
TIME_FORMAT = "%d/%b/%Y:%H:%M:%S %z"
|
413
403
|
|
414
404
|
def initialize
|
415
|
-
super
|
416
405
|
@time_parser = TimeParser.new(TIME_FORMAT)
|
417
406
|
@mutex = Mutex.new
|
418
407
|
end
|
@@ -421,7 +410,7 @@ module Fluent
|
|
421
410
|
{'format' => REGEXP, 'time_format' => TIME_FORMAT}
|
422
411
|
end
|
423
412
|
|
424
|
-
def
|
413
|
+
def call(text)
|
425
414
|
m = REGEXP.match(text)
|
426
415
|
unless m
|
427
416
|
if block_given?
|
@@ -475,7 +464,9 @@ module Fluent
|
|
475
464
|
end
|
476
465
|
end
|
477
466
|
|
478
|
-
class SyslogParser
|
467
|
+
class SyslogParser
|
468
|
+
include Configurable
|
469
|
+
|
479
470
|
# From existence TextParser pattern
|
480
471
|
REGEXP = /^(?<time>[^ ]*\s*[^ ]* [^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[0-9]+)\])?(?:[^\:]*\:)? *(?<message>.*)$/
|
481
472
|
# From in_syslog default pattern
|
@@ -484,8 +475,11 @@ module Fluent
|
|
484
475
|
config_param :time_format, :string, :default => "%b %d %H:%M:%S"
|
485
476
|
config_param :with_priority, :bool, :default => false
|
486
477
|
|
478
|
+
attr_accessor :estimate_current_event
|
479
|
+
|
487
480
|
def initialize
|
488
481
|
super
|
482
|
+
@estimate_current_event = true
|
489
483
|
@mutex = Mutex.new
|
490
484
|
end
|
491
485
|
|
@@ -500,7 +494,7 @@ module Fluent
|
|
500
494
|
{'format' => @regexp, 'time_format' => @time_format}
|
501
495
|
end
|
502
496
|
|
503
|
-
def
|
497
|
+
def call(text)
|
504
498
|
m = @regexp.match(text)
|
505
499
|
unless m
|
506
500
|
if block_given?
|
@@ -539,7 +533,9 @@ module Fluent
|
|
539
533
|
end
|
540
534
|
end
|
541
535
|
|
542
|
-
class MultilineParser
|
536
|
+
class MultilineParser
|
537
|
+
include Configurable
|
538
|
+
|
543
539
|
config_param :format_firstline, :string, :default => nil
|
544
540
|
|
545
541
|
FORMAT_MAX_NUM = 20
|
@@ -564,7 +560,7 @@ module Fluent
|
|
564
560
|
end
|
565
561
|
end
|
566
562
|
|
567
|
-
def
|
563
|
+
def call(text, &block)
|
568
564
|
if block
|
569
565
|
@parser.call(text, &block)
|
570
566
|
else
|
@@ -632,7 +628,7 @@ module Fluent
|
|
632
628
|
'tsv' => Proc.new { TSVParser.new },
|
633
629
|
'ltsv' => Proc.new { LabeledTSVParser.new },
|
634
630
|
'csv' => Proc.new { CSVParser.new },
|
635
|
-
'nginx' => Proc.new { RegexpParser.new(/^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]
|
631
|
+
'nginx' => Proc.new { RegexpParser.new(/^(?<remote>[^ ]*) (?<host>[^ ]*) (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*) +\S*)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/, {'time_format'=>"%d/%b/%Y:%H:%M:%S %z"}) },
|
636
632
|
'none' => Proc.new { NoneParser.new },
|
637
633
|
'multiline' => Proc.new { MultilineParser.new },
|
638
634
|
}.each { |name, factory|
|
@@ -640,9 +636,7 @@ module Fluent
|
|
640
636
|
}
|
641
637
|
|
642
638
|
def self.register_template(name, regexp_or_proc, time_format=nil)
|
643
|
-
if regexp_or_proc.is_a?(
|
644
|
-
factory = Proc.new { regexp_or_proc.new }
|
645
|
-
elsif regexp_or_proc.is_a?(Regexp)
|
639
|
+
if regexp_or_proc.is_a?(Regexp)
|
646
640
|
regexp = regexp_or_proc
|
647
641
|
factory = Proc.new { RegexpParser.new(regexp, {'time_format'=>time_format}) }
|
648
642
|
else
|
@@ -652,9 +646,26 @@ module Fluent
|
|
652
646
|
TEMPLATE_REGISTRY.register(name, factory)
|
653
647
|
end
|
654
648
|
|
655
|
-
def
|
656
|
-
|
657
|
-
|
649
|
+
def initialize
|
650
|
+
@parser = nil
|
651
|
+
@estimate_current_event = nil
|
652
|
+
end
|
653
|
+
|
654
|
+
attr_reader :parser
|
655
|
+
|
656
|
+
# SET false BEFORE CONFIGURE, to return nil when time not parsed
|
657
|
+
# 'configure()' may raise errors for unexpected configurations
|
658
|
+
attr_accessor :estimate_current_event
|
659
|
+
|
660
|
+
def configure(conf, required=true)
|
661
|
+
format = conf['format']
|
662
|
+
|
663
|
+
if format == nil
|
664
|
+
if required
|
665
|
+
raise ConfigError, "'format' parameter is required"
|
666
|
+
else
|
667
|
+
return nil
|
668
|
+
end
|
658
669
|
end
|
659
670
|
|
660
671
|
if format[0] == ?/ && format[format.length-1] == ?/
|
@@ -668,7 +679,7 @@ module Fluent
|
|
668
679
|
raise ConfigError, "Invalid regexp '#{format[1..-2]}': #{$!}"
|
669
680
|
end
|
670
681
|
|
671
|
-
RegexpParser.new(regexp)
|
682
|
+
@parser = RegexpParser.new(regexp, conf)
|
672
683
|
else
|
673
684
|
# built-in template
|
674
685
|
begin
|
@@ -676,26 +687,9 @@ module Fluent
|
|
676
687
|
rescue ConfigError => e # keep same error message
|
677
688
|
raise ConfigError, "Unknown format template '#{format}'"
|
678
689
|
end
|
679
|
-
|
680
|
-
factory.call
|
690
|
+
@parser = factory.call
|
681
691
|
end
|
682
|
-
end
|
683
|
-
|
684
|
-
def initialize
|
685
|
-
@parser = nil
|
686
|
-
@estimate_current_event = nil
|
687
|
-
end
|
688
|
-
|
689
|
-
attr_reader :parser
|
690
|
-
|
691
|
-
# SET false BEFORE CONFIGURE, to return nil when time not parsed
|
692
|
-
# 'configure()' may raise errors for unexpected configurations
|
693
|
-
attr_accessor :estimate_current_event
|
694
|
-
|
695
|
-
def configure(conf, required=true)
|
696
|
-
format = conf['format']
|
697
692
|
|
698
|
-
@parser = TextParser.lookup(format)
|
699
693
|
if ! @estimate_current_event.nil? && @parser.respond_to?(:'estimate_current_event=')
|
700
694
|
@parser.estimate_current_event = @estimate_current_event
|
701
695
|
end
|
@@ -709,9 +703,9 @@ module Fluent
|
|
709
703
|
|
710
704
|
def parse(text, &block)
|
711
705
|
if block
|
712
|
-
@parser.
|
706
|
+
@parser.call(text, &block)
|
713
707
|
else # keep backward compatibility. Will be removed at v1
|
714
|
-
return @parser.
|
708
|
+
return @parser.call(text)
|
715
709
|
end
|
716
710
|
end
|
717
711
|
end
|