fluent-plugin-mongo 0.8.1 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2bf1813aa5586654b52813282aa11f01c7dba05f
4
- data.tar.gz: 240c7befe5e653491b962753b250134ab48d2ee6
3
+ metadata.gz: 130e2e8712112dcda7b7d44b19448f5cd2177ccc
4
+ data.tar.gz: 79e4d7512049f24a830ccfef2b973084f9847b21
5
5
  SHA512:
6
- metadata.gz: 9ab2a0129a3bd0b2fa56d520d58a67d1bf545981d3b68ed45b577453a9f29d942b65fb3a126b07e004619b239b643653866e7b31a47b0a8b88e7a625b7644721
7
- data.tar.gz: 1e2387e3218da98c9afae121da65f1dd70fff92addef623f2c0d23d4d0054061f51c4c8635d8c1668638abdfad10f78932f49544fb02ccb27c34c97b3c66778e
6
+ metadata.gz: 635611797a2fae046e0961801e8a7f1fee7d436fcc2356406f5227b78916c6e7feb954b2d1d4d129e4573dffdf9c2627fbada20b35af35663e6ca33237cfe1ff
7
+ data.tar.gz: 642e6babffd923a6426d0bc4bb85d64608b45e372f8bb3d30de755488737d8c0d4d25eb0266a66ad226c2b9c506115b24d2d07bd08f4032f9c5d49ef33f9e200
data/.travis.yml CHANGED
@@ -1,14 +1,12 @@
1
1
  rvm:
2
- - 1.9.3
3
- - 2.0.0
4
2
  - 2.1
5
3
  - 2.2.4
6
4
  - 2.3.1
5
+ - 2.4.0
7
6
  - ruby-head
8
7
 
9
8
  gemfile:
10
9
  - Gemfile
11
- - Gemfile.v0.12
12
10
 
13
11
  services:
14
12
  - mongodb
@@ -22,10 +20,4 @@ script: bundle exec rake test
22
20
 
23
21
  matrix:
24
22
  allow_failures:
25
- - rvm: 1.9.3
26
23
  - rvm: ruby-head
27
- exclude:
28
- - rvm: 1.9.3
29
- gemfile: Gemfile
30
- - rvm: 2.0.0
31
- gemfile: Gemfile
data/ChangeLog CHANGED
@@ -1,14 +1,3 @@
1
- Release 0.8.1 - 2017/03/23
2
-
3
- * Add connection_string parameter for MongDB URI
4
- * out_mongo_replset: Add nodes parameter
5
-
6
-
7
- Release 0.8.0 - 2017/02/10
8
-
9
- * Update mongo gem dependency to v2.0 or upper
10
-
11
-
12
1
  Release 0.7.16 - 2016/10/05
13
2
 
14
3
  * out_mongo: Log warn / deprecated message for invalid record handling
