fluentd 0.10.0

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 (54) hide show
  1. data/AUTHORS +1 -0
  2. data/COPYING +14 -0
  3. data/ChangeLog +178 -0
  4. data/README.rdoc +57 -0
  5. data/Rakefile +62 -0
  6. data/VERSION +1 -0
  7. data/bin/fluent-cat +6 -0
  8. data/bin/fluent-gem +10 -0
  9. data/bin/fluentd +6 -0
  10. data/fluent.conf +78 -0
  11. data/fluentd.gemspec +116 -0
  12. data/lib/fluent/buffer.rb +274 -0
  13. data/lib/fluent/command/cat.rb +299 -0
  14. data/lib/fluent/command/fluentd.rb +245 -0
  15. data/lib/fluent/config.rb +304 -0
  16. data/lib/fluent/engine.rb +224 -0
  17. data/lib/fluent/env.rb +6 -0
  18. data/lib/fluent/event.rb +159 -0
  19. data/lib/fluent/input.rb +41 -0
  20. data/lib/fluent/load.rb +23 -0
  21. data/lib/fluent/log.rb +277 -0
  22. data/lib/fluent/match.rb +189 -0
  23. data/lib/fluent/mixin.rb +170 -0
  24. data/lib/fluent/output.rb +466 -0
  25. data/lib/fluent/parser.rb +115 -0
  26. data/lib/fluent/plugin.rb +145 -0
  27. data/lib/fluent/plugin/buf_file.rb +181 -0
  28. data/lib/fluent/plugin/buf_memory.rb +97 -0
  29. data/lib/fluent/plugin/buf_zfile.rb +84 -0
  30. data/lib/fluent/plugin/in_http.rb +282 -0
  31. data/lib/fluent/plugin/in_stream.rb +187 -0
  32. data/lib/fluent/plugin/in_syslog.rb +174 -0
  33. data/lib/fluent/plugin/in_tail.rb +150 -0
  34. data/lib/fluent/plugin/out_copy.rb +72 -0
  35. data/lib/fluent/plugin/out_file.rb +111 -0
  36. data/lib/fluent/plugin/out_null.rb +44 -0
  37. data/lib/fluent/plugin/out_roundrobin.rb +72 -0
  38. data/lib/fluent/plugin/out_stdout.rb +34 -0
  39. data/lib/fluent/plugin/out_stream.rb +128 -0
  40. data/lib/fluent/plugin/out_test.rb +68 -0
  41. data/lib/fluent/test.rb +8 -0
  42. data/lib/fluent/test/base.rb +63 -0
  43. data/lib/fluent/test/input_test.rb +89 -0
  44. data/lib/fluent/test/output_test.rb +93 -0
  45. data/lib/fluent/version.rb +5 -0
  46. data/test/helper.rb +6 -0
  47. data/test/match.rb +115 -0
  48. data/test/plugin/in_http.rb +84 -0
  49. data/test/plugin/in_stream.rb +136 -0
  50. data/test/plugin/out_copy.rb +55 -0
  51. data/test/plugin/out_file.rb +82 -0
  52. data/test/plugin/out_roundrobin.rb +65 -0
  53. data/test/plugin/out_stream.rb +74 -0
  54. metadata +224 -0
