fluent-plugin-mongo 0.7.16 → 0.8.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -1
- data/VERSION +1 -1
- data/bin/mongo-tail +37 -30
- data/fluent-plugin-mongo.gemspec +1 -1
- data/lib/fluent/plugin/in_mongo_tail.rb +122 -138
- data/lib/fluent/plugin/logger_support.rb +25 -0
- data/lib/fluent/plugin/mongo_auth.rb +32 -0
- data/lib/fluent/plugin/out_mongo.rb +83 -136
- data/lib/fluent/plugin/out_mongo_replset.rb +20 -31
- data/test/helper.rb +6 -0
- data/test/plugin/test_in_mongo_tail.rb +96 -0
- data/test/plugin/test_out_mongo.rb +282 -0
- data/test/plugin/test_out_mongo_replset.rb +125 -0
- metadata +16 -22
- data/lib/fluent/plugin/mongo_util.rb +0 -27
- data/lib/fluent/plugin/out_mongo_tag_collection.rb +0 -20
- data/test/plugin/in_mongo_tail.rb +0 -73
- data/test/plugin/out_mongo.rb +0 -298
- data/test/plugin/out_mongo_tag_mapped.rb +0 -69
- data/test/test_helper.rb +0 -59
- data/test/tools/auth_repl_set_manager.rb +0 -14
- data/test/tools/repl_set_manager.rb +0 -420
- data/test/tools/rs_test_helper.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5a76dcf9763e4ba6cd2ad37a15b1f5b3145d31e
|
4
|
+
data.tar.gz: 17f1414c1edf96ae7009ad701815b2f120eb6018
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e45d8d167be9f710635f207edde89c8b2962f7ee16a59f34eb406617c6839ba1021ced2ae508c8450ad36f4e2a8d9475eb53020ecc4984329615105f3a3d87b
|
7
|
+
data.tar.gz: 2bbeb260a265b4fd040577862d8b39b72b7d3045c5e2083f758671a80eb8da1a440f6e2c5b3dd8ec1ecfde9043796a46039a82935c32279ff87f4d7e5c7a8e2f
|
data/.travis.yml
CHANGED
@@ -10,12 +10,15 @@ gemfile:
|
|
10
10
|
- Gemfile
|
11
11
|
- Gemfile.v0.12
|
12
12
|
|
13
|
+
services:
|
14
|
+
- mongodb
|
15
|
+
|
13
16
|
before_install:
|
14
17
|
- gem update bundler
|
15
18
|
before_script:
|
16
19
|
- git submodule update -i
|
17
20
|
|
18
|
-
script:
|
21
|
+
script: bundle exec rake test
|
19
22
|
|
20
23
|
matrix:
|
21
24
|
allow_failures:
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.8.0.rc1
|
data/bin/mongo-tail
CHANGED
@@ -8,11 +8,11 @@ require 'json'
|
|
8
8
|
require 'mongo'
|
9
9
|
|
10
10
|
TailConfig = {
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
11
|
+
d: 'fluent',
|
12
|
+
c: 'out_mongo_backup',
|
13
|
+
h: 'localhost',
|
14
|
+
p: 27017,
|
15
|
+
n: 10
|
16
16
|
}
|
17
17
|
|
18
18
|
OptionParser.new { |opt|
|
@@ -28,51 +28,58 @@ OptionParser.new { |opt|
|
|
28
28
|
opt.parse!(ARGV)
|
29
29
|
}
|
30
30
|
|
31
|
+
def get_client_options(conf)
|
32
|
+
client_options = {}
|
33
|
+
client_options[:database] = conf[:d]
|
34
|
+
client_options
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_collection_options
|
38
|
+
collection_options = {}
|
39
|
+
collection_options[:capped] = true
|
40
|
+
collection_options
|
41
|
+
end
|
42
|
+
|
31
43
|
def get_capped_collection(conf)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
puts "#{conf[:c]} is not capped. mongo-tail can not tail normal collection."
|
39
|
-
end
|
44
|
+
client_options = get_client_options(conf)
|
45
|
+
collection_options = get_collection_options
|
46
|
+
client = Mongo::Client.new(["#{conf[:h]}:#{conf[:p]}"], client_options)
|
47
|
+
collection = client["#{conf[:c]}", collection_options]
|
48
|
+
if collection.capped?
|
49
|
+
collection
|
40
50
|
else
|
41
|
-
puts "#{conf[:c]} not
|
51
|
+
puts "#{conf[:c]} is not capped. mongo-tail can not tail normal collection."
|
42
52
|
end
|
43
53
|
end
|
44
54
|
|
45
|
-
def
|
55
|
+
def create_skip_number(collection, conf)
|
46
56
|
skip = collection.count - conf[:n]
|
47
|
-
|
48
|
-
cursor_conf[:skip] = skip if skip > 0
|
49
|
-
cursor_conf
|
57
|
+
skip
|
50
58
|
end
|
51
59
|
|
52
60
|
def tail_n(collection, conf)
|
53
|
-
collection.find(
|
61
|
+
collection.find().skip(create_skip_number(collection, conf)).each {|doc|
|
54
62
|
puts doc.to_json
|
55
63
|
}
|
56
64
|
end
|
57
65
|
|
58
66
|
def tail_forever(collection, conf)
|
59
|
-
cursor_conf = create_cursor_conf(collection, conf)
|
60
|
-
cursor_conf[:tailable] = true
|
61
|
-
|
62
|
-
cursor = Mongo::Cursor.new(collection, cursor_conf)
|
63
67
|
loop {
|
64
|
-
|
65
|
-
cursor = Mongo::Cursor.new(collection, cursor_conf) unless cursor.alive?
|
68
|
+
option['_id'] = {'$gt' => BSON::ObjectId(@last_id)} if @last_id
|
66
69
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
+
documents = collection.find(option)
|
71
|
+
if documents.count >= 1
|
72
|
+
documents.each {|doc|
|
73
|
+
STDOUT.puts doc.to_json
|
74
|
+
STDOUT.flush
|
75
|
+
if id = doc.delete('_id')
|
76
|
+
@last_id = id.to_s
|
77
|
+
end
|
78
|
+
}
|
70
79
|
else
|
71
80
|
sleep 1
|
72
81
|
end
|
73
82
|
}
|
74
|
-
rescue
|
75
|
-
# ignore Mongo::OperationFailuer at CURSOR_NOT_FOUND
|
76
83
|
end
|
77
84
|
|
78
85
|
exit unless collection = get_capped_collection(TailConfig)
|
data/fluent-plugin-mongo.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.require_paths = ['lib']
|
19
19
|
|
20
20
|
gem.add_dependency "fluentd", [">= 0.10.58", "< 2"]
|
21
|
-
gem.
|
21
|
+
gem.add_runtime_dependency "mongo", "~> 2.2.0"
|
22
22
|
gem.add_development_dependency "rake", ">= 0.9.2"
|
23
23
|
gem.add_development_dependency "simplecov", ">= 0.5.4"
|
24
24
|
gem.add_development_dependency "rr", ">= 1.0.0"
|
@@ -4,38 +4,56 @@ module Fluent
|
|
4
4
|
class MongoTailInput < Input
|
5
5
|
Plugin.register_input('mongo_tail', self)
|
6
6
|
|
7
|
-
require 'fluent/plugin/mongo_util'
|
8
|
-
include MongoUtil
|
9
|
-
|
10
|
-
config_param :database, :string, :default => nil
|
11
|
-
config_param :collection, :string
|
12
|
-
config_param :host, :string, :default => 'localhost'
|
13
|
-
config_param :port, :integer, :default => 27017
|
14
|
-
config_param :wait_time, :integer, :default => 1
|
15
|
-
config_param :url, :string, :default => nil
|
16
|
-
|
17
|
-
config_param :tag, :string, :default => nil
|
18
|
-
config_param :tag_key, :string, :default => nil
|
19
|
-
config_param :time_key, :string, :default => nil
|
20
|
-
config_param :time_format, :string, :default => nil
|
21
|
-
config_param :object_id_keys, :array, :default => nil
|
22
|
-
|
23
|
-
# To store last ObjectID
|
24
|
-
config_param :id_store_file, :string, :default => nil
|
25
|
-
config_param :id_store_collection, :string, :default => nil
|
26
|
-
|
27
|
-
# SSL connection
|
28
|
-
config_param :ssl, :bool, :default => false
|
29
|
-
|
30
7
|
unless method_defined?(:log)
|
31
8
|
define_method(:log) { $log }
|
32
9
|
end
|
33
10
|
|
11
|
+
# Define `router` method of v0.12 to support v0.10 or earlier
|
12
|
+
unless method_defined?(:router)
|
13
|
+
define_method("router") { ::Fluent::Engine }
|
14
|
+
end
|
15
|
+
|
16
|
+
require 'fluent/plugin/mongo_auth'
|
17
|
+
include MongoAuthParams
|
18
|
+
include MongoAuth
|
19
|
+
require 'fluent/plugin/logger_support'
|
20
|
+
include LoggerSupport
|
21
|
+
|
22
|
+
desc "MongoDB database"
|
23
|
+
config_param :database, :string, default: nil
|
24
|
+
desc "MongoDB collection"
|
25
|
+
config_param :collection, :string
|
26
|
+
desc "MongoDB host"
|
27
|
+
config_param :host, :string, default: 'localhost'
|
28
|
+
desc "MongoDB port"
|
29
|
+
config_param :port, :integer, default: 27017
|
30
|
+
desc "Tailing interval"
|
31
|
+
config_param :wait_time, :integer, default: 1
|
32
|
+
desc "MongoDB node URL"
|
33
|
+
config_param :url, :string, default: nil
|
34
|
+
|
35
|
+
desc "Input tag"
|
36
|
+
config_param :tag, :string, default: nil
|
37
|
+
desc "Treat key as tag"
|
38
|
+
config_param :tag_key, :string, default: nil
|
39
|
+
desc "Treat key as time"
|
40
|
+
config_param :time_key, :string, default: nil
|
41
|
+
desc "Time format"
|
42
|
+
config_param :time_format, :string, default: nil
|
43
|
+
config_param :object_id_keys, :array, default: nil
|
44
|
+
|
45
|
+
desc "To store last ObjectID"
|
46
|
+
config_param :id_store_file, :string, default: nil
|
47
|
+
|
48
|
+
desc "SSL connection"
|
49
|
+
config_param :ssl, :bool, default: false
|
50
|
+
|
34
51
|
def initialize
|
35
52
|
super
|
36
53
|
require 'mongo'
|
37
54
|
require 'bson'
|
38
55
|
|
56
|
+
@client_options = {}
|
39
57
|
@connection_options = {}
|
40
58
|
end
|
41
59
|
|
@@ -54,86 +72,72 @@ module Fluent
|
|
54
72
|
raise ConfigError, "One of 'database' or 'url' must be specified"
|
55
73
|
end
|
56
74
|
|
57
|
-
@last_id = get_last_id
|
75
|
+
@last_id = @id_store_file ? get_last_id : nil
|
58
76
|
@connection_options[:ssl] = @ssl
|
59
77
|
|
60
|
-
|
78
|
+
configure_logger(@mongo_log_level)
|
61
79
|
end
|
62
80
|
|
63
81
|
def start
|
64
82
|
super
|
65
|
-
|
66
|
-
@
|
83
|
+
|
84
|
+
@file = get_id_store_file if @id_store_file
|
85
|
+
@collection = get_collection
|
86
|
+
# Resume tailing from last inserted id.
|
87
|
+
# Because tailable option is obsoleted since mongo driver 2.0.
|
88
|
+
@last_id = get_last_inserted_id if !@id_store_file and get_last_inserted_id
|
67
89
|
@thread = Thread.new(&method(:run))
|
68
90
|
end
|
69
91
|
|
70
92
|
def shutdown
|
71
|
-
|
72
|
-
|
93
|
+
if @id_store_file
|
94
|
+
save_last_id
|
95
|
+
@file.close
|
96
|
+
end
|
73
97
|
|
74
98
|
@stop = true
|
75
99
|
@thread.join
|
76
|
-
@client.
|
100
|
+
@client.close
|
101
|
+
|
77
102
|
super
|
78
103
|
end
|
79
104
|
|
80
105
|
def run
|
81
106
|
loop {
|
82
|
-
|
107
|
+
option = {}
|
83
108
|
begin
|
84
109
|
loop {
|
85
110
|
return if @stop
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
111
|
+
|
112
|
+
option['_id'] = {'$gt' => BSON::ObjectId(@last_id)} if @last_id
|
113
|
+
documents = @collection.find(option)
|
114
|
+
if documents.count >= 1
|
115
|
+
process_documents(documents)
|
90
116
|
else
|
91
117
|
sleep @wait_time
|
92
118
|
end
|
93
119
|
}
|
94
120
|
rescue
|
95
|
-
# ignore
|
121
|
+
# ignore Exceptions
|
96
122
|
end
|
97
123
|
}
|
98
124
|
end
|
99
125
|
|
100
126
|
private
|
101
127
|
|
102
|
-
def
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
raise ConfigError, "'#{database_name}.#{@collection}' is not capped: node = #{node_string}" unless collection.capped?
|
108
|
-
collection
|
109
|
-
rescue Mongo::ConnectionFailure => e
|
110
|
-
log.fatal "Failed to connect to 'mongod'. Please restart 'fluentd' after 'mongod' started: #{e}"
|
111
|
-
exit!
|
112
|
-
rescue Mongo::OperationFailure => e
|
113
|
-
log.fatal "Operation failed. Probably, 'mongod' needs an authentication: #{e}"
|
114
|
-
exit!
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
def get_database
|
119
|
-
case
|
120
|
-
when @database
|
121
|
-
authenticate(Mongo::Connection.new(@host, @port, @connection_options).db(@database))
|
122
|
-
when @url
|
123
|
-
parser = Mongo::URIParser.new(@url)
|
124
|
-
parser.connection.db(parser.db_name)
|
125
|
-
end
|
128
|
+
def client
|
129
|
+
@client_options[:database] = @database
|
130
|
+
@client_options[:user] = @user if @user
|
131
|
+
@client_options[:password] = @password if @password
|
132
|
+
Mongo::Client.new(["#{node_string}"], @client_options)
|
126
133
|
end
|
127
|
-
|
128
|
-
def
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
when @url
|
133
|
-
Mongo::URIParser.new(@url).db_name
|
134
|
-
end
|
134
|
+
|
135
|
+
def get_collection
|
136
|
+
@client = client
|
137
|
+
@client = authenticate(@client)
|
138
|
+
@client["#{@collection}"]
|
135
139
|
end
|
136
|
-
|
140
|
+
|
137
141
|
def node_string
|
138
142
|
case
|
139
143
|
when @database
|
@@ -143,87 +147,67 @@ module Fluent
|
|
143
147
|
end
|
144
148
|
end
|
145
149
|
|
146
|
-
def
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
@last_id = id.to_s
|
167
|
-
doc['_id_str'] = @last_id
|
168
|
-
save_last_id(@last_id)
|
169
|
-
end
|
170
|
-
|
171
|
-
# Should use MultiEventStream?
|
172
|
-
router.emit(tag, time, doc)
|
173
|
-
end
|
150
|
+
def process_documents(documents)
|
151
|
+
es = MultiEventStream.new
|
152
|
+
documents.each {|doc|
|
153
|
+
time = if @time_key
|
154
|
+
t = doc.delete(@time_key)
|
155
|
+
t.nil? ? Engine.now : t.to_i
|
156
|
+
else
|
157
|
+
Engine.now
|
158
|
+
end
|
159
|
+
tag = if @tag_key
|
160
|
+
t = doc.delete(@tag_key)
|
161
|
+
t.nil? ? 'mongo.missing_tag' : t
|
162
|
+
else
|
163
|
+
@tag
|
164
|
+
end
|
165
|
+
if @object_id_keys
|
166
|
+
@object_id_keys.each {|id_key|
|
167
|
+
doc[id_key] = doc[id_key].to_s
|
168
|
+
}
|
169
|
+
end
|
174
170
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
171
|
+
if id = doc.delete('_id')
|
172
|
+
@last_id = id.to_s
|
173
|
+
doc['_id_str'] = @last_id
|
174
|
+
save_last_id if @id_store_file
|
175
|
+
end
|
176
|
+
es.add(time, doc)
|
177
|
+
}
|
178
|
+
router.emit_stream(tag, es)
|
180
179
|
end
|
181
180
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
if
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
@id_storage = get_database.collection(@id_store_collection)
|
181
|
+
def get_last_inserted_id
|
182
|
+
last_inserted_id = nil
|
183
|
+
documents = @collection.find()
|
184
|
+
if documents.count >= 1
|
185
|
+
documents.each {|doc|
|
186
|
+
if id = doc.delete('_id')
|
187
|
+
last_inserted_id = id
|
188
|
+
end
|
189
|
+
}
|
192
190
|
end
|
191
|
+
last_inserted_id
|
193
192
|
end
|
194
|
-
|
195
|
-
def
|
196
|
-
|
197
|
-
|
198
|
-
|
193
|
+
|
194
|
+
def get_id_store_file
|
195
|
+
file = File.open(@id_store_file, 'w')
|
196
|
+
file.sync
|
197
|
+
file
|
199
198
|
end
|
200
199
|
|
201
200
|
def get_last_id
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
end
|
206
|
-
|
207
|
-
if @id_store_collection
|
208
|
-
collection = get_database.collection(@id_store_collection)
|
209
|
-
count = collection.find.count
|
210
|
-
doc = collection.find.skip(count - 1).limit(1).first
|
211
|
-
return doc && doc["last_id"]
|
212
|
-
end
|
213
|
-
rescue
|
201
|
+
if File.exist?(@id_store_file)
|
202
|
+
BSON::ObjectId(File.read(@id_store_file)).to_s rescue nil
|
203
|
+
else
|
214
204
|
nil
|
215
205
|
end
|
216
206
|
end
|
217
207
|
|
218
|
-
def save_last_id
|
219
|
-
|
220
|
-
|
221
|
-
@id_storage.write(last_id)
|
222
|
-
end
|
223
|
-
|
224
|
-
if @id_storage.is_a?(Mongo::Collection)
|
225
|
-
@id_storage.insert("last_id" => last_id)
|
226
|
-
end
|
208
|
+
def save_last_id
|
209
|
+
@file.pos = 0
|
210
|
+
@file.write(@last_id)
|
227
211
|
end
|
228
212
|
end
|
229
213
|
end
|