data/README.rdoc CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  fluent-plugin-mongo provides input and output plugins for {Fluentd}[http://fluentd.org] ({GitHub}[http://github.com/fluent/fluentd])
4
4
 
5
+ = Requirements
6
+
7
+ |fluent-plugin-mongo| fluentd | ruby |
8
+ |-------------------|------------|--------|
9
+ | >= 1.0.0 | >= 0.14.12 | >= 2.1 |
10
+ | < 1.0.0 | ~> 0.12.0 | >= 1.9 |
11
+
5
12
  = Installation
6
13
 
7
14
  == Gems
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.8.1
1
+ 1.0.0.rc1
@@ -23,4 +23,5 @@ Gem::Specification.new do |gem|
23
23
  gem.add_development_dependency "simplecov", ">= 0.5.4"
24
24
  gem.add_development_dependency "rr", ">= 1.0.0"
25
25
  gem.add_development_dependency "test-unit", ">= 3.0.0"
26
+ gem.add_development_dependency "timecop", "~> 0.8.0"
26
27
  end
@@ -1,23 +1,19 @@
1
- require 'fluent/input'
2
-
3
- module Fluent
1
+ # coding: utf-8
2
+ require 'mongo'
3
+ require 'bson'
4
+ require 'fluent/plugin/input'
5
+ require 'fluent/plugin/mongo_auth'
6
+ require 'fluent/plugin/logger_support'
7
+
8
+ module Fluent::Plugin
4
9
  class MongoTailInput < Input
5
- Plugin.register_input('mongo_tail', self)
6
-
7
- unless method_defined?(:log)
8
- define_method(:log) { $log }
9
- end
10
+ Fluent::Plugin.register_input('mongo_tail', self)
10
11
 
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
12
+ helpers :timer
15
13
 
16
- require 'fluent/plugin/mongo_auth'
17
- include MongoAuthParams
18
- include MongoAuth
19
- require 'fluent/plugin/logger_support'
20
- include LoggerSupport
14
+ include Fluent::MongoAuthParams
15
+ include Fluent::MongoAuth
16
+ include Fluent::LoggerSupport
21
17
 
22
18
  desc "MongoDB database"
23
19
  config_param :database, :string, default: nil
@@ -50,8 +46,6 @@ module Fluent
50
46
 
51
47
  def initialize
52
48
  super
53
- require 'mongo'
54
- require 'bson'
55
49
 
56
50
  @client_options = {}
57
51
  @connection_options = {}
@@ -61,15 +55,15 @@ module Fluent
61
55
  super
62
56
 
63
57
  if !@tag and !@tag_key
64
- raise ConfigError, "'tag' or 'tag_key' option is required on mongo_tail input"
58
+ raise Fluent::ConfigError, "'tag' or 'tag_key' option is required on mongo_tail input"
65
59
  end
66
60
 
67
61
  if @database && @url
68
- raise ConfigError, "Both 'database' and 'url' can not be set"
62
+ raise Fluent::ConfigError, "Both 'database' and 'url' can not be set"
69
63
  end
70
64
 
71
65
  if !@database && !@url
72
- raise ConfigError, "One of 'database' or 'url' must be specified"
66
+ raise Fluent::ConfigError, "One of 'database' or 'url' must be specified"
73
67
  end
74
68
 
75
69
  @last_id = @id_store_file ? get_last_id : nil
@@ -86,7 +80,7 @@ module Fluent
86
80
  # Resume tailing from last inserted id.
87
81
  # Because tailable option is obsoleted since mongo driver 2.0.
88
82
  @last_id = get_last_inserted_id if !@id_store_file and get_last_inserted_id
89
- @thread = Thread.new(&method(:run))
83
+ timer_execute(:in_mongo_tail_watcher, @wait_time, &method(:run))
90
84
  end
91
85
 
92
86
  def shutdown
@@ -95,32 +89,22 @@ module Fluent
95
89
  @file.close
96
90
  end
97
91
 
98
- @stop = true
99
- @thread.join
100
92
  @client.close
101
93
 
102
94
  super
103
95
  end
104
96
 
105
97
  def run
106
- loop {
107
- option = {}
108
- begin
109
- loop {
110
- return if @stop
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)
116
- else
117
- sleep @wait_time
118
- end
119
- }
120
- rescue
121
- # ignore Exceptions
98
+ option = {}
99
+ begin
100
+ option['_id'] = {'$gt' => BSON::ObjectId(@last_id)} if @last_id
101
+ documents = @collection.find(option)
102
+ if documents.count >= 1
103
+ process_documents(documents)
122
104
  end
123
- }
105
+ rescue
106
+ # ignore Exceptions
107
+ end
124
108
  end
125
109
 
126
110
  private
@@ -148,13 +132,13 @@ module Fluent
148
132
  end
149
133
 
150
134
  def process_documents(documents)
