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.

Files changed (140) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/.travis.yml +0 -4
  4. data/ChangeLog +0 -72
  5. data/Gemfile +0 -6
  6. data/Rakefile +12 -3
  7. data/example/in_http.conf +14 -0
  8. data/example/in_syslog.conf +15 -0
  9. data/example/in_tail.conf +14 -0
  10. data/example/in_tcp.conf +13 -0
  11. data/example/in_udp.conf +13 -0
  12. data/example/out_copy.conf +20 -0
  13. data/example/out_file.conf +13 -0
  14. data/example/out_forward.conf +30 -0
  15. data/fluent.conf +2 -12
  16. data/fluentd.gemspec +8 -11
  17. data/lib/fluent/agent.rb +180 -0
  18. data/lib/fluent/buffer.rb +6 -12
  19. data/lib/fluent/command/cat.rb +1 -3
  20. data/lib/fluent/command/debug.rb +1 -3
  21. data/lib/fluent/command/fluentd.rb +0 -10
  22. data/lib/fluent/config.rb +9 -3
  23. data/lib/fluent/config/basic_parser.rb +1 -6
  24. data/lib/fluent/config/configure_proxy.rb +25 -61
  25. data/lib/fluent/config/dsl.rb +16 -0
  26. data/lib/fluent/config/element.rb +21 -2
  27. data/lib/fluent/config/error.rb +16 -0
  28. data/lib/fluent/config/literal_parser.rb +9 -27
  29. data/lib/fluent/config/parser.rb +16 -0
  30. data/lib/fluent/config/section.rb +16 -2
  31. data/lib/fluent/config/types.rb +16 -1
  32. data/lib/fluent/config/v1_parser.rb +4 -12
  33. data/lib/fluent/configurable.rb +16 -0
  34. data/lib/fluent/engine.rb +43 -163
  35. data/lib/fluent/env.rb +16 -1
  36. data/lib/fluent/event.rb +20 -48
  37. data/lib/fluent/event_router.rb +187 -0
  38. data/lib/fluent/filter.rb +32 -0
  39. data/lib/fluent/formatter.rb +29 -101
  40. data/lib/fluent/input.rb +6 -4
  41. data/lib/fluent/label.rb +18 -0
  42. data/lib/fluent/load.rb +1 -3
  43. data/lib/fluent/log.rb +1 -3
  44. data/lib/fluent/match.rb +12 -19
  45. data/lib/fluent/mixin.rb +9 -25
  46. data/lib/fluent/output.rb +27 -45
  47. data/lib/fluent/parser.rb +93 -99
  48. data/lib/fluent/plugin.rb +22 -48
  49. data/lib/fluent/plugin/buf_file.rb +10 -7
  50. data/lib/fluent/plugin/buf_memory.rb +2 -3
  51. data/lib/fluent/plugin/buf_zfile.rb +75 -0
  52. data/lib/fluent/plugin/exec_util.rb +16 -0
  53. data/lib/fluent/plugin/in_debug_agent.rb +2 -3
  54. data/lib/fluent/plugin/in_exec.rb +2 -9
  55. data/lib/fluent/plugin/in_forward.rb +4 -22
  56. data/lib/fluent/plugin/in_gc_stat.rb +2 -3
  57. data/lib/fluent/plugin/in_http.rb +19 -59
  58. data/lib/fluent/plugin/in_monitor_agent.rb +21 -47
  59. data/lib/fluent/plugin/in_object_space.rb +2 -3
  60. data/lib/fluent/plugin/in_status.rb +2 -3
  61. data/lib/fluent/plugin/in_stream.rb +6 -16
  62. data/lib/fluent/plugin/in_syslog.rb +8 -17
  63. data/lib/fluent/plugin/in_tail.rb +17 -24
  64. data/lib/fluent/plugin/in_tcp.rb +16 -0
  65. data/lib/fluent/plugin/in_udp.rb +16 -0
  66. data/lib/fluent/plugin/out_copy.rb +3 -4
  67. data/lib/fluent/plugin/out_exec.rb +2 -4
  68. data/lib/fluent/plugin/out_exec_filter.rb +2 -13
  69. data/lib/fluent/plugin/out_file.rb +5 -6
  70. data/lib/fluent/plugin/out_forward.rb +4 -5
  71. data/lib/fluent/plugin/out_null.rb +2 -3
  72. data/lib/fluent/plugin/out_relabel.rb +26 -0
  73. data/lib/fluent/plugin/out_roundrobin.rb +3 -4
  74. data/lib/fluent/plugin/out_stdout.rb +2 -3
  75. data/lib/fluent/plugin/out_stream.rb +2 -3
  76. data/{test/scripts → lib}/fluent/plugin/out_test.rb +2 -3
  77. data/lib/fluent/plugin/socket_util.rb +19 -10
  78. data/lib/fluent/process.rb +4 -6
  79. data/lib/fluent/registry.rb +16 -0
  80. data/lib/fluent/root_agent.rb +212 -0
  81. data/lib/fluent/status.rb +2 -3
  82. data/lib/fluent/supervisor.rb +33 -54
  83. data/lib/fluent/test.rb +16 -0
  84. data/lib/fluent/test/base.rb +3 -17
  85. data/lib/fluent/test/input_test.rb +52 -7
  86. data/lib/fluent/test/output_test.rb +4 -20
  87. data/lib/fluent/version.rb +17 -1
  88. data/spec/config/config_parser_spec.rb +314 -0
  89. data/spec/config/configurable_spec.rb +524 -0
  90. data/spec/config/configure_proxy_spec.rb +96 -0
  91. data/spec/config/dsl_spec.rb +239 -0
  92. data/spec/config/helper.rb +49 -0
  93. data/spec/config/literal_parser_spec.rb +222 -0
  94. data/spec/config/section_spec.rb +97 -0
  95. data/spec/config/system_config_spec.rb +49 -0
  96. data/test/helper.rb +0 -25
  97. data/test/plugin/test_in_exec.rb +1 -1
  98. data/test/plugin/test_in_forward.rb +2 -1
  99. data/test/plugin/test_in_gc_stat.rb +1 -1
  100. data/test/plugin/test_in_http.rb +3 -78
  101. data/test/plugin/test_in_object_space.rb +1 -1
  102. data/test/plugin/test_in_status.rb +1 -1
  103. data/test/plugin/test_in_stream.rb +2 -1
  104. data/test/plugin/test_in_syslog.rb +2 -1
  105. data/test/plugin/test_in_tail.rb +6 -11
  106. data/test/plugin/test_in_tcp.rb +2 -1
  107. data/test/plugin/test_in_udp.rb +2 -1
  108. data/test/plugin/test_out_copy.rb +1 -12
  109. data/test/plugin/test_out_exec.rb +1 -1
  110. data/test/plugin/test_out_exec_filter.rb +1 -1
  111. data/test/plugin/test_out_file.rb +7 -96
  112. data/test/plugin/test_out_forward.rb +2 -1
  113. data/test/plugin/test_out_roundrobin.rb +1 -12
  114. data/test/plugin/test_out_stdout.rb +1 -1
  115. data/test/plugin/test_out_stream.rb +2 -1
  116. data/test/scripts/fluent/plugin/formatter_known.rb +1 -4
  117. data/test/scripts/fluent/plugin/parser_known.rb +1 -2
  118. data/test/test_config.rb +1 -1
  119. data/test/test_configdsl.rb +2 -1
  120. data/test/test_formatter.rb +3 -395
  121. data/test/test_match.rb +2 -1
  122. data/test/test_mixin.rb +3 -75
  123. data/test/test_output.rb +1 -112
  124. data/test/test_parser.rb +85 -152
  125. metadata +58 -167
  126. data/example/v1_literal_example.conf +0 -36
  127. data/lib/fluent/plugin/in_dummy.rb +0 -103
  128. data/lib/fluent/timezone.rb +0 -131
  129. data/test/config/assertions.rb +0 -42
  130. data/test/config/test_config_parser.rb +0 -389
  131. data/test/config/test_configurable.rb +0 -652
  132. data/test/config/test_configure_proxy.rb +0 -99
  133. data/test/config/test_dsl.rb +0 -237
  134. data/test/config/test_literal_parser.rb +0 -295
  135. data/test/config/test_section.rb +0 -112
  136. data/test/config/test_system_config.rb +0 -99
  137. data/test/config/test_types.rb +0 -63
  138. data/test/plugin/test_in_dummy.rb +0 -95
  139. data/test/test_event.rb +0 -168
  140. data/test/test_input.rb +0 -21
