fluent-plugin-mongo 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +3 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/fluent/plugin/out_mongo.rb +36 -32
- data/lib/fluent/plugin/out_mongo_backup.rb +3 -6
- data/test/plugin/out_mongo.rb +91 -0
- metadata +11 -10
data/README.rdoc
CHANGED
@@ -6,6 +6,9 @@
|
|
6
6
|
|
7
7
|
Store fluent-event as MongoDB Document to MongoDB database.
|
8
8
|
|
9
|
+
MongoOutput set 'time' field to a document by default.
|
10
|
+
You set -false- to 'include_time_key' parameter if you disable this behaivor.
|
11
|
+
|
9
12
|
=== MongoBackup
|
10
13
|
|
11
14
|
Store fluent-event to capped collection for backup.
|
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ begin
|
|
12
12
|
gemspec.homepage = "http://github.com/fluent"
|
13
13
|
gemspec.has_rdoc = false
|
14
14
|
gemspec.require_paths = ["lib"]
|
15
|
-
gemspec.add_dependency "
|
15
|
+
gemspec.add_dependency "fluentd", "~> 0.10.1"
|
16
16
|
gemspec.add_dependency "mongo", ">= 1.2.0"
|
17
17
|
gemspec.test_files = Dir["test/**/*.rb"]
|
18
18
|
gemspec.files = Dir["bin/**/*", "lib/**/*", "test/**/*.rb"] + %w[VERSION AUTHORS Rakefile]
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -4,81 +4,85 @@ module Fluent
|
|
4
4
|
class MongoOutput < BufferedOutput
|
5
5
|
Fluent::Plugin.register_output('mongo', self)
|
6
6
|
|
7
|
+
include SetTagKeyMixin
|
8
|
+
config_set_default :include_tag_key, false
|
9
|
+
|
10
|
+
include SetTimeKeyMixin
|
11
|
+
config_set_default :include_time_key, true
|
12
|
+
|
13
|
+
config_param :database, :string
|
14
|
+
config_param :collection, :string
|
15
|
+
config_param :host, :string, :default => 'localhost'
|
16
|
+
config_param :port, :integer, :default => 27017
|
17
|
+
|
18
|
+
attr_reader :argument
|
19
|
+
|
7
20
|
def initialize
|
8
21
|
super
|
9
22
|
require 'mongo'
|
10
23
|
require 'msgpack'
|
11
24
|
|
12
|
-
|
13
|
-
@database_name = nil
|
14
|
-
@collection_name = nil
|
25
|
+
@argument = {:capped => false}
|
15
26
|
end
|
16
27
|
|
17
28
|
def configure(conf)
|
18
29
|
super
|
19
30
|
|
20
|
-
@database_name = conf['database'] if conf.has_key?('database')
|
21
|
-
@collection_name = conf['collection'] if conf.has_key?('collection')
|
22
|
-
raise ConfigError, "'database' and 'collection' parameter is required on mongo output" if @database_name.nil? || @collection_name.nil?
|
23
|
-
@host, @port = host_and_port(conf)
|
24
|
-
|
25
31
|
# capped configuration
|
26
|
-
|
27
|
-
if conf['capped']
|
32
|
+
if conf.has_key?('capped')
|
28
33
|
raise ConfigError, "'capped_size' parameter is required on <store> of Mongo output" unless conf.has_key?('capped_size')
|
29
34
|
@argument[:capped] = true
|
30
35
|
@argument[:size] = Config.size_value(conf['capped_size'])
|
31
36
|
@argument[:max] = Config.size_value(conf['capped_max']) if conf.has_key?('capped_max')
|
32
37
|
end
|
38
|
+
|
39
|
+
# MongoDB uses BSON's Date for time.
|
40
|
+
def @timef.format_nocache(time)
|
41
|
+
time
|
42
|
+
end
|
33
43
|
end
|
34
44
|
|
35
45
|
def start
|
36
46
|
super
|
37
|
-
@
|
47
|
+
@client = get_or_create_collection
|
38
48
|
end
|
39
49
|
|
40
50
|
def shutdown
|
41
51
|
# Mongo::Connection checks alive or closed myself
|
42
|
-
@
|
52
|
+
@client.db.connection.close
|
43
53
|
super
|
44
54
|
end
|
45
55
|
|
46
|
-
def format(tag,
|
47
|
-
|
56
|
+
def format(tag, time, record)
|
57
|
+
record.to_msgpack
|
48
58
|
end
|
49
59
|
|
50
60
|
def write(chunk)
|
51
61
|
records = []
|
52
|
-
chunk.
|
53
|
-
|
54
|
-
|
55
|
-
rescue EOFError
|
56
|
-
# EOFError always occured when reached end of chunk.
|
57
|
-
end
|
62
|
+
chunk.msgpack_each { |record|
|
63
|
+
record[@time_key] = Time.at(record[@time_key]) if @include_time_key
|
64
|
+
records << record
|
58
65
|
}
|
59
|
-
|
60
|
-
@collection.insert(records)
|
66
|
+
operate(records)
|
61
67
|
end
|
62
68
|
|
63
69
|
private
|
64
70
|
|
65
|
-
def host_and_port(conf)
|
66
|
-
host = conf['host'] || 'localhost'
|
67
|
-
port = conf['port'] || 27017
|
68
|
-
[host, Integer(port)]
|
69
|
-
end
|
70
|
-
|
71
71
|
def get_or_create_collection
|
72
|
-
db = Mongo::Connection.new(@host, @port).db(@
|
73
|
-
if db.collection_names.include?(@
|
74
|
-
collection = db.collection(@
|
72
|
+
db = Mongo::Connection.new(@host, @port).db(@database)
|
73
|
+
if db.collection_names.include?(@collection)
|
74
|
+
collection = db.collection(@collection)
|
75
75
|
return collection if @argument[:capped] == collection.capped? # TODO: Verify capped configuration
|
76
76
|
|
77
77
|
# raise Exception if old collection does not match lastest configuration
|
78
78
|
raise ConfigError, "New configuration is different from existing collection"
|
79
79
|
end
|
80
80
|
|
81
|
-
db.create_collection(@
|
81
|
+
db.create_collection(@collection, @argument)
|
82
|
+
end
|
83
|
+
|
84
|
+
def operate(records)
|
85
|
+
@client.insert(records)
|
82
86
|
end
|
83
87
|
end
|
84
88
|
|
@@ -9,13 +9,10 @@ class MongoBackupOutput < CopyOutput
|
|
9
9
|
Fluent::Plugin.register_output('mongo_backup', self)
|
10
10
|
|
11
11
|
class MongoOutputForBackup < MongoOutput
|
12
|
-
|
13
|
-
|
12
|
+
config_param :database, :string, :default => 'fluent'
|
13
|
+
config_param :collection, :string, :default => 'out_mongo_backup'
|
14
14
|
|
15
|
-
|
16
|
-
@database_name = 'fluent'
|
17
|
-
@collection_name = 'out_mongo_backup'
|
18
|
-
end
|
15
|
+
# TODO: optimize
|
19
16
|
end
|
20
17
|
|
21
18
|
def configure(conf)
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'fluent/test'
|
3
|
+
|
4
|
+
class MongoOutputTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
Fluent::Test.setup
|
7
|
+
require 'fluent/plugin/out_mongo'
|
8
|
+
end
|
9
|
+
|
10
|
+
CONFIG = %[
|
11
|
+
type mongo
|
12
|
+
database fluent
|
13
|
+
collection test
|
14
|
+
]
|
15
|
+
|
16
|
+
def create_driver(conf = CONFIG)
|
17
|
+
Fluent::Test::BufferedOutputTestDriver.new(Fluent::MongoOutput) {
|
18
|
+
def start
|
19
|
+
super
|
20
|
+
end
|
21
|
+
|
22
|
+
def shutdown
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
def operate(records)
|
27
|
+
records
|
28
|
+
end
|
29
|
+
}.configure(conf)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_configure
|
33
|
+
d = create_driver(%[
|
34
|
+
type mongo
|
35
|
+
database fluent_test
|
36
|
+
collection test_collection
|
37
|
+
|
38
|
+
host fluenter
|
39
|
+
port 27018
|
40
|
+
|
41
|
+
capped
|
42
|
+
capped_size 100
|
43
|
+
])
|
44
|
+
|
45
|
+
assert_equal('fluent_test', d.instance.database)
|
46
|
+
assert_equal('test_collection', d.instance.collection)
|
47
|
+
assert_equal('fluenter', d.instance.host)
|
48
|
+
assert_equal(27018, d.instance.port)
|
49
|
+
assert_equal({:capped => true, :size => 100}, d.instance.argument)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_format
|
53
|
+
d = create_driver
|
54
|
+
|
55
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
56
|
+
d.emit({'a' => 1}, time)
|
57
|
+
d.emit({'a' => 2}, time)
|
58
|
+
d.expect_format({'a' => 1, d.instance.time_key => time}.to_msgpack)
|
59
|
+
d.expect_format({'a' => 2, d.instance.time_key => time}.to_msgpack)
|
60
|
+
|
61
|
+
d.run
|
62
|
+
end
|
63
|
+
|
64
|
+
def emit_documents(d)
|
65
|
+
time = Time.parse("2011-01-02 13:14:15 UTC").to_i
|
66
|
+
d.emit({'a' => 1}, time)
|
67
|
+
d.emit({'a' => 2}, time)
|
68
|
+
time
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_write
|
72
|
+
d = create_driver
|
73
|
+
t = emit_documents(d)
|
74
|
+
|
75
|
+
documents = d.run
|
76
|
+
assert_equal([{'a' => 1, d.instance.time_key => Time.at(t)},
|
77
|
+
{'a' => 2, d.instance.time_key => Time.at(t)}], documents)
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_write_at_enable_tag
|
81
|
+
d = create_driver(CONFIG + %[
|
82
|
+
include_tag_key true
|
83
|
+
include_time_key false
|
84
|
+
])
|
85
|
+
t = emit_documents(d)
|
86
|
+
|
87
|
+
documents = d.run
|
88
|
+
assert_equal([{'a' => 1, d.instance.tag_key => 'test'},
|
89
|
+
{'a' => 2, d.instance.tag_key => 'test'}], documents)
|
90
|
+
end
|
91
|
+
end
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 4
|
8
|
+
- 0
|
9
|
+
version: 0.4.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Masahiro Nakagawa
|
@@ -14,11 +14,11 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-10-
|
17
|
+
date: 2011-10-16 00:00:00 +09:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
name:
|
21
|
+
name: fluentd
|
22
22
|
prerelease: false
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
24
|
none: false
|
@@ -27,9 +27,9 @@ dependencies:
|
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
segments:
|
29
29
|
- 0
|
30
|
-
-
|
31
|
-
-
|
32
|
-
version: 0.
|
30
|
+
- 10
|
31
|
+
- 1
|
32
|
+
version: 0.10.1
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
35
|
- !ruby/object:Gem::Dependency
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- bin/mongo-tail
|
63
63
|
- lib/fluent/plugin/out_mongo.rb
|
64
64
|
- lib/fluent/plugin/out_mongo_backup.rb
|
65
|
+
- test/plugin/out_mongo.rb
|
65
66
|
- README.rdoc
|
66
67
|
has_rdoc: true
|
67
68
|
homepage: http://github.com/fluent
|
@@ -95,5 +96,5 @@ rubygems_version: 1.3.7
|
|
95
96
|
signing_key:
|
96
97
|
specification_version: 3
|
97
98
|
summary: MongoDB output plugin for Fluent event collector
|
98
|
-
test_files:
|
99
|
-
|
99
|
+
test_files:
|
100
|
+
- test/plugin/out_mongo.rb
|