151
- es = MultiEventStream.new
135
+ es = Fluent::MultiEventStream.new
152
136
  documents.each {|doc|
153
137
  time = if @time_key
154
138
  t = doc.delete(@time_key)
155
- t.nil? ? Engine.now : t.to_i
139
+ t.nil? ? Fluent::Engine.now : t.to_i
156
140
  else
157
- Engine.now
141
+ Fluent::Engine.now
158
142
  end
159
143
  @tag = if @tag_key
160
144
  t = doc.delete(@tag_key)
@@ -1,29 +1,26 @@
1
- require 'fluent/output'
1
+ require 'mongo'
2
+ require 'msgpack'
3
+ require 'fluent/plugin/output'
4
+ require 'fluent/plugin/mongo_auth'
5
+ require 'fluent/plugin/logger_support'
2
6
 
3
- module Fluent
4
- class MongoOutput < BufferedOutput
5
- Plugin.register_output('mongo', self)
7
+ module Fluent::Plugin
8
+ class MongoOutput < Output
9
+ Fluent::Plugin.register_output('mongo', self)
6
10
 
7
- unless method_defined?(:log)
8
- define_method(:log) { $log }
9
- end
11
+ helpers :event_emitter, :inject, :compat_parameters
10
12
 
11
- require 'fluent/plugin/mongo_auth'
12
- include MongoAuthParams
13
- include MongoAuth
14
- require 'fluent/plugin/logger_support'
15
- include LoggerSupport
13
+ include Fluent::MongoAuthParams
14
+ include Fluent::MongoAuth
15
+ include Fluent::LoggerSupport
16
16
 
17
- include SetTagKeyMixin
18
- config_set_default :include_tag_key, false
17
+ DEFAULT_BUFFER_TYPE = "memory"
19
18
 
20
- include SetTimeKeyMixin
19
+ config_set_default :include_tag_key, false
21
20
  config_set_default :include_time_key, true
22
21
 
23
- desc "MongoDB connection string"
24
- config_param :connection_string, :default => nil
25
22
  desc "MongoDB database"
26
- config_param :database, :string, :default => nil
23
+ config_param :database, :string
27
24
  desc "MongoDB collection"
28
25
  config_param :collection, :string, default: 'untagged'
29
26
  desc "MongoDB host"
@@ -53,15 +50,16 @@ module Fluent
53
50
  config_param :ssl_verify, :bool, default: false
54
51
  config_param :ssl_ca_cert, :string, default: nil
55
52
 
53
+ config_section :buffer do
54
+ config_set_default :@type, DEFAULT_BUFFER_TYPE
55
+ config_set_default :chunk_keys, ['tag']
56
+ end
57
+
56
58
  attr_reader :client_options, :collection_options
57
59
 
58
60
  def initialize
59
61
  super
60
62
 
61
- require 'mongo'
62
- require 'msgpack'
63
-
64
- @nodes = nil
65
63
  @client_options = {}
66
64
  @collection_options = {capped: false}
67
65
  end
@@ -72,10 +70,10 @@ module Fluent
72
70
 
73
71
  def configure(conf)
74
72
  if conf.has_key?('buffer_chunk_limit')
75
- configured_chunk_limit_size = Config.size_value(conf['buffer_chunk_limit'])
73
+ configured_chunk_limit_size = Fluent::Config.size_value(conf['buffer_chunk_limit'])
76
74
  estimated_limit_size = LIMIT_AFTER_v1_8
77
75
  estimated_limit_size_conf = '8m'
78
- if conf.has_key?('mongodb_smaller_bson_limit') && Config.bool_value(conf['mongodb_smaller_bson_limit'])
76
+ if conf.has_key?('mongodb_smaller_bson_limit') && Fluent::Config.bool_value(conf['mongodb_smaller_bson_limit'])
79
77
  estimated_limit_size = LIMIT_BEFORE_v1_8
80
78
  estimated_limit_size_conf = '2m'
81
79
  end
@@ -84,33 +82,31 @@ module Fluent
84
82
  conf['buffer_chunk_limit'] = estimated_limit_size_conf
85
83
  end
86
84
  else
87
- if conf.has_key?('mongodb_smaller_bson_limit') && Config.bool_value(conf['mongodb_smaller_bson_limit'])
85
+ if conf.has_key?('mongodb_smaller_bson_limit') && Fluent::Config.bool_value(conf['mongodb_smaller_bson_limit'])
88
86
  conf['buffer_chunk_limit'] = '2m'
89
87
  else
90
88
  conf['buffer_chunk_limit'] = '8m'
91
89
  end
92
90
  end
91
+ compat_parameters_convert(conf, :inject)
93
92
 
94
93
  super
95
94
 
96
- if @connection_string.nil? && @database.nil?
97
- raise Fluent::ConfigError, "connection_string or database parameter is required"
98
- end
99
-
100
95
  unless @ignore_invalid_record
101
96
  log.warn "Since v0.8, invalid record detection will be removed because mongo driver v2.x and API spec don't provide it. You may lose invalid records, so you should not send such records to mongo plugin"
102
97
  end
103
98
 
104
99
  if conf.has_key?('tag_mapped')
105
- @tag_mapped = true
100
+ log.warn "'tag_mapped' feature is replaced with built-in config placeholder. Please consider to use 'collection ${tag}'."
101
+ @collection = '${tag}'
106
102
  end
107
- raise ConfigError, "normal mode requires collection parameter" if !@tag_mapped and !conf.has_key?('collection')
103
+ raise Fluent::ConfigError, "normal mode requires collection parameter" if !@tag_mapped and !conf.has_key?('collection')
108
104
 
109
105
  if conf.has_key?('capped')
110
- raise ConfigError, "'capped_size' parameter is required on <store> of Mongo output" unless conf.has_key?('capped_size')
106
+ raise Fluent::ConfigError, "'capped_size' parameter is required on <store> of Mongo output" unless conf.has_key?('capped_size')
111
107
  @collection_options[:capped] = true
112
- @collection_options[:size] = Config.size_value(conf['capped_size'])
113
- @collection_options[:max] = Config.size_value(conf['capped_max']) if conf.has_key?('capped_max')
108
+ @collection_options[:size] = Fluent::Config.size_value(conf['capped_size'])
109
+ @collection_options[:max] = Fluent::Config.size_value(conf['capped_max']) if conf.has_key?('capped_max')
114
110
  end
115
111
 
116
112
  if remove_tag_prefix = conf['remove_tag_prefix']
@@ -128,12 +124,6 @@ module Fluent
128
124
  @client_options[:ssl_verify] = @ssl_verify
129
125
  @client_options[:ssl_ca_cert] = @ssl_ca_cert
130
126
  end
131
- @nodes = ["#{@host}:#{@port}"] if @nodes.nil?
132
-
133
- # MongoDB uses BSON's Date for time.
134
- def @timef.format_nocache(time)
135
- time
136
- end
137
127
 
138
128
  configure_logger(@mongo_log_level)
139
129
 
@@ -163,28 +153,36 @@ module Fluent
163
153
  [time, record].to_msgpack
164
154
  end
165
155
 
156
+ def formatted_to_msgpack_binary
157
+ true
158
+ end
159
+
160
+ def multi_workers_ready?
161
+ true
162
+ end
163
+
166
164
  def write(chunk)
167
- collection_name = @tag_mapped ? chunk.key : @collection
165
+ collection_name = extract_placeholders(@collection, chunk.metadata)
168
166
  operate(format_collection_name(collection_name), collect_records(chunk))
169
167
  end
170
168
 
171
169
  private
172
170
 
173
171
  def client
174
- if @connection_string
175
- Mongo::Client.new(@connection_string)
176
- else
177
- @client_options[:database] = @database
178
- @client_options[:user] = @user if @user
179
- @client_options[:password] = @password if @password
180
- Mongo::Client.new(@nodes, @client_options)
181
- end
172
+ @client_options[:database] = @database
173
+ @client_options[:user] = @user if @user
174
+ @client_options[:password] = @password if @password
175
+ Mongo::Client.new(["#{@host}:#{@port}"], @client_options)
182
176
  end
183
177
 
184
178
  def collect_records(chunk)
185
179
  records = []
180
+ time_key = @inject_config.time_key
181
+ tag = chunk.metadata.tag
186
182
  chunk.msgpack_each {|time, record|
187
- record[@time_key] = Time.at(time || record[@time_key]) if @include_time_key
183
+ record = inject_values_to_record(tag, time, record)
184
+ # MongoDB uses BSON's Date for time.
185
+ record[time_key] = Time.at(time || record[time_key]) if time_key
188
186
  records << record
189
187
  }
190
188
  records
@@ -1,18 +1,12 @@
1
1
  require 'fluent/plugin/out_mongo'
2
2
 
3
- module Fluent
3
+ module Fluent::Plugin
4
4
  class MongoOutputReplset < MongoOutput
5
- Plugin.register_output('mongo_replset', self)
6
-
7
- unless method_defined?(:log)
8
- define_method(:log) { $log }
9
- end
5
+ Fluent::Plugin.register_output('mongo_replset', self)
10
6
 
11
7
  config_set_default :include_tag_key, false
12
8
  config_set_default :include_time_key, true
13
9
 
14
- desc "Nodes of replica set"
15
- config_param :nodes, :array, value_type: :string, :default => nil
16
10
  desc "Replica set name"
17
11
  config_param :replica_set, :string
18
12
  desc "Read from specified role"
@@ -20,10 +14,6 @@ module Fluent
20
14
  desc "Retry number"
21
15
  config_param :num_retries, :integer, :default => 60
22
16
 
23
- unless method_defined?(:log)
24
- define_method(:log) { $log }
25
- end
26
-
27
17
  def configure(conf)
28
18
  super
29
19
 
@@ -37,6 +27,14 @@ module Fluent
37
27
  log.debug "Setup replica set configuration: #{conf['replica_set']}"
38
28
  end
39
29
 
30
+ def format(tag, time, record)
31
+ super
32
+ end
33
+
34
+ def write(chunk)
35
+ super
36
+ end
37
+
40
38
  private
41
39
 
42
40
  def operate(client, records)
@@ -1,4 +1,7 @@
1
1
  require "helper"
2
+ require "fluent/test/driver/input"
3
+ require "fluent/test/helpers"
4
+ require "timecop"
2
5
 
3
6
  class MongoTailInputTest < Test::Unit::TestCase
4
7
  def setup
@@ -44,7 +47,7 @@ class MongoTailInputTest < Test::Unit::TestCase
44
47
  end
45
48
 
46
49
  def create_driver(conf=default_config)
47
- Fluent::Test::InputTestDriver.new(Fluent::MongoTailInput).configure(conf)
50
+ Fluent::Test::Driver::Input.new(Fluent::Plugin::MongoTailInput).configure(conf)
48
51
  end
49
52
 
50
53
  def test_configure
@@ -67,6 +70,78 @@ class MongoTailInputTest < Test::Unit::TestCase
67
70
  assert_equal(expected, d.instance.mongo_log_level)
68
71
  end
69
72
 
73
+ class TailInputTest < self
74
+ include Fluent::Test::Helpers
75
+
76
+ def setup_mongod
77
+ options = {}
78
+ options[:database] = database_name
79
+ @client = ::Mongo::Client.new(["localhost:#{port}"], options)
80
+ @time = Time.now
81
+ Timecop.freeze(@time)
82
+ end
83
+
84
+ def teardown_mongod
85
+ @client[collection_name].drop
86
+ Timecop.return
87
+ end
88
+
89
+ def test_emit
90
+ d = create_driver(%[
91
+ @type mongo_tail
92
+ database #{database_name}
93
+ collection #{collection_name}
94
+ tag input.mongo
95
+ time_key time
96
+ ])
97
+ d.run(expect_records: 1, timeout: 5) do
98
+ @client[collection_name].insert_one({message: "test"})
99
+ end
100
+ events = d.events
101
+ assert_equal "input.mongo", events[0][0]
102
+ assert_equal event_time(@time.to_s), events[0][1]
103
+ assert_equal "test", events[0][2]["message"]
104
+ end
105
+
106
+ def test_emit_with_tag_time_keys
107
+ d = create_driver(%[
108
+ @type mongo_tail
109
+ database #{database_name}
110
+ collection #{collection_name}
111
+ tag input.mongo
112
+ tag_key tag
113
+ time_key time
114
+ ])
115
+ d.run(expect_records: 1, timeout: 5) do
116
+ @client[collection_name].insert_one({message: "test", tag: "user.defined", time: Fluent::Engine.now})
117
+ end
118
+ events = d.events
119
+ assert_equal "user.defined", events[0][0]
120
+ assert_equal event_time(@time.to_s), events[0][1]
121
+ assert_equal "test", events[0][2]["message"]
122
+ end
123
+
124
+ def test_emit_after_last_id
125
+ d = create_driver(%[
126
+ @type mongo_tail
127
+ database #{database_name}
128
+ collection #{collection_name}
129
+ tag input.mongo.last_id
130
+ time_key time
131
+ ])
132
+ @client[collection_name].insert_one({message: "can't obtain"})
133
+
134
+ d.run(expect_records: 1, timeout: 5) do
135
+ @client[collection_name].insert_one({message: "can obtain"})
136
+ end
137
+ events = d.events
138
+ assert_equal 1, events.size
139
+ assert_equal "input.mongo.last_id", events[0][0]
140
+ assert_equal event_time(@time.to_s), events[0][1]
141
+ assert_equal "can obtain", events[0][2]["message"]
142
+ end
143
+ end
144
+
70
145
  class MongoAuthenticateTest < self
71
146
  require 'fluent/plugin/mongo_auth'
72
147
  include ::Fluent::MongoAuth
@@ -1,7 +1,11 @@
1
1
  # coding: utf-8
2
2
  require "helper"
3
+ require "fluent/test/driver/output"
4
+ require "fluent/test/helpers"
3
5
 
4
6
  class MongoOutputTest < ::Test::Unit::TestCase
7
+ include Fluent::Test::Helpers
8
+
5
9
  def setup
6
10
  Fluent::Test.setup
7
11
  setup_mongod
@@ -38,17 +42,17 @@ class MongoOutputTest < ::Test::Unit::TestCase
38
42
  @client = ::Mongo::Client.new(["localhost:#{port}"], options)
39
43
  end
40
44
 
41
- def teardown_mongod
42
- @client[collection_name].drop
45
+ def teardown_mongod(collection = collection_name)
46
+ @client[collection].drop
43
47
  end
44
48
 
45
- def create_driver(conf=default_config, tag='test')
46
- Fluent::Test::BufferedOutputTestDriver.new(Fluent::MongoOutput, tag).configure(conf, true)
49
+ def create_driver(conf=default_config)
50
+ Fluent::Test::Driver::Output.new(Fluent::Plugin::MongoOutput).configure(conf)
47
51
  end
48
52
 
49
53
  def test_configure
50
54
  d = create_driver(%[
51
- @type mongo
55
+ type mongo
52
56
  database fluent_test
53
57
  collection test_collection
54
58
 
@@ -62,30 +66,6 @@ class MongoOutputTest < ::Test::Unit::TestCase
62
66
  assert_equal(port, d.instance.port)
63
67
  assert_equal({capped: true, size: 100}, d.instance.collection_options)
64
68
  assert_equal({ssl: false, write: {j: false}}, d.instance.client_options)
65
- assert_nil d.instance.connection_string
66
- end
67
-
68
- def test_configure_with_connection_string
69
- d = create_driver(%[
70
- @type mongo
71
- connection_string mongodb://localhost/fluent_test
72
- collection test_collection
73
- capped
74
- capped_size 100
75
- ])
76
- assert_equal('mongodb://localhost/fluent_test', d.instance.connection_string)
77
- assert_nil d.instance.database
78
- end
79
-
80
- def test_configure_without_connection_string_or_database
81
- assert_raise Fluent::ConfigError do
82
- d = create_driver(%[
83
- @type mongo
84
- collection test_collection
85
- capped
86
- capped_size 100
87
- ])
88
- end
89
69
  end
90
70
 
91
71
  def test_configure_with_ssl
@@ -115,6 +95,7 @@ class MongoOutputTest < ::Test::Unit::TestCase
115
95
  d = create_driver(conf)
116
96
  assert_true(d.instance.tag_mapped)
117
97
  assert_equal(/^raw\./, d.instance.remove_tag_prefix)
98
+ assert_equal('${tag}', d.instance.collection)
118
99
  end
119
100
 
120
101
  def test_configure_with_write_concern
@@ -155,61 +136,88 @@ class MongoOutputTest < ::Test::Unit::TestCase
155
136
  assert_equal(expected, d.instance.mongo_log_level)
156
137
  end
157
138
 
158
- def get_documents
159
- @client[collection_name].find.to_a.map {|e| e.delete('_id'); e}
139
+ def get_documents(collection = collection_name)
140
+ @client[collection].find.to_a.map {|e| e.delete('_id'); e}
160
141
  end
161
142
 
162
143
  def emit_documents(d)
163
- time = Time.parse("2011-01-02 13:14:15 UTC").to_i
164
- d.emit({'a' => 1}, time)
165
- d.emit({'a' => 2}, time)
144
+ time = event_time("2011-01-02 13:14:15 UTC")
145
+ d.feed(time, {'a' => 1})
146
+ d.feed(time, {'a' => 2})
166
147
  time
167
148
  end
168
149
 
169
150
  def test_format
170
151
  d = create_driver
171
152
 
172
- time = Time.parse("2011-01-02 13:14:15 UTC").to_i
173
- d.emit({'a' => 1}, time)
174
- d.emit({'a' => 2}, time)
175
- d.expect_format([time, {'a' => 1, d.instance.time_key => time}].to_msgpack)
176
- d.expect_format([time, {'a' => 2, d.instance.time_key => time}].to_msgpack)
177
- d.run
178
-
179
- documents = get_documents
180
- assert_equal(2, documents.size)
153
+ time = event_time("2011-01-02 13:14:15 UTC")
154
+ d.run(default_tag: 'test') do
155
+ d.feed(time, {'a' => 1})
156
+ d.feed(time, {'a' => 2})
157
+ end
158
+ assert_equal([time, {'a' => 1}].to_msgpack, d.formatted[0])
159
+ assert_equal([time, {'a' => 2}].to_msgpack, d.formatted[1])
160
+ assert_equal(2, d.formatted.size)
181
161
  end
182
162
 
183
163
  def test_write
184
164
  d = create_driver
185
- t = emit_documents(d)
186
-
187
- d.run
165
+ d.run(default_tag: 'test') do
166
+ emit_documents(d)
167
+ end
188
168
  actual_documents = get_documents
189
- time = Time.parse("2011-01-02 13:14:15 UTC")
190
- expected = [{'a' => 1, d.instance.time_key => time},
191
- {'a' => 2, d.instance.time_key => time}]
169
+ time = event_time("2011-01-02 13:14:15 UTC")
170
+ expected = [{'a' => 1, d.instance.inject_config.time_key => Time.at(time).localtime},
171
+ {'a' => 2, d.instance.inject_config.time_key => Time.at(time).localtime}]
192
172
  assert_equal(expected, actual_documents)
193
173
  end
194
174
 
175
+ class WriteWithCollectionPlaceholder < self
176
+ def setup
177
+ @tag = 'custom'
178
+ setup_mongod
179
+ end
180
+
181
+ def teardown
182
+ teardown_mongod(@tag)
183
+ end
184
+
185
+ def test_write_with_collection_placeholder
186
+ d = create_driver(%[
187
+ type mongo
188
+ database #{database_name}
189
+ collection ${tag}
190
+ include_time_key true
191
+ ])
192
+ d.run(default_tag: @tag) do
193
+ emit_documents(d)
194
+ end
195
+ actual_documents = get_documents(@tag)
196
+ time = event_time("2011-01-02 13:14:15 UTC")
197
+ expected = [{'a' => 1, d.instance.inject_config.time_key => Time.at(time).localtime},
198
+ {'a' => 2, d.instance.inject_config.time_key => Time.at(time).localtime}]
199
+ assert_equal(expected, actual_documents)
200
+ end
201
+ end
202
+
195
203
  def test_write_at_enable_tag
196
204
  d = create_driver(default_config + %[
197
205
  include_tag_key true
198
206
  include_time_key false
199
207
  ])
200
- t = emit_documents(d)
201
-
202
- d.run
208
+ d.run(default_tag: 'test') do
209
+ emit_documents(d)
210
+ end
203
211
  actual_documents = get_documents
204
- expected = [{'a' => 1, d.instance.tag_key => 'test'},
205
- {'a' => 2, d.instance.tag_key => 'test'}]
212
+ expected = [{'a' => 1, d.instance.inject_config.tag_key => 'test'},
213
+ {'a' => 2, d.instance.inject_config.tag_key => 'test'}]
206
214
  assert_equal(expected, actual_documents)
207
215
  end
208
216
 
209
217
  def emit_invalid_documents(d)
210
- time = Time.parse("2011-01-02 13:14:15 UTC").to_i
211
- d.emit({'a' => 3, 'b' => "c", '$last' => '石動'}, time)
212
- d.emit({'a' => 4, 'b' => "d", 'first' => '菖蒲'.encode('EUC-JP').force_encoding('UTF-8')}, time)
218
+ time = event_time("2011-01-02 13:14:15 UTC")
219
+ d.feed(time, {'a' => 3, 'b' => "c", '$last' => '石動'})
220
+ d.feed(time, {'a' => 4, 'b' => "d", 'first' => '菖蒲'.encode('EUC-JP').force_encoding('UTF-8')})
213
221
  time
214
222
  end
215
223
 
@@ -219,19 +227,19 @@ class MongoOutputTest < ::Test::Unit::TestCase
219
227
  replace_dollar_in_key_with _dollar_
220
228
  ])
221
229
 
222
- original_time = "2016-02-01 13:14:15 UTC"
223
- time = Time.parse(original_time).to_i
224
- d.emit({
225
- "foo.bar1" => {
226
- "$foo$bar" => "baz"
227
- },
228
- "foo.bar2" => [
229
- {
230
- "$foo$bar" => "baz"
231
- }
232
- ],
233
- }, time)
234
- d.run
230
+ time = event_time("2011-01-02 13:14:15 UTC")
231
+ d.run(default_tag: 'test') do
232
+ d.feed(time, {
233
+ "foo.bar1" => {
234
+ "$foo$bar" => "baz"
235
+ },
236
+ "foo.bar2" => [
237
+ {
238
+ "$foo$bar" => "baz"
239
+ }
240
+ ],
241
+ })
242
+ end
235
243
 
236
244
  documents = get_documents
237
245
  expected = {"foo_dot_bar1" => {
@@ -241,7 +249,7 @@ class MongoOutputTest < ::Test::Unit::TestCase
241
249
  {
242
250
  "_dollar_foo$bar"=>"baz"
243
251
  },
244
- ], "time" => Time.parse(original_time)
252
+ ], "time" => Time.at(time).localtime
245
253
  }