data/lib/fluent/input.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  #
2
- # Fluent
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
- @router = Engine
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
@@ -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
@@ -1,7 +1,5 @@
1
1
  #
2
- # Fluent
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.
data/lib/fluent/match.rb CHANGED
@@ -1,7 +1,5 @@
1
1
  #
2
- # Fluent
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
- GlobMatchPattern.new(str)
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
- ## TODO
66
- #class RegexMatchPattern < MatchPattern
67
- # def initialize(regex)
68
- # @regex = regex
69
- # end
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
- # Fluent
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
- require 'fluent/timezone'
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, :timezone
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
- if conf['timezone']
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
- # Fluent
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
- @router = Engine
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 = Time.now.to_f + 1.0
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 = Time.now.to_f
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 - Time.now.to_f
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['@type'] || conf['@type'] || sconf['type'] || conf['type']
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 = Time.now.to_f + @flush_interval
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(force = false)
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 = Time.now.to_f
279
+ time = Engine.now
279
280
 
280
281
  empty = @buffer.queue_size == 0
281
- if empty && @next_flush_time < (now = Time.now.to_f)
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.", :plugin_id=>plugin_id
325
+ $log.warn "retry succeeded.", :instance=>object_id
325
326
  end
326
327
 
327
328
  if has_next
328
- return Time.now.to_f + @queued_chunk_flush_interval
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, :plugin_id=>plugin_id
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, :plugin_id=>plugin_id
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, :plugin_id=>plugin_id
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, :plugin_id=>plugin_id
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, :plugin_id=>plugin_id
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
- @num_errors_lock.synchronize do
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.finite? ? wait + (rand * (wait / 4.0) - (wait / 8.0)) : 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 conf['timezone']
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(force = false)
554
- if force
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
- # Fluent
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 ParserError, "value must be string: #{value}"
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
- begin
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 < Parser
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 parse(text)
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 < Parser
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 parse(text)
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
- begin
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 < Parser
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 configure(conf)
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, @key_num))
324
+ yield values_map(text.split(@delimiter))
346
325
  else
347
- return values_map(text.split(@delimiter, @key_num))
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 parse(text)
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 parse(text)
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 < Parser
374
+ class NoneParser
375
+ include Configurable
376
+
396
377
  config_param :message_key, :string, :default => 'message'
397
378
 
398
- def parse(text)
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 < Parser
411
- REGEXP = /^(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\] "(?<method>\S+)(?: +(?<path>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/
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 parse(text)
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 < Parser
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 parse(text)
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 < Parser
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 parse(text, &block)
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>[^\"]*?)(?: +\S*)?)?" (?<code>[^ ]*) (?<size>[^ ]*)(?: "(?<referer>[^\"]*)" "(?<agent>[^\"]*)")?$/, {'time_format'=>"%d/%b/%Y:%H:%M:%S %z"}) },
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?(Class)
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 self.lookup(format)
656
- if format.nil?
657
- raise ConfigError, "'format' parameter is required"
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.parse(text, &block)
706
+ @parser.call(text, &block)
713
707
  else # keep backward compatibility. Will be removed at v1
714
- return @parser.parse(text)
708
+ return @parser.call(text)
715
709
  end
716
710
  end
717
711
  end