fluentd 0.10.13 → 0.10.15

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

data/ChangeLog CHANGED
@@ -1,4 +1,20 @@
1
1
 
2
+ Release 0.10.15 - 2012/03/09
3
+
4
+ * Added experimental in_status plugin
5
+ * out_forward: normalize the phi value of the failure detector into 1sec
6
+ * out_forward: improved memory efficiency
7
+ * out_forward: use weighted moving average for the phi accrual failure detector
8
+
9
+
10
+ Release 0.10.14 - 2012/03/05
11
+
12
+ * Show warnings if in_tcp or out_unix is used
13
+ * BasicBuffer shows warnings when data.bytesize > @buffer_chunk_limit
14
+ * out_forward: randomize roundrobin queue correctly
15
+ * Added development dependencies to the gemspec
16
+
17
+
2
18
  Release 0.10.13 - 2012/02/21
3
19
 
4
20
  * Rewrote in_tail
@@ -61,21 +61,4 @@ License:: Apache License, Version 2.0
61
61
 
62
62
  == Contributors:
63
63
 
64
- Patches contributed by:
65
-
66
- * {Abhishek Parolkar}[https://github.com/parolkar]
67
- * {Chad Skidmore}[https://github.com/chad-skidmore]
68
- * {Eiichiro Iwata}[http://github.com/eiichiroi]
69
- * {Francesc Esplugas}[https://github.com/fesplugas]
70
- * {hirochachacha}[https://github.com/hirochachacha]
71
- * {Hiro Yoshikawa}[https://github.com/hiroyoshikawa]
72
- * {Masahiro Nakagawa}[https://github.com/repeatedly]
73
- * {Nathan Parry}[https://github.com/nparry]
74
- * {Nobuyuki Kubota}[https://github.com/nobu-k]
75
- * {Sakuro Ozawa}[https://github.com/sakuro]
76
- * {Satoshi Tagomori}[https://github.com/tagomoris]
77
- * {Takashi Nagayasu}[https://github.com/sumipan]
78
- * {Tsuyoshi Ozawa}[https://github.com/oza]
79
- * {uu59}[https://github.com/uu59]
80
- * {Waldemar Quevedo Salinas}[https://github.com/wallyqs]
81
- * {Yuichi Tateno}[https://github.com/hotchpotch]
64
+ Patches contributed by {those people}[https://github.com/fluent/fluentd/contributors].
data/Rakefile CHANGED
@@ -18,9 +18,12 @@ begin
18
18
  gemspec.add_dependency "cool.io", "~> 1.1.0"
19
19
  gemspec.add_dependency "http_parser.rb", "~> 0.5.1"
20
20
  gemspec.add_development_dependency "rake", ">= 0.9.2"
21
+ gemspec.add_development_dependency "rr", ">= 1.0.0"
22
+ gemspec.add_development_dependency "timecop", ">= 0.3.0"
23
+ gemspec.add_development_dependency "jeweler", ">= 1.0.0"
21
24
  gemspec.test_files = Dir["test/**/*.rb"]
22
25
  gemspec.files = Dir["bin/**/*", "lib/**/*", "test/**/*.rb"] +
23
- %w[fluent.conf VERSION AUTHORS Rakefile COPYING fluentd.gemspec]
26
+ %w[fluent.conf VERSION AUTHORS Rakefile COPYING fluentd.gemspec Gemfile]
24
27
  gemspec.executables = ['fluentd', 'fluent-cat', 'fluent-gem']
25
28
  gemspec.required_ruby_version = '~> 1.9.2'
26
29
  end
@@ -53,5 +56,15 @@ Rake::TestTask.new(:base_test) do |t|
53
56
  #t.warning = true
54
57
  end
55
58
 
56
- task :default => [VERSION_FILE, :build]
59
+ # workaround for fluentd >= 0 dependency
60
+ task :mv_gemfile do
61
+ File.rename "Gemfile", "Gemfile.bak" rescue nil
62
+ end
63
+
64
+ # workaround for fluentd >= 0 dependency
65
+ task :revert_gemfile do
66
+ File.rename "Gemfile.bak", "Gemfile" rescue nil
67
+ end
68
+
69
+ task :default => [VERSION_FILE, :mv_gemfile, :build, :revert_gemfile]
57
70
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.10.13
1
+ 0.10.15
@@ -0,0 +1,160 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "fluentd"
8
+ s.version = "0.10.14"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Sadayuki Furuhashi"]
12
+ s.date = "2012-03-07"
13
+ s.email = "frsyuki@gmail.com"
14
+ s.executables = ["fluentd", "fluent-cat", "fluent-gem"]
15
+ s.extra_rdoc_files = [
16
+ "ChangeLog",
17
+ "README",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ "AUTHORS",
22
+ "COPYING",
23
+ "Gemfile",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "bin/fluent-cat",
27
+ "bin/fluent-gem",
28
+ "bin/fluentd",
29
+ "fluent.conf",
30
+ "fluentd.gemspec",
31
+ "lib/fluent/buffer.rb",
32
+ "lib/fluent/command/cat.rb",
33
+ "lib/fluent/command/fluentd.rb",
34
+ "lib/fluent/config.rb",
35
+ "lib/fluent/engine.rb",
36
+ "lib/fluent/env.rb",
37
+ "lib/fluent/event.rb",
38
+ "lib/fluent/input.rb",
39
+ "lib/fluent/load.rb",
40
+ "lib/fluent/log.rb",
41
+ "lib/fluent/match.rb",
42
+ "lib/fluent/mixin.rb",
43
+ "lib/fluent/output.rb",
44
+ "lib/fluent/parser.rb",
45
+ "lib/fluent/plugin.rb",
46
+ "lib/fluent/plugin/buf_file.rb",
47
+ "lib/fluent/plugin/buf_memory.rb",
48
+ "lib/fluent/plugin/buf_zfile.rb",
49
+ "lib/fluent/plugin/in_exec.rb",
50
+ "lib/fluent/plugin/in_forward.rb",
51
+ "lib/fluent/plugin/in_http.rb",
52
+ "lib/fluent/plugin/in_status.rb",
53
+ "lib/fluent/plugin/in_stream.rb",
54
+ "lib/fluent/plugin/in_syslog.rb",
55
+ "lib/fluent/plugin/in_tail.rb",
56
+ "lib/fluent/plugin/out_copy.rb",
57
+ "lib/fluent/plugin/out_exec.rb",
58
+ "lib/fluent/plugin/out_exec_filter.rb",
59
+ "lib/fluent/plugin/out_file.rb",
60
+ "lib/fluent/plugin/out_forward.rb",
61
+ "lib/fluent/plugin/out_null.rb",
62
+ "lib/fluent/plugin/out_roundrobin.rb",
63
+ "lib/fluent/plugin/out_stdout.rb",
64
+ "lib/fluent/plugin/out_stream.rb",
65
+ "lib/fluent/plugin/out_test.rb",
66
+ "lib/fluent/process.rb",
67
+ "lib/fluent/status.rb",
68
+ "lib/fluent/supervisor.rb",
69
+ "lib/fluent/test.rb",
70
+ "lib/fluent/test/base.rb",
71
+ "lib/fluent/test/input_test.rb",
72
+ "lib/fluent/test/output_test.rb",
73
+ "lib/fluent/version.rb",
74
+ "test/config.rb",
75
+ "test/helper.rb",
76
+ "test/match.rb",
77
+ "test/mixin.rb",
78
+ "test/plugin/in_exec.rb",
79
+ "test/plugin/in_forward.rb",
80
+ "test/plugin/in_http.rb",
81
+ "test/plugin/in_stream.rb",
82
+ "test/plugin/out_copy.rb",
83
+ "test/plugin/out_exec.rb",
84
+ "test/plugin/out_exec_filter.rb",
85
+ "test/plugin/out_file.rb",
86
+ "test/plugin/out_forward.rb",
87
+ "test/plugin/out_roundrobin.rb",
88
+ "test/plugin/out_stream.rb"
89
+ ]
90
+ s.homepage = "http://fluentd.org/"
91
+ s.require_paths = ["lib"]
92
+ s.required_ruby_version = Gem::Requirement.new("~> 1.9.2")
93
+ s.rubygems_version = "1.8.12"
94
+ s.summary = "Fluent event collector"
95
+ s.test_files = ["test/config.rb", "test/helper.rb", "test/match.rb", "test/mixin.rb", "test/plugin/in_exec.rb", "test/plugin/in_forward.rb", "test/plugin/in_http.rb", "test/plugin/in_stream.rb", "test/plugin/out_copy.rb", "test/plugin/out_exec.rb", "test/plugin/out_exec_filter.rb", "test/plugin/out_file.rb", "test/plugin/out_forward.rb", "test/plugin/out_roundrobin.rb", "test/plugin/out_stream.rb"]
96
+
97
+ if s.respond_to? :specification_version then
98
+ s.specification_version = 3
99
+
100
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
101
+ s.add_runtime_dependency(%q<fluentd>, [">= 0"])
102
+ s.add_development_dependency(%q<rake>, [">= 0.9.2"])
103
+ s.add_development_dependency(%q<rr>, [">= 1.0.0"])
104
+ s.add_development_dependency(%q<timecop>, [">= 0.3.0"])
105
+ s.add_development_dependency(%q<jeweler>, [">= 1.0.0"])
106
+ s.add_development_dependency(%q<rake>, [">= 0.9.2"])
107
+ s.add_development_dependency(%q<rr>, [">= 1.0.0"])
108
+ s.add_development_dependency(%q<timecop>, [">= 0.3.0"])
109
+ s.add_development_dependency(%q<jeweler>, [">= 1.0.0"])
110
+ s.add_runtime_dependency(%q<msgpack>, ["~> 0.4.4"])
111
+ s.add_runtime_dependency(%q<json>, [">= 1.4.3"])
112
+ s.add_runtime_dependency(%q<yajl-ruby>, ["~> 1.0.0"])
113
+ s.add_runtime_dependency(%q<cool.io>, ["~> 1.1.0"])
114
+ s.add_runtime_dependency(%q<http_parser.rb>, ["~> 0.5.1"])
115
+ s.add_development_dependency(%q<rake>, [">= 0.9.2"])
116
+ s.add_development_dependency(%q<rr>, [">= 1.0.0"])
117
+ s.add_development_dependency(%q<timecop>, [">= 0.3.0"])
118
+ s.add_development_dependency(%q<jeweler>, [">= 1.0.0"])
119
+ else
120
+ s.add_dependency(%q<fluentd>, [">= 0"])
121
+ s.add_dependency(%q<rake>, [">= 0.9.2"])
122
+ s.add_dependency(%q<rr>, [">= 1.0.0"])
123
+ s.add_dependency(%q<timecop>, [">= 0.3.0"])
124
+ s.add_dependency(%q<jeweler>, [">= 1.0.0"])
125
+ s.add_dependency(%q<rake>, [">= 0.9.2"])
126
+ s.add_dependency(%q<rr>, [">= 1.0.0"])
127
+ s.add_dependency(%q<timecop>, [">= 0.3.0"])
128
+ s.add_dependency(%q<jeweler>, [">= 1.0.0"])
129
+ s.add_dependency(%q<msgpack>, ["~> 0.4.4"])
130
+ s.add_dependency(%q<json>, [">= 1.4.3"])
131
+ s.add_dependency(%q<yajl-ruby>, ["~> 1.0.0"])
132
+ s.add_dependency(%q<cool.io>, ["~> 1.1.0"])
133
+ s.add_dependency(%q<http_parser.rb>, ["~> 0.5.1"])
134
+ s.add_dependency(%q<rake>, [">= 0.9.2"])
135
+ s.add_dependency(%q<rr>, [">= 1.0.0"])
136
+ s.add_dependency(%q<timecop>, [">= 0.3.0"])
137
+ s.add_dependency(%q<jeweler>, [">= 1.0.0"])
138
+ end
139
+ else
140
+ s.add_dependency(%q<fluentd>, [">= 0"])
141
+ s.add_dependency(%q<rake>, [">= 0.9.2"])
142
+ s.add_dependency(%q<rr>, [">= 1.0.0"])
143
+ s.add_dependency(%q<timecop>, [">= 0.3.0"])
144
+ s.add_dependency(%q<jeweler>, [">= 1.0.0"])
145
+ s.add_dependency(%q<rake>, [">= 0.9.2"])
146
+ s.add_dependency(%q<rr>, [">= 1.0.0"])
147
+ s.add_dependency(%q<timecop>, [">= 0.3.0"])
148
+ s.add_dependency(%q<jeweler>, [">= 1.0.0"])
149
+ s.add_dependency(%q<msgpack>, ["~> 0.4.4"])
150
+ s.add_dependency(%q<json>, [">= 1.4.3"])
151
+ s.add_dependency(%q<yajl-ruby>, ["~> 1.0.0"])
152
+ s.add_dependency(%q<cool.io>, ["~> 1.1.0"])
153
+ s.add_dependency(%q<http_parser.rb>, ["~> 0.5.1"])
154
+ s.add_dependency(%q<rake>, [">= 0.9.2"])
155
+ s.add_dependency(%q<rr>, [">= 1.0.0"])
156
+ s.add_dependency(%q<timecop>, [">= 0.3.0"])
157
+ s.add_dependency(%q<jeweler>, [">= 1.0.0"])
158
+ end
159
+ end
160
+
@@ -21,6 +21,12 @@ module Fluent
21
21
  class BufferError < StandardError
22
22
  end
23
23
 
24
+ class BufferChunkLimitError < BufferError
25
+ end
26
+
27
+ class BufferQueueLimitError < BufferError
28
+ end
29
+
24
30
 
25
31
  class Buffer
26
32
  include Configurable
@@ -165,11 +171,17 @@ class BasicBuffer < Buffer
165
171
  ## FIXME
166
172
  #elsif data.bytesize > @buffer_chunk_limit
167
173
  # # TODO
168
- # raise BufferError, "received data too large"
174
+ # raise BufferChunkLimitError, "received data too large"
169
175
 
170
176
  elsif @queue.size >= @buffer_queue_limit
171
- # TODO
172
- raise BufferError, "queue size exceeds limit"
177
+ raise BufferQueueLimitError, "queue size exceeds limit"
178
+ end
179
+
180
+ if data.bytesize > @buffer_chunk_limit
181
+ $log.warn "Size of the emitted data exceeds buffer_chunk_limit."
182
+ $log.warn "This may occur problems in the output plugins ``at this server.``"
183
+ $log.warn "To avoid problems, set a smaller number to the buffer_chunk_limit"
184
+ $log.warn "in the forward output ``at the log forwarding server.``"
173
185
  end
174
186
 
175
187
  nc = new_chunk(key) # TODO generate unique chunk id
@@ -41,7 +41,7 @@ op.on('-s', "--setup [DIR=#{File.dirname(Fluent::DEFAULT_CONFIG_PATH)}]", "insta
41
41
  opts[:setup_path] = s || File.dirname(Fluent::DEFAULT_CONFIG_PATH)
42
42
  }
43
43
 
44
- op.on('-c', '--config PATH', "config flie path (default: #{Fluent::DEFAULT_CONFIG_PATH})") {|s|
44
+ op.on('-c', '--config PATH', "config file path (default: #{Fluent::DEFAULT_CONFIG_PATH})") {|s|
45
45
  opts[:config_path] = s
46
46
  }
47
47
 
@@ -12,6 +12,7 @@ require 'cool.io/eventmachine'
12
12
  require 'fluent/env'
13
13
  require 'fluent/version'
14
14
  require 'fluent/log'
15
+ require 'fluent/status'
15
16
  require 'fluent/config'
16
17
  require 'fluent/engine'
17
18
  require 'fluent/mixin'
@@ -168,6 +168,7 @@ class BufferedOutput < Output
168
168
  @error_history = []
169
169
  @error_history.extend(MonitorMixin)
170
170
  @secondary_limit = 8
171
+ @emit_count = 0
171
172
  end
172
173
 
173
174
  config_param :buffer_type, :string, :default => 'memory'
@@ -210,6 +211,9 @@ class BufferedOutput < Output
210
211
 
211
212
  @secondary.secondary_init(self)
212
213
  end
214
+
215
+ Status.register(self, "queue_size") { @buffer.queue_size }
216
+ Status.register(self, "emit_count") { @emit_count }
213
217
  end
214
218
 
215
219
  def start
@@ -226,6 +230,7 @@ class BufferedOutput < Output
226
230
  end
227
231
 
228
232
  def emit(tag, es, chain, key="")
233
+ @emit_count += 1
229
234
  data = format_stream(tag, es)
230
235
  if @buffer.emit(key, data, chain)
231
236
  submit_flush
@@ -0,0 +1,81 @@
1
+
2
+ #
3
+ # Fluent
4
+ #
5
+ # Copyright (C) 2011 FURUHASHI Sadayuki
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ module Fluent
20
+
21
+
22
+ class StatusInput < Input
23
+ Plugin.register_input('status', self)
24
+
25
+ def initialize
26
+ super
27
+ end
28
+
29
+ config_param :emit_interval, :time, :default => 60
30
+ config_param :tag, :string
31
+
32
+ class TimerWatcher < Coolio::TimerWatcher
33
+ def initialize(interval, repeat, &callback)
34
+ @callback = callback
35
+ super(interval, repeat)
36
+ end
37
+
38
+ def on_timer
39
+ @callback.call
40
+ rescue
41
+ # TODO log?
42
+ $log.error $!.to_s
43
+ $log.error_backtrace
44
+ end
45
+ end
46
+
47
+ def configure(conf)
48
+ super
49
+ end
50
+
51
+ def start
52
+ @loop = Coolio::Loop.new
53
+ @timer = TimerWatcher.new(@emit_interval, true, &method(:on_timer))
54
+ @loop.attach(@timer)
55
+ @thread = Thread.new(&method(:run))
56
+ end
57
+
58
+ def shutdown
59
+ @loop.watchers.each {|w| w.detach }
60
+ @loop.stop
61
+ @thread.join
62
+ end
63
+
64
+ def run
65
+ @loop.run
66
+ rescue
67
+ $log.error "unexpected error", :error=>$!.to_s
68
+ $log.error_backtrace
69
+ end
70
+
71
+ def on_timer
72
+ now = Engine.now
73
+ Status.each {|record|
74
+ Engine.emit(@tag, now, record)
75
+ }
76
+ end
77
+ end
78
+
79
+
80
+ end
81
+
@@ -170,8 +170,7 @@ class TcpInput < ForwardInput
170
170
 
171
171
  def initialize
172
172
  super
173
- ## TODO
174
- #$log.warn "'tcp' input is obsoleted and will be removed. Use 'forward' instead."
173
+ $log.warn "'tcp' input is obsoleted and will be removed soon. Use 'forward' instead."
175
174
  end
176
175
  end
177
176
 
@@ -184,8 +183,7 @@ class UnixInput < StreamInput
184
183
 
185
184
  def configure(conf)
186
185
  super
187
- ## TODO
188
- #$log.warn "'unix' input is obsoleted and will be removed. Use 'forward' instead."
186
+ $log.warn "'unix' input is obsoleted and will be removed. Use 'forward' instead."
189
187
  end
190
188
 
191
189
  def listen
@@ -71,7 +71,7 @@ class ForwardOutput < ObjectBufferedOutput
71
71
  name = "#{host}:#{port}"
72
72
  end
73
73
 
74
- failure = FailureDetector.new(@heartbeat_interval.to_f/2, @hard_timeout, Time.now.to_i.to_f)
74
+ failure = FailureDetector.new(@heartbeat_interval, @hard_timeout, Time.now.to_i.to_f)
75
75
  sockaddr = Socket.pack_sockaddr_in(port, host)
76
76
  port, host = Socket.unpack_sockaddr_in(sockaddr)
77
77
  @nodes[sockaddr] = Node.new(name, host, port, weight, standby, failure,
@@ -171,7 +171,7 @@ class ForwardOutput < ObjectBufferedOutput
171
171
  }
172
172
 
173
173
  r = Random.new(@rand_seed)
174
- weight_array.sort_by { r.rand }
174
+ weight_array.sort_by! { r.rand }
175
175
 
176
176
  @weight_array = weight_array
177
177
  end
@@ -350,11 +350,14 @@ class ForwardOutput < ObjectBufferedOutput
350
350
  PHI_FACTOR = 1.0 / Math.log(10.0)
351
351
  SAMPLE_SIZE = 1000
352
352
 
353
- def initialize(init_int, hard_timeout, init_last)
353
+ def initialize(heartbeat_interval, hard_timeout, init_last)
354
+ @heartbeat_interval = heartbeat_interval
354
355
  @last = init_last
355
- @init_int = init_int
356
356
  @hard_timeout = hard_timeout
357
- @window = [init_int]
357
+
358
+ # microsec
359
+ @init_gap = (heartbeat_interval * 1e6).to_i
360
+ @window = [@init_gap]
358
361
  end
359
362
 
360
363
  def hard_timeout?(now)
@@ -363,11 +366,11 @@ class ForwardOutput < ObjectBufferedOutput
363
366
 
364
367
  def add(now)
365
368
  if @window.empty?
366
- @window << @init_int
369
+ @window << @init_gap
367
370
  @last = now
368
371
  else
369
- int = now - @last
370
- @window << int
372
+ gap = now - @last
373
+ @window << (gap * 1e6).to_i
371
374
  @window.shift if @window.length > SAMPLE_SIZE
372
375
  @last = now
373
376
  end
@@ -376,9 +379,24 @@ class ForwardOutput < ObjectBufferedOutput
376
379
  def phi(now)
377
380
  size = @window.size
378
381
  return 0.0 if size == 0
382
+
383
+ # Calculate weighted moving average
384
+ mean_usec = 0
385
+ fact = 0
386
+ @window.each_with_index {|gap,i|
387
+ mean_usec += gap * (1+i)
388
+ fact += (1+i)
389
+ }
390
+ mean_usec = mean_usec / fact
391
+
392
+ # Normalize arrive intervals into 1sec
393
+ mean = (mean_usec.to_f / 1e6) - @heartbeat_interval + 1
394
+
395
+ # Calculate phi of the phi accrual failure detector
379
396
  t = now - @last
380
- mean = @window.inject(0) {|r,v| r + v } / size
381
- return PHI_FACTOR * t / mean
397
+ phi = PHI_FACTOR * t / mean
398
+
399
+ return phi
382
400
  end
383
401
 
384
402
  def sample_size
@@ -91,8 +91,8 @@ class TcpOutput < StreamOutput
91
91
 
92
92
  def initialize
93
93
  super
94
- ## TODO
95
- #$log.warn "'tcp' output is obsoleted and will be removed. Use 'forward' instead."
94
+ $log.warn "'tcp' output is obsoleted and will be removed. Use 'forward' instead."
95
+ $log.warn "see 'forward' section in http://fluentd.org/doc/plugin.html for the high-availability configuration."
96
96
  end
97
97
 
98
98
  config_param :port, :integer, :default => DEFAULT_LISTEN_PORT
@@ -114,8 +114,7 @@ class UnixOutput < StreamOutput
114
114
 
115
115
  def initialize
116
116
  super
117
- ## TODO
118
- #$log.warn "'unix' output is obsoleted and will be removed."
117
+ $log.warn "'unix' output is obsoleted and will be removed."
119
118
  end
120
119
 
121
120
  config_param :path, :string
@@ -0,0 +1,49 @@
1
+ #
2
+ # Fluent
3
+ #
4
+ # Copyright (C) 2011 FURUHASHI Sadayuki
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+ module Fluent
19
+
20
+
21
+
22
+ class StatusClass
23
+ def initialize
24
+ @entries = {}
25
+ end
26
+
27
+ def register(instance, name, &block)
28
+ (@entries[instance.object_id] ||= {})[name] = block
29
+ nil
30
+ end
31
+
32
+ def each(&block)
33
+ @entries.each {|obj_id,hash|
34
+ record = {}
35
+ hash.each_pair {|name,block|
36
+ record[name] = block.call
37
+ }
38
+ block.call(record)
39
+ }
40
+ end
41
+ end
42
+
43
+ # Don't use this class from plugins.
44
+ # The interface may be changed
45
+ Status = StatusClass.new
46
+
47
+
48
+ end
49
+
@@ -1,5 +1,5 @@
1
1
  module Fluent
2
2
 
3
- VERSION = '0.10.13'
3
+ VERSION = '0.10.15'
4
4
 
5
5
  end
@@ -1,8 +1,10 @@
1
1
  require 'test/unit'
2
2
  require 'fileutils'
3
3
  require 'fluent/log'
4
+ require 'rr'
4
5
 
5
6
  class Test::Unit::TestCase
7
+ include RR::Adapters::TestUnit
6
8
  end
7
9
 
8
10
  $log = Fluent::Log.new(STDOUT, Fluent::Log::LEVEL_WARN)
@@ -1,232 +1,158 @@
1
1
  require 'helper'
2
2
  require 'fluent/mixin'
3
+ require 'fluent/env'
4
+ require 'fluent/plugin'
5
+ require 'fluent/config'
6
+ require 'fluent/test'
7
+ require 'timecop'
3
8
 
4
- #class MixinTest < Test::Unit::TestCase
5
- # class MixinOutputTester < Fluent::BufferedOutput
6
- # Fluent::Plugin.register_output('mixintest', self)
7
- # include Fluent::PlainTextFormatterMixin
8
- # def configure(conf)
9
- # super
10
- # end
11
- # def write(chunk)
12
- # chunk.read
13
- # end
14
- # end
15
- #
16
- # def create_driver(conf='')
17
- # Fluent::Test::BufferedOutputTestDriver.new(MixinOutputTester).configure(conf)
18
- # end
19
- #
20
- # def test_default_config
21
- # d = create_driver
22
- # assert_equal true, d.instance.output_include_time
23
- # assert_equal true, d.instance.output_include_tag
24
- # assert_equal 'json', d.instance.output_data_type
25
- # assert_equal "\t", d.instance.output_field_separator
26
- # assert_equal true, d.instance.output_add_newline
27
- # assert_equal nil, d.instance.instance_eval{@localtime}
28
- #
29
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
30
- # d.emit({"foo"=>1,"bar"=>501}, time)
31
- # d.emit({"foo"=>2,"bar"=>502}, time)
32
- # text = d.run
33
- # assert_equal %[2011-11-29T12:02:50Z\ttest\t{"foo":1,"bar":501}\n2011-11-29T12:02:50Z\ttest\t{"foo":2,"bar":502}\n], text
34
- # end
35
- #
36
- # def test_timezone
37
- # d = create_driver %[
38
- #utc
39
- #]
40
- # assert_equal false, d.instance.instance_eval{@localtime}
41
- #
42
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
43
- # d.emit({"foo"=>1,"bar"=>501}, time)
44
- # d.emit({"foo"=>2,"bar"=>502}, time)
45
- # text = d.run
46
- # assert_equal %[2011-11-29T12:02:50Z\ttest\t{"foo":1,"bar":501}\n2011-11-29T12:02:50Z\ttest\t{"foo":2,"bar":502}\n], text
47
- #
48
- # d = create_driver %[
49
- #localtime
50
- #]
51
- # assert_equal true, d.instance.instance_eval{@localtime}
52
- #
53
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
54
- # time_s = Time.parse("2011-11-29 12:02:50 UTC").getlocal.iso8601
55
- # d.emit({"foo"=>1,"bar"=>501}, time)
56
- # d.emit({"foo"=>2,"bar"=>502}, time)
57
- # text = d.run
58
- # assert_equal time_s + %[\ttest\t{"foo":1,"bar":501}\n] + time_s + %[\ttest\t{"foo":2,"bar":502}\n], text
59
- # end
60
- #
61
- # def test_time_tag_onoff
62
- # d = create_driver %[
63
- #output_include_time true
64
- #output_include_tag false
65
- #]
66
- # assert_equal true, d.instance.output_include_time
67
- # assert_equal false, d.instance.output_include_tag
68
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
69
- # d.emit({"foo"=>1,"bar"=>501}, time)
70
- # d.emit({"foo"=>2,"bar"=>502}, time)
71
- # text = d.run
72
- # assert_equal %[2011-11-29T12:02:50Z\t{"foo":1,"bar":501}\n2011-11-29T12:02:50Z\t{"foo":2,"bar":502}\n], text
73
- #
74
- # d = create_driver %[
75
- #output_include_time false
76
- #output_include_tag true
77
- #]
78
- # assert_equal false, d.instance.output_include_time
79
- # assert_equal true, d.instance.output_include_tag
80
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
81
- # d.emit({"foo"=>1,"bar"=>501}, time)
82
- # d.emit({"foo"=>2,"bar"=>502}, time)
83
- # text = d.run
84
- # assert_equal %[test\t{"foo":1,"bar":501}\ntest\t{"foo":2,"bar":502}\n], text
85
- #
86
- # d = create_driver %[
87
- #output_include_time false
88
- #output_include_tag false
89
- #]
90
- # assert_equal false, d.instance.output_include_time
91
- # assert_equal false, d.instance.output_include_tag
92
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
93
- # d.emit({"foo"=>1,"bar"=>501}, time)
94
- # d.emit({"foo"=>2,"bar"=>502}, time)
95
- # text = d.run
96
- # assert_equal %[{"foo":1,"bar":501}\n{"foo":2,"bar":502}\n], text
97
- # end
98
- #
99
- # def test_data_type
100
- # d = create_driver %[
101
- #output_data_type json
102
- #]
103
- # assert_equal 'json', d.instance.output_data_type
104
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
105
- # d.emit({"foo"=>1,"bar"=>"This is what you want"}, time)
106
- # d.emit({"foo"=>2,"bar"=>"Is this what you want or not"}, time)
107
- # text = d.run
108
- # assert_equal %[2011-11-29T12:02:50Z\ttest\t{"foo":1,"bar":"This is what you want"}\n2011-11-29T12:02:50Z\ttest\t{"foo":2,"bar":"Is this what you want or not"}\n], text
109
- #
110
- # d = create_driver %[
111
- #output_data_type attr:foo
112
- #]
113
- # assert_equal 'attr:foo', d.instance.output_data_type
114
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
115
- # d.emit({"foo"=>1,"bar"=>"This is what you want"}, time)
116
- # d.emit({"foo"=>2,"bar"=>"Is this what you want or not"}, time)
117
- # text = d.run
118
- # assert_equal %[2011-11-29T12:02:50Z\ttest\t1\n2011-11-29T12:02:50Z\ttest\t2\n], text
119
- #
120
- # d = create_driver %[
121
- #output_data_type attr:bar
122
- #]
123
- # assert_equal 'attr:bar', d.instance.output_data_type
124
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
125
- # d.emit({"foo"=>1,"bar"=>"This is what you want"}, time)
126
- # d.emit({"foo"=>2,"bar"=>"Is this what you want or not"}, time)
127
- # text = d.run
128
- # assert_equal %[2011-11-29T12:02:50Z\ttest\tThis is what you want\n2011-11-29T12:02:50Z\ttest\tIs this what you want or not\n], text
129
- #
130
- # d = create_driver %[
131
- #output_data_type attr:foo,bar
132
- #]
133
- # assert_equal 'attr:foo,bar', d.instance.output_data_type
134
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
135
- # d.emit({"foo"=>1,"bar"=>"This is what you want"}, time)
136
- # d.emit({"foo"=>2,"bar"=>"Is this what you want or not"}, time)
137
- # text = d.run
138
- # assert_equal %[2011-11-29T12:02:50Z\ttest\t1\tThis is what you want\n2011-11-29T12:02:50Z\ttest\t2\tIs this what you want or not\n], text
139
- # end
140
- #
141
- # def test_add_newline
142
- # d = create_driver %[
143
- #output_add_newline false
144
- #]
145
- # assert_equal false, d.instance.output_add_newline
146
- #
147
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
148
- # d.emit({"foo"=>1,"bar"=>"This is what you want"}, time)
149
- # d.emit({"foo"=>2,"bar"=>"Is this what you want or not"}, time)
150
- # text = d.run
151
- # assert_equal %[2011-11-29T12:02:50Z\ttest\t{"foo":1,"bar":"This is what you want"}2011-11-29T12:02:50Z\ttest\t{"foo":2,"bar":"Is this what you want or not"}], text
152
- #
153
- # d = create_driver %[
154
- #output_add_newline false
155
- #]
156
- # assert_equal false, d.instance.output_add_newline
157
- #
158
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
159
- # d.emit({"foo"=>1,"bar"=>"This is what you want\n"}, time)
160
- # d.emit({"foo"=>2,"bar"=>"Is this what you want or not\n"}, time)
161
- # text = d.run
162
- # assert_equal %[2011-11-29T12:02:50Z\ttest\t{"foo":1,"bar":"This is what you want\\n"}2011-11-29T12:02:50Z\ttest\t{"foo":2,"bar":"Is this what you want or not\\n"}], text
163
- #
164
- # d = create_driver %[
165
- #output_data_type attr:bar
166
- #output_add_newline false
167
- #]
168
- # assert_equal false, d.instance.output_add_newline
169
- #
170
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
171
- # d.emit({"foo"=>1,"bar"=>"This is what you want\n"}, time)
172
- # d.emit({"foo"=>2,"bar"=>"Is this what you want or not\n"}, time)
173
- # text = d.run
174
- # assert_equal %[2011-11-29T12:02:50Z\ttest\tThis is what you want\n2011-11-29T12:02:50Z\ttest\tIs this what you want or not\n], text
175
- #
176
- # d = create_driver %[
177
- #output_data_type attr:bar
178
- #output_add_newline true
179
- #]
180
- # assert_equal true, d.instance.output_add_newline
181
- #
182
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
183
- # d.emit({"foo"=>1,"bar"=>"This is what you want\n"}, time)
184
- # d.emit({"foo"=>2,"bar"=>"Is this what you want or not\n"}, time)
185
- # text = d.run
186
- # assert_equal %[2011-11-29T12:02:50Z\ttest\tThis is what you want\n\n2011-11-29T12:02:50Z\ttest\tIs this what you want or not\n\n], text
187
- # end
188
- #
189
- # def test_field_separator
190
- # time = Time.parse("2011-11-29 12:02:50 UTC").to_i
191
- #
192
- # d = create_driver %[
193
- #output_field_separator SPACE
194
- #]
195
- # assert_equal " ", d.instance.output_field_separator
196
- # d.emit({"foo"=>1,"bar"=>501}, time)
197
- # d.emit({"foo"=>2,"bar"=>502}, time)
198
- # text = d.run
199
- # assert_equal %[2011-11-29T12:02:50Z test {"foo":1,"bar":501}\n2011-11-29T12:02:50Z test {"foo":2,"bar":502}\n], text
200
- #
201
- # d = create_driver %[
202
- #output_field_separator SPACE
203
- #output_data_type attr:bar,foo
204
- #]
205
- # assert_equal " ", d.instance.output_field_separator
206
- # d.emit({"foo"=>1,"bar"=>501}, time)
207
- # d.emit({"foo"=>2,"bar"=>502}, time)
208
- # text = d.run
209
- # assert_equal %[2011-11-29T12:02:50Z test 501 1\n2011-11-29T12:02:50Z test 502 2\n], text
210
- #
211
- # d = create_driver %[
212
- #output_field_separator COMMA
213
- #]
214
- # assert_equal ",", d.instance.output_field_separator
215
- # d.emit({"foo"=>1,"bar"=>501}, time)
216
- # d.emit({"foo"=>2,"bar"=>502}, time)
217
- # text = d.run
218
- # assert_equal %[2011-11-29T12:02:50Z,test,{"foo":1,"bar":501}\n2011-11-29T12:02:50Z,test,{"foo":2,"bar":502}\n], text
219
- #
220
- # d = create_driver %[
221
- #output_field_separator COMMA
222
- #output_data_type attr:foo,bar
223
- #]
224
- # assert_equal ",", d.instance.output_field_separator
225
- # d.emit({"foo"=>1,"bar"=>501}, time)
226
- # d.emit({"foo"=>2,"bar"=>502}, time)
227
- # text = d.run
228
- # assert_equal %[2011-11-29T12:02:50Z,test,1,501\n2011-11-29T12:02:50Z,test,2,502\n], text
229
- # end
230
- #
231
- #end
9
+ module MixinTest
10
+ module Utils
11
+ def setup
12
+ super
13
+ Fluent::Test.setup
14
+ @time = Time.utc(1,2,3,4,5,2010,nil,nil,nil,nil)
15
+ Timecop.freeze(@time)
16
+ end
232
17
 
18
+ def teardown
19
+ super
20
+ Timecop.return
21
+ end
22
+
23
+ module Checker
24
+ extend self
25
+ def format_check(tag, time, record); end
26
+ end
27
+
28
+ @@num = 0
29
+ def create_register_output_name
30
+ "mixin_text_#{@@num+=1}"
31
+ end
32
+
33
+ def format_check(hash, tagname = 'test')
34
+ mock(Checker).format_check(tagname, @time.to_i, hash)
35
+ end
36
+
37
+ def create_driver(include_klass, conf = '')
38
+ register_output_name = create_register_output_name
39
+ include_klasses = [include_klass].flatten
40
+
41
+ klass = Class.new(Fluent::BufferedOutput) {
42
+ include_klasses.each {|k| include k }
43
+
44
+ Fluent::Plugin.register_output(register_output_name, self)
45
+ def format(tag, time, record)
46
+ Checker.format_check(tag, time, record)
47
+ [tag, time, record].to_msgpack
48
+ end
49
+
50
+ def write(chunk); end
51
+ }
52
+
53
+ Fluent::Test::BufferedOutputTestDriver.new(klass) {
54
+ }.configure("tyep #{register_output_name}" + conf)
55
+ end
56
+ end
57
+
58
+ class SetTagKeyMixinText < Test::Unit::TestCase
59
+ include Utils
60
+
61
+ def test_tag_key_default
62
+ format_check({
63
+ 'a' => 1
64
+ })
65
+
66
+ d = create_driver(Fluent::SetTagKeyMixin, %[
67
+ ])
68
+ d.emit({'a' => 1})
69
+ d.run
70
+ end
71
+
72
+ def test_include_tag_key_true
73
+ format_check({
74
+ 'tag' => 'test',
75
+ 'a' => 1
76
+ })
77
+
78
+ d = create_driver(Fluent::SetTagKeyMixin, %[
79
+ include_tag_key true
80
+ ])
81
+
82
+ d.emit({'a' => 1})
83
+ d.run
84
+ end
85
+
86
+ def test_include_tag_key_false
87
+ format_check({
88
+ 'a' => 1
89
+ })
90
+
91
+ d = create_driver(Fluent::SetTagKeyMixin, %[
92
+ include_tag_key false
93
+ ])
94
+ d.emit({'a' => 1})
95
+ d.run
96
+ end
97
+
98
+ def test_tag_key_set
99
+ format_check({
100
+ 'tag_key_changed' => 'test',
101
+ 'a' => 1
102
+ })
103
+
104
+ d = create_driver(Fluent::SetTagKeyMixin, %[
105
+ include_tag_key true
106
+ tag_key tag_key_changed
107
+ ])
108
+
109
+ d.emit({'a' => 1})
110
+ d.run
111
+ end
112
+ end
113
+
114
+ class SetTimeKeyMixinText < Test::Unit::TestCase
115
+ include Utils
116
+
117
+ def test_time_key_default
118
+ format_check({
119
+ 'a' => 1
120
+ })
121
+
122
+ d = create_driver(Fluent::SetTimeKeyMixin, %[
123
+ ])
124
+
125
+ d.emit({'a' => 1})
126
+ d.run
127
+ end
128
+
129
+ def test_include_time_key_true
130
+ format_check({
131
+ 'time' => "2010-05-04T03:02:01Z",
132
+ 'a' => 1
133
+ })
134
+
135
+ d = create_driver(Fluent::SetTimeKeyMixin, %[
136
+ include_time_key true
137
+ ])
138
+
139
+ d.emit({'a' => 1})
140
+ d.run
141
+ end
142
+
143
+ def test_time_format
144
+ format_check({
145
+ 'time' => "20100504",
146
+ 'a' => 1
147
+ })
148
+
149
+ d = create_driver(Fluent::SetTimeKeyMixin, %[
150
+ include_time_key true
151
+ time_format %Y%m%d
152
+ ])
153
+
154
+ d.emit({'a' => 1})
155
+ d.run
156
+ end
157
+ end
158
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluentd
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.13
4
+ version: 0.10.15
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-22 00:00:00.000000000Z
12
+ date: 2012-03-09 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: msgpack
16
- requirement: &70115974571520 !ruby/object:Gem::Requirement
16
+ requirement: &70355087964700 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.4.4
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70115974571520
24
+ version_requirements: *70355087964700
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: json
27
- requirement: &70115974563160 !ruby/object:Gem::Requirement
27
+ requirement: &70355087961840 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.4.3
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70115974563160
35
+ version_requirements: *70355087961840
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: yajl-ruby
38
- requirement: &70115974560860 !ruby/object:Gem::Requirement
38
+ requirement: &70355087958040 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 1.0.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70115974560860
46
+ version_requirements: *70355087958040
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: cool.io
49
- requirement: &70115974558780 !ruby/object:Gem::Requirement
49
+ requirement: &70355087953920 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.1.0
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70115974558780
57
+ version_requirements: *70355087953920
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: http_parser.rb
60
- requirement: &70115974553640 !ruby/object:Gem::Requirement
60
+ requirement: &70355087948700 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.5.1
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70115974553640
68
+ version_requirements: *70355087948700
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
- requirement: &70115974549200 !ruby/object:Gem::Requirement
71
+ requirement: &70355087947960 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,7 +76,40 @@ dependencies:
76
76
  version: 0.9.2
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70115974549200
79
+ version_requirements: *70355087947960
80
+ - !ruby/object:Gem::Dependency
81
+ name: rr
82
+ requirement: &70355087946840 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: 1.0.0
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70355087946840
91
+ - !ruby/object:Gem::Dependency
92
+ name: timecop
93
+ requirement: &70355087946240 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: 0.3.0
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *70355087946240
102
+ - !ruby/object:Gem::Dependency
103
+ name: jeweler
104
+ requirement: &70355087945380 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: 1.0.0
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *70355087945380
80
113
  description:
81
114
  email: frsyuki@gmail.com
82
115
  executables:
@@ -97,6 +130,7 @@ files:
97
130
  - bin/fluent-gem
98
131
  - bin/fluentd
99
132
  - fluent.conf
133
+ - fluentd.gemspec
100
134
  - lib/fluent/buffer.rb
101
135
  - lib/fluent/command/cat.rb
102
136
  - lib/fluent/command/fluentd.rb
@@ -118,6 +152,7 @@ files:
118
152
  - lib/fluent/plugin/in_exec.rb
119
153
  - lib/fluent/plugin/in_forward.rb
120
154
  - lib/fluent/plugin/in_http.rb
155
+ - lib/fluent/plugin/in_status.rb
121
156
  - lib/fluent/plugin/in_stream.rb
122
157
  - lib/fluent/plugin/in_syslog.rb
123
158
  - lib/fluent/plugin/in_tail.rb
@@ -132,6 +167,7 @@ files:
132
167
  - lib/fluent/plugin/out_stream.rb
133
168
  - lib/fluent/plugin/out_test.rb
134
169
  - lib/fluent/process.rb
170
+ - lib/fluent/status.rb
135
171
  - lib/fluent/supervisor.rb
136
172
  - lib/fluent/test.rb
137
173
  - lib/fluent/test/base.rb