246
254
  assert_equal(1, documents.size)
247
255
  assert_equal(expected, documents[0])
@@ -266,13 +274,13 @@ class MongoOutputTest < ::Test::Unit::TestCase
266
274
  user fluent
267
275
  password password
268
276
  ])
269
- t = emit_documents(d)
270
-
271
- d.run
277
+ d.run(default_tag: 'test') do
278
+ emit_documents(d)
279
+ end
272
280
  actual_documents = get_documents
273
- time = Time.parse("2011-01-02 13:14:15 UTC")
274
- expected = [{'a' => 1, d.instance.time_key => time},
275
- {'a' => 2, d.instance.time_key => time}]
281
+ time = event_time("2011-01-02 13:14:15 UTC")
282
+ expected = [{'a' => 1, d.instance.inject_config.time_key => Time.at(time).localtime},
283
+ {'a' => 2, d.instance.inject_config.time_key => Time.at(time).localtime}]
276
284
  assert_equal(expected, actual_documents)
277
285
  end
278
286
  end
@@ -1,6 +1,11 @@
1
1
  require "helper"
2
+ require "fluent/test/driver/output"
3
+ require "fluent/test/helpers"
4
+ require 'fluent/mixin' # for TimeFormatter
2
5
 
3
6
  class MongoReplsetOutputTest < ::Test::Unit::TestCase