@@ -0,0 +1,93 @@
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
+ module Test
20
+
21
+
22
+ class TestOutputChain
23
+ def initialize
24
+ @called = 0
25
+ end
26
+
27
+ def next
28
+ @called += 1
29
+ end
30
+
31
+ attr_reader :called
32
+ end
33
+
34
+
35
+ class OutputTestDriver < InputTestDriver
36
+ def initialize(klass, tag='test', &block)
37
+ super(klass, &block)
38
+ @tag = tag
39
+ end
40
+
41
+ attr_accessor :tag
42
+
43
+ def emit(record, time=Time.now)
44
+ es = OneEventStream.new(time.to_i, record)
45
+ chain = TestOutputChain.new
46
+ @instance.emit(@tag, es, chain)
47
+ assert_equal 1, chain.called
48
+ end
49
+ end
50
+
51
+
52
+ class BufferedOutputTestDriver < InputTestDriver
53
+ def initialize(klass, tag='test', &block)
54
+ super(klass, &block)
55
+ @entries = []
56
+ @expected_buffer = nil
57
+ @tag = tag
58
+ end
59
+
60
+ attr_accessor :tag
61
+
62
+ def emit(record, time=Time.now)
63
+ @entries << [time.to_i, record]
64
+ self
65
+ end
66
+
67
+ def expect_format(str)
68
+ (@expected_buffer ||= '') << str
69
+ end
70
+
71
+ def run(&block)
72
+ result = nil
73
+ super {
74
+ es = ArrayEventStream.new(@entries)
75
+ buffer = @instance.format_stream(@tag, es)
76
+
77
+ block.call if block
78
+
79
+ if @expected_buffer
80
+ assert_equal(@expected_buffer, buffer)
81
+ end
82
+
83
+ chunk = MemoryBufferChunk.new('', buffer)
84
+ result = @instance.write(chunk)
85
+ }
86
+ result
87
+ end
88
+ end
89
+
90
+
91
+ end
92
+ end
93
+
@@ -0,0 +1,5 @@
1
+ module Fluent
2
+
3
+ VERSION = '0.10.0'
4
+
5
+ end
@@ -0,0 +1,6 @@
1
+ require 'test/unit'
2
+ require 'fileutils'
3
+
4
+ class Test::Unit::TestCase
5
+ end
6
+
@@ -0,0 +1,115 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ require 'fluent/match'
4
+
5
+ class MatchTest < Test::Unit::TestCase
6
+ include Fluent
7
+
8
+ def test_simple
9
+ assert_match('a', 'a')
10
+ assert_match('a.b', 'a.b')
11
+ assert_not_match('a', 'b')
12
+ assert_not_match('a.b', 'aab')
13
+ end
14
+
15
+ def test_wildcard
16
+ assert_match('a*', 'a')
17
+ assert_match('a*', 'ab')
18
+ assert_match('a*', 'abc')
19
+
20
+ assert_match('*a', 'a')
21
+ assert_match('*a', 'ba')
22
+ assert_match('*a', 'cba')
23
+
24
+ assert_match('*a*', 'a')
25
+ assert_match('*a*', 'ba')
26
+ assert_match('*a*', 'ac')
27
+ assert_match('*a*', 'bac')
28
+
29
+ assert_not_match('a*', 'a.b')
30
+ assert_not_match('a*', 'ab.c')
31
+ assert_not_match('a*', 'ba')
32
+ assert_not_match('*a', 'ab')
33
+
34
+ assert_match('a.*', 'a.b')
35
+ assert_match('a.*', 'a.c')
36
+ assert_not_match('a.*', 'ab')
37
+
38
+ assert_match('a.*.c', 'a.b.c')
39
+ assert_match('a.*.c', 'a.c.c')
40
+ assert_not_match('a.*.c', 'a.c')
41
+ end
42
+
43
+ def test_recursive_wildcard
44
+ assert_match('a.**', 'a')
45
+ assert_not_match('a.**', 'ab')
46
+ assert_not_match('a.**', 'abc')
47
+ assert_match('a.**', 'a.b')
48
+ assert_not_match('a.**', 'ab.c')
49
+ assert_not_match('a.**', 'ab.d.e')
50
+
51
+ assert_match('a**', 'a')
52
+ assert_match('a**', 'ab')
53
+ assert_match('a**', 'abc')
54
+ assert_match('a**', 'a.b')
55
+ assert_match('a**', 'ab.c')
56
+ assert_match('a**', 'ab.d.e')
57
+
58
+ assert_match('**.a', 'a')
59
+ assert_not_match('**.a', 'ba')
60
+ assert_not_match('**.a', 'c.ba')
61
+ assert_match('**.a', 'b.a')
62
+ assert_match('**.a', 'cb.a')
63
+ assert_match('**.a', 'd.e.a')
64
+
65
+ assert_match('**a', 'a')
66
+ assert_match('**a', 'ba')
67
+ assert_match('**a', 'c.ba')
68
+ assert_match('**a', 'b.a')
69
+ assert_match('**a', 'cb.a')
70
+ assert_match('**a', 'd.e.a')
71
+ end
72
+
73
+ def test_or
74
+ assert_match('a.{b,c}', 'a.b')
75
+ assert_match('a.{b,c}', 'a.c')
76
+ assert_not_match('a.{b,c}', 'a.d')
77
+
78
+ assert_match('a.{b,c}.**', 'a.b')
79
+ assert_match('a.{b,c}.**', 'a.c')
80
+ assert_not_match('a.{b,c}.**', 'a.d')
81
+ assert_not_match('a.{b,c}.**', 'a.cd')
82
+
83
+ assert_match('a.{b.**,c}', 'a.b')
84
+ assert_match('a.{b.**,c}', 'a.b.c')
85
+ assert_match('a.{b.**,c}', 'a.c')
86
+ assert_not_match('a.{b.**,c}', 'a.c.d')
87
+ end
88
+
89
+ #def test_character_class
90
+ # assert_match('[a]', 'a')
91
+ # assert_match('[ab]', 'a')
92
+ # assert_match('[ab]', 'b')
93
+ # assert_not_match('[ab]', 'c')
94
+ #
95
+ # assert_match('[a-b]', 'a')
96
+ # assert_match('[a-b]', 'a')
97
+ # assert_match('[a-b]', 'b')
98
+ # assert_not_match('[a-b]', 'c')
99
+ #
100
+ # assert_match('[a-b0-9]', 'a')
101
+ # assert_match('[a-b0-9]', '0')
102
+ # assert_not_match('[a-b0-9]', 'c')
103
+ #end
104
+
105
+ def assert_match(pat, str)
106
+ m = GlobMatchPattern.new(pat)
107
+ assert_equal true, m.match(str)
108
+ end
109
+
110
+ def assert_not_match(pat, str)
111
+ m = GlobMatchPattern.new(pat)
112
+ assert_equal false, m.match(str)
113
+ end
114
+ end
115
+
@@ -0,0 +1,84 @@
1
+ require 'fluent/test'
2
+ require 'net/http'
3
+
4
+ class HttpInputTest < Test::Unit::TestCase
5
+ def setup
6
+ Fluent::Test.setup
7
+ end
8
+
9
+ CONFIG = %[
10
+ port 9911
11
+ bind 127.0.0.1
12
+ body_size_limit 10m
13
+ keepalive_timeout 5
14
+ ]
15
+
16
+ def create_driver(conf=CONFIG)
17
+ Fluent::Test::InputTestDriver.new(Fluent::HttpInput).configure(conf)
18
+ end
19
+
20
+ def test_configure
21
+ d = create_driver
22
+ assert_equal 9911, d.instance.port
23
+ assert_equal '127.0.0.1', d.instance.bind
24
+ assert_equal 10*1024*1024, d.instance.body_size_limit
25
+ assert_equal 5, d.instance.keepalive_timeout
26
+ end
27
+
28
+ def test_time
29
+ d = create_driver
30
+
31
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
32
+ Fluent::Engine.now = time
33
+
34
+ d.expect_emit "tag1", time, {"a"=>1}
35
+ d.expect_emit "tag2", time, {"a"=>2}
36
+
37
+ d.run do
38
+ d.expected_emits.each {|tag,time,record|
39
+ res = post("/#{tag}", {"json"=>record.to_json})
40
+ assert_equal "200", res.code
41
+ }
42
+ end
43
+ end
44
+
45
+ def test_json
46
+ d = create_driver
47
+
48
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
49
+
50
+ d.expect_emit "tag1", time, {"a"=>1}
51
+ d.expect_emit "tag2", time, {"a"=>2}
52
+
53
+ d.run do
54
+ d.expected_emits.each {|tag,time,record|
55
+ res = post("/#{tag}", {"json"=>record.to_json, "time"=>time.to_s})
56
+ assert_equal "200", res.code
57
+ }
58
+ end
59
+ end
60
+
61
+ def test_msgpack
62
+ d = create_driver
63
+
64
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
65
+
66
+ d.expect_emit "tag1", time, {"a"=>1}
67
+ d.expect_emit "tag2", time, {"a"=>2}
68
+
69
+ d.run do
70
+ d.expected_emits.each {|tag,time,record|
71
+ res = post("/#{tag}", {"msgpack"=>record.to_msgpack, "time"=>time.to_s})
72
+ assert_equal "200", res.code
73
+ }
74
+ end
75
+ end
76
+
77
+ def post(path, params)
78
+ http = Net::HTTP.new("127.0.0.1", 9911)
79
+ req = Net::HTTP::Post.new(path, {})
80
+ req.set_form_data(params)
81
+ http.request(req)
82
+ end
83
+ end
84
+
@@ -0,0 +1,136 @@
1
+ require 'fluent/test'
2
+
3
+ module StreamInputTest
4
+ def setup
5
+ Fluent::Test.setup
6
+ end
7
+
8
+ def test_time
9
+ d = create_driver
10
+
11
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
12
+ Fluent::Engine.now = time
13
+
14
+ d.expect_emit "tag1", time, {"a"=>1}
15
+ d.expect_emit "tag2", time, {"a"=>2}
16
+
17
+ d.run do
18
+ d.expected_emits.each {|tag,time,record|
19
+ send_data [tag, 0, record].to_msgpack
20
+ }
21
+ sleep 0.5
22
+ end
23
+ end
24
+
25
+ def test_message
26
+ d = create_driver
27
+
28
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
29
+
30
+ d.expect_emit "tag1", time, {"a"=>1}
31
+ d.expect_emit "tag2", time, {"a"=>2}
32
+
33
+ d.run do
34
+ d.expected_emits.each {|tag,time,record|
35
+ send_data [tag, time, record].to_msgpack
36
+ }
37
+ sleep 0.5
38
+ end
39
+ end
40
+
41
+ def test_forward
42
+ d = create_driver
43
+
44
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
45
+
46
+ d.expect_emit "tag1", time, {"a"=>1}
47
+ d.expect_emit "tag1", time, {"a"=>2}
48
+
49
+ d.run do
50
+ entries = []
51
+ d.expected_emits.each {|tag,time,record|
52
+ entries << [time, record]
53
+ }
54
+ send_data ["tag1", entries].to_msgpack
55
+ sleep 0.5
56
+ end
57
+ end
58
+
59
+ def test_packed_forward
60
+ d = create_driver
61
+
62
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
63
+
64
+ d.expect_emit "tag1", time, {"a"=>1}
65
+ d.expect_emit "tag1", time, {"a"=>2}
66
+
67
+ d.run do
68
+ entries = ''
69
+ d.expected_emits.each {|tag,time,record|
70
+ [time, record].to_msgpack(entries)
71
+ }
72
+ send_data ["tag1", entries].to_msgpack
73
+ sleep 0.5
74
+ end
75
+ end
76
+
77
+ def create_driver(klass, conf)
78
+ Fluent::Test::InputTestDriver.new(klass).configure(conf)
79
+ end
80
+
81
+ def send_data(data)
82
+ io = connect
83
+ begin
84
+ io.write data
85
+ ensure
86
+ io.close
87
+ end
88
+ end
89
+ end
90
+
91
+ class TcpInputTest < Test::Unit::TestCase
92
+ include StreamInputTest
93
+
94
+ CONFIG = %[
95
+ port 13998
96
+ bind 127.0.0.1
97
+ ]
98
+
99
+ def create_driver(conf=CONFIG)
100
+ super(Fluent::TcpInput, conf)
101
+ end
102
+
103
+ def test_configure
104
+ d = create_driver
105
+ assert_equal 13998, d.instance.port
106
+ assert_equal '127.0.0.1', d.instance.bind
107
+ end
108
+
109
+ def connect
110
+ TCPSocket.new('127.0.0.1', 13998)
111
+ end
112
+ end
113
+
114
+ class UnixInputTest < Test::Unit::TestCase
115
+ include StreamInputTest
116
+
117
+ TMP_DIR = File.dirname(__FILE__) + "/../tmp"
118
+
119
+ CONFIG = %[
120
+ path #{TMP_DIR}/unix
121
+ ]
122
+
123
+ def create_driver(conf=CONFIG)
124
+ super(Fluent::UnixInput, conf)
125
+ end
126
+
127
+ def test_configure
128
+ d = create_driver
129
+ assert_equal "#{TMP_DIR}/unix", d.instance.path
130
+ end
131
+
132
+ def connect
133
+ UNIXSocket.new("#{TMP_DIR}/unix")
134
+ end
135
+ end
136
+
@@ -0,0 +1,55 @@
1
+ require 'fluent/test'
2
+
3
+ class CopyOutputTest < Test::Unit::TestCase
4
+ def setup
5
+ Fluent::Test.setup
6
+ end
7
+
8
+ CONFIG = %[
9
+ <store>
10
+ type test
11
+ name c0
12
+ </store>
13
+ <store>
14
+ type test
15
+ name c1
16
+ </store>
17
+ <store>
18
+ type test
19
+ name c2
20
+ </store>
21
+ ]
22
+
23
+ def create_driver(conf = CONFIG)
24
+ Fluent::Test::OutputTestDriver.new(Fluent::CopyOutput).configure(conf)
25
+ end
26
+
27
+ def test_configure
28
+ d = create_driver
29
+
30
+ outputs = d.instance.outputs
31
+ assert_equal 3, outputs.size
32
+ assert_equal Fluent::TestOutput, outputs[0].class
33
+ assert_equal Fluent::TestOutput, outputs[1].class
34
+ assert_equal Fluent::TestOutput, outputs[2].class
35
+ assert_equal "c0", outputs[0].name
36
+ assert_equal "c1", outputs[1].name
37
+ assert_equal "c2", outputs[2].name
38
+ end
39
+
40
+ def test_emit
41
+ d = create_driver
42
+
43
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
44
+ d.emit({"a"=>1}, time)
45
+ d.emit({"a"=>2}, time)
46
+
47
+ d.instance.outputs.each {|o|
48
+ assert_equal [
49
+ [time, {"a"=>1}],
50
+ [time, {"a"=>2}],
51
+ ], o.events
52
+ }
53
+ end
54
+ end
55
+