7
+ include Fluent::Test::Helpers
8
+
4
9
  def setup
5
10
  Fluent::Test.setup
6
11
  end
@@ -16,18 +21,14 @@ class MongoReplsetOutputTest < ::Test::Unit::TestCase
16
21
  'fluent_test'
17
22
  end
18
23
 
19
- def nodes
20
- ["localhost:#{port}"]
21
- end
22
-
23
24
  def port
24
25
  27018
25
26
  end
26
27
 
27
28
  def default_config
28
29
  %[
29
- @type mongo_replset
30
- nodes localhost:27018
30
+ type mongo
31
+ port 27018
31
32
  database #{database_name}
32
33
  collection #{collection_name}
33
34
  include_time_key true
@@ -35,39 +36,24 @@ class MongoReplsetOutputTest < ::Test::Unit::TestCase
35
36
  ]
36
37
  end
37
38
 
38
- def create_driver(conf=default_config, tag='test')
39
- Fluent::Test::BufferedOutputTestDriver.new(Fluent::MongoOutputReplset, tag).configure(conf, true)
39
+ def create_driver(conf=default_config)
40
+ Fluent::Test::Driver::Output.new(Fluent::Plugin::MongoOutputReplset).configure(conf)
40
41
  end
41
42
 
42
43
  def test_configure
43
44
  d = create_driver(%[
44
- @type mongo_replset
45
+ type mongo
45
46
  port 27018
46
47
  database fluent_test
47
48
  collection test_collection
48
- replica_set rs0
49
- ])
50
49
 
51
- assert_equal('fluent_test', d.instance.database)
52
- assert_equal('test_collection', d.instance.collection)
53
- assert_equal('localhost', d.instance.host)
54
- assert_equal(27018, d.instance.port)
55
- assert_equal({replica_set: 'rs0', :ssl=>false, :write=>{:j=>false}},
56
- d.instance.client_options)
57
- end
58
-
59
- def test_configure_with_nodes
60
- d = create_driver(%[
61
- @type mongo_replset
62
- nodes localhost:27018,localhost:27019
63
- database fluent_test
64
- collection test_collection
65
50
  replica_set rs0
66
51
  ])
67
52
 
68
53
  assert_equal('fluent_test', d.instance.database)
69
54
  assert_equal('test_collection', d.instance.collection)
70
- assert_equal(['localhost:27018', 'localhost:27019'], d.instance.nodes)
55
+ assert_equal('localhost', d.instance.host)
56
+ assert_equal(port, d.instance.port)
71
57
  assert_equal({replica_set: 'rs0', :ssl=>false, :write=>{:j=>false}},
72
58
  d.instance.client_options)
73
59
  end
@@ -97,7 +83,7 @@ class MongoReplsetOutputTest < ::Test::Unit::TestCase
97
83
  def setup_mongod
98
84
  options = {}
99
85
  options[:database] = database_name
100
- @client = ::Mongo::Client.new(nodes, options)
86
+ @client = ::Mongo::Client.new(["localhost:#{port}"], options)
101
87
  end
102
88
 
103
89
  def teardown_mongod
@@ -109,35 +95,34 @@ class MongoReplsetOutputTest < ::Test::Unit::TestCase
109
95
  end
110
96
 
111
97
  def emit_documents(d)
112
- time = Time.parse("2011-01-02 13:14:15 UTC").to_i
113
- d.emit({'a' => 1}, time)
114
- d.emit({'a' => 2}, time)
98
+ time = event_time("2011-01-02 13:14:15 UTC")
99
+ d.feed(time, {'a' => 1})
100
+ d.feed(time, {'a' => 2})
115
101
  time
116
102
  end
117
103
 
118
104
  def test_format
119
105
  d = create_driver
120
106
 
121
- time = Time.parse("2011-01-02 13:14:15 UTC").to_i
122
- d.emit({'a' => 1}, time)
123
- d.emit({'a' => 2}, time)
124
- d.expect_format([time, {'a' => 1, d.instance.time_key => time}].to_msgpack)
125
- d.expect_format([time, {'a' => 2, d.instance.time_key => time}].to_msgpack)
126
- d.run
127
-
128
- documents = get_documents
129
- assert_equal(2, documents.size)
107
+ time = event_time("2011-01-02 13:14:15 UTC")
108
+ d.run(default_tag: 'test') do
109
+ d.feed(time, {'a' => 1})
110
+ d.feed(time, {'a' => 2})
111
+ end
112
+ assert_equal([time, {'a' => 1}].to_msgpack, d.formatted[0])
113
+ assert_equal([time, {'a' => 2}].to_msgpack, d.formatted[1])
114
+ assert_equal(2, d.formatted.size)
130
115
  end
131
116
 
132
117
  def test_write
133
118
  d = create_driver
134
- t = emit_documents(d)
135
-
136
- d.run
119
+ d.run(default_tag: 'test') do
120
+ emit_documents(d)
121
+ end
137
122
  actual_documents = get_documents
138
- time = Time.parse("2011-01-02 13:14:15 UTC")
139
- expected = [{'a' => 1, d.instance.time_key => time},
140
- {'a' => 2, d.instance.time_key => time}]
123
+ time = event_time("2011-01-02 13:14:15 UTC")
124
+ expected = [{'a' => 1, d.instance.inject_config.time_key => Time.at(time).localtime},
125
+ {'a' => 2, d.instance.inject_config.time_key => Time.at(time).localtime}]
141
126
  assert_equal(expected, actual_documents)
142
127
  end
143
128
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-mongo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.1
4
+ version: 1.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Nakagawa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-22 00:00:00.000000000 Z
11
+ date: 2017-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -100,6 +100,20 @@ dependencies:
100
100
  - - ">="
101
101
  - !ruby/object:Gem::Version
102
102
  version: 3.0.0
103
+ - !ruby/object:Gem::Dependency
104
+ name: timecop
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 0.8.0
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 0.8.0
103
117
  description: MongoDB plugin for Fluentd
104
118
  email: repeatedly@gmail.com
105
119
  executables:
@@ -112,7 +126,6 @@ files:
112
126
  - AUTHORS
113
127
  - ChangeLog
114
128
  - Gemfile
115
- - Gemfile.v0.12
116
129
  - README.rdoc
117
130
  - Rakefile
118
131
  - VERSION
@@ -142,9 +155,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
142
155
  version: '0'
143
156
  required_rubygems_version: !ruby/object:Gem::Requirement
144
157
  requirements:
145
- - - ">="
158
+ - - ">"
146
159
  - !ruby/object:Gem::Version
147
- version: '0'
160
+ version: 1.3.1
148
161
  requirements: []
149
162
  rubyforge_project:
150
163
  rubygems_version: 2.5.2
data/Gemfile.v0.12 DELETED
@@ -1,6 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gem 'json', '= 1.8.3'
4
- gem 'fluentd', '~> 0.12.0'
5
-
6
- gemspec