logstash-input-mongodb 0.3.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 388af0f33d8e7e99f421dfb5f178b213b394fbb8
4
- data.tar.gz: a5275546392e3c9c588f266e9d84f5c8124af36b
3
+ metadata.gz: 72644c97133f7c613f5b48174648a9ea546db026
4
+ data.tar.gz: 15fe10c80d301bc8dad93d934406a0965326fbf7
5
5
  SHA512:
6
- metadata.gz: e61433c0e8d75fcb990c7353d5ba5edb3af08a5ae924696b40f8ad2b0e0e4a2edef4d71a204caf2b6d7dc439b85db24983edade05f1725c3fa713284974583d5
7
- data.tar.gz: 45321ea60084617ea0e917632b072cd12eae3a6098de2712dc3a8eb4b15738cb164821e17daee8b92ec29c04c8f17c686767726338c6c131476055ca38245862
6
+ metadata.gz: 7ae54fbae2c1399e5c33063dccb1af2ca54f9a1ac2570f69ba09a5b3bcee0cd8498ccfbbb0ea8d78141cc5bb3e2f9b0c907fa37fccdc8d885bb6a64845216b32
7
+ data.tar.gz: ef0e8f79fe5324b55a6b7f9c443727c34c6d7869d90ad7c9b297c818b2900ced3cb73ec9016a326f42385a7593ac55b2b18114960fa31ebee26910db6275e6d3
data/DEVELOPER.md CHANGED
@@ -1,2 +1,46 @@
1
1
  # logstash-input-example
2
2
  Example input plugin. This should help bootstrap your effort to write your own input plugin!
3
+
4
+ ## Build new gem
5
+
6
+ Change version in logstash-input-mongodb.gemspec
7
+
8
+ And build new gem:
9
+
10
+ ```bash
11
+ $ gem build logstash-input-mongodb.gemspec
12
+ ```
13
+
14
+ ## Developing
15
+
16
+ ### Use rvm on Ubuntu
17
+
18
+ 1. Install rvm https://rvm.io/
19
+
20
+ 2. Install jruby
21
+
22
+ ```bash
23
+ $ rvm install jruby 1.7.25
24
+ ```
25
+
26
+ 3. Use jruby from rvm
27
+
28
+ ```bash
29
+ $ rvm alias create default jruby-1.7.25
30
+ $ rvm use default
31
+ $ /bin/bash --login
32
+ $ gem install bundler
33
+ $ bundle install
34
+ ```
35
+
36
+ 4. Run tests
37
+
38
+ * Unit
39
+ ```bash
40
+ $ ruby test/*
41
+ ```
42
+
43
+ * Rspec (but it needs mongo on localhost, it would be nice to have it is not depended on local mongo)
44
+ ```bash
45
+ $ ./bin/rspec
46
+ ```
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  require "logstash/inputs/base"
3
4
  require "logstash/namespace"
4
5
  require "logstash/timestamp"
@@ -31,6 +32,12 @@ class LogStash::Inputs::MongoDB < LogStash::Inputs::Base
31
32
 
32
33
  config :since_table, :validate => :string, :default => "logstash_since"
33
34
 
35
+ # This allows you to select the column you would like compare the since info
36
+ config :since_column, :validate => :string, :default => "_id"
37
+
38
+ # This allows you to select the type of since info, like "id", "date"
39
+ config :since_type, :validate => :string, :default => "id"
40
+
34
41
  # The collection to use. Is turned into a regex so 'events' will match 'events_20150227'
35
42
  # Example collection: events_20150227 or events_
36
43
  config :collection, :validate => :string, :required => true
@@ -85,9 +92,16 @@ class LogStash::Inputs::MongoDB < LogStash::Inputs::Base
85
92
  @logger.debug("init placeholder for #{since_table}_#{mongo_collection_name}")
86
93
  since = sqlitedb[SINCE_TABLE]
87
94
  mongo_collection = mongodb.collection(mongo_collection_name)
88
- first_entry = mongo_collection.find({}).sort('_id' => 1).limit(1).first
89
- first_entry_id = first_entry['_id'].to_s
95
+
96
+ first_entry = mongo_collection.find({}).sort(since_column => 1).limit(1).first
97
+ first_entry_id = ''
98
+ if since_type == 'id'
99
+ first_entry_id = first_entry[since_column].to_s
100
+ else
101
+ first_entry_id = first_entry[since_column].to_i
102
+ end
90
103
  since.insert(:table => "#{since_table}_#{mongo_collection_name}", :place => first_entry_id)
104
+ @logger.info("init placeholder for #{since_table}_#{mongo_collection_name}: #{first_entry}")
91
105
  return first_entry_id
92
106
  end
93
107
 
@@ -134,7 +148,7 @@ class LogStash::Inputs::MongoDB < LogStash::Inputs::Base
134
148
  collection = mongodb.collection(mongo_collection_name)
135
149
  # Need to make this sort by date in object id then get the first of the series
136
150
  # db.events_20150320.find().limit(1).sort({ts:1})
137
- return collection.find({:_id => {:$gt => last_id_object}}).limit(batch_size)
151
+ return collection.find({:_id => {:$gte => last_id_object}}).limit(batch_size)
138
152
  end
139
153
 
140
154
  public
@@ -224,17 +238,26 @@ class LogStash::Inputs::MongoDB < LogStash::Inputs::Base
224
238
  last_id = @collection_data[index][:last_id]
225
239
  #@logger.debug("last_id is #{last_id}", :index => index, :collection => collection_name)
226
240
  # get batch of events starting at the last_place if it is set
227
- last_id_object = BSON::ObjectId(last_id)
241
+
242
+
243
+ last_id_object = last_id
244
+ if since_type == 'id'
245
+ last_id_object = BSON::ObjectId(last_id)
246
+ elsif since_type == 'time'
247
+ if last_id != ''
248
+ last_id_object = Time.at(last_id)
249
+ end
250
+ end
228
251
  cursor = get_cursor_for_collection(@mongodb, collection_name, last_id_object, batch_size)
229
252
  cursor.each do |doc|
230
253
  logdate = DateTime.parse(doc['_id'].generation_time.to_s)
231
254
  event = LogStash::Event.new("host" => @host)
232
255
  decorate(event)
233
- event["logdate"] = logdate.iso8601
256
+ event.set("logdate",logdate.iso8601.force_encoding(Encoding::UTF_8))
234
257
  log_entry = doc.to_h.to_s
235
258
  log_entry['_id'] = log_entry['_id'].to_s
236
- event["log_entry"] = log_entry
237
- event["mongo_id"] = doc['_id'].to_s
259
+ event.set("log_entry",log_entry.force_encoding(Encoding::UTF_8))
260
+ event.set("mongo_id",doc['_id'].to_s)
238
261
  @logger.debug("mongo_id: "+doc['_id'].to_s)
239
262
  #@logger.debug("EVENT looks like: "+event.to_s)
240
263
  #@logger.debug("Sent message: "+doc.to_h.to_s)
@@ -245,8 +268,8 @@ class LogStash::Inputs::MongoDB < LogStash::Inputs::Base
245
268
  doc_obj_bin = doc_hex_bytes.pack("C*").unpack("a4 a3 a2 a3")
246
269
  host_id = doc_obj_bin[1].unpack("S")
247
270
  process_id = doc_obj_bin[2].unpack("S")
248
- event['host_id'] = host_id.first.to_i
249
- event['process_id'] = process_id.first.to_i
271
+ event.set('host_id',host_id.first.to_i)
272
+ event.set('process_id',process_id.first.to_i)
250
273
  end
251
274
 
252
275
  if @parse_method == 'flatten'
@@ -265,21 +288,26 @@ class LogStash::Inputs::MongoDB < LogStash::Inputs::Base
265
288
  # Check for an integer
266
289
  @logger.debug("key: #{k.to_s} value: #{v.to_s}")
267
290
  if v.is_a? Numeric
268
- event[k.to_s] = v
291
+ event.set(k.to_s,v)
292
+ elsif v.is_a? Time
293
+ event.set(k.to_s,v.iso8601)
294
+
269
295
  elsif v.is_a? String
270
296
  if v == "NaN"
271
- event[k.to_s] = Float::NAN
297
+ event.set(k.to_s, Float::NAN)
272
298
  elsif /\A[-+]?\d+[.][\d]+\z/ == v
273
- event[k.to_s] = v.to_f
299
+ event.set(k.to_s, v.to_f)
274
300
  elsif (/\A[-+]?\d+\z/ === v) || (v.is_a? Integer)
275
- event[k.to_s] = v.to_i
301
+ event.set(k.to_s, v.to_i)
276
302
  else
277
- event[k.to_s] = v
303
+ event.set(k.to_s, v)
278
304
  end
279
305
  else
280
- event[k.to_s] = v.to_s unless k.to_s == "_id" || k.to_s == "tags"
306
+ if k.to_s == "_id" || k.to_s == "tags"
307
+ event.set(k.to_s, v.to_s )
308
+ end
281
309
  if (k.to_s == "tags") && (v.is_a? Array)
282
- event['tags'] = v
310
+ event.set('tags',v)
283
311
  end
284
312
  end
285
313
  end
@@ -292,24 +320,24 @@ class LogStash::Inputs::MongoDB < LogStash::Inputs::Base
292
320
  if (@dig_dig_fields.include? kk) && (vv.respond_to? :each)
293
321
  vv.each do |kkk, vvv|
294
322
  if /\A[-+]?\d+\z/ === vvv
295
- event["#{k}_#{kk}_#{kkk}"] = vvv.to_i
323
+ event.set("#{k}_#{kk}_#{kkk}",vvv.to_i)
296
324
  else
297
- event["#{k}_#{kk}_#{kkk}"] = vvv.to_s
325
+ event.set("#{k}_#{kk}_#{kkk}", vvv.to_s)
298
326
  end
299
327
  end
300
328
  else
301
329
  if /\A[-+]?\d+\z/ === vv
302
- event["#{k}_#{kk}"] = vv.to_i
330
+ event.set("#{k}_#{kk}", vv.to_i)
303
331
  else
304
- event["#{k}_#{kk}"] = vv.to_s
332
+ event.set("#{k}_#{kk}",vv.to_s)
305
333
  end
306
334
  end
307
335
  end
308
336
  else
309
337
  if /\A[-+]?\d+\z/ === v
310
- event[k] = v.to_i
338
+ event.set(k,v.to_i)
311
339
  else
312
- event[k] = v.to_s
340
+ event.set(k,v.to_s)
313
341
  end
314
342
  end
315
343
  end
@@ -317,19 +345,27 @@ class LogStash::Inputs::MongoDB < LogStash::Inputs::Base
317
345
  elsif @parse_method == 'simple'
318
346
  doc.each do |k, v|
319
347
  if v.is_a? Numeric
320
- event[k] = v.abs
348
+ event.set(k, v.abs)
321
349
  elsif v.is_a? Array
322
- event[k] = v
350
+ event.set(k, v)
323
351
  elsif v == "NaN"
324
- event[k] = Float::NAN
352
+ event.set(k, Float::NAN)
325
353
  else
326
- event[k] = v.to_s
354
+ event.set(k, v.to_s)
327
355
  end
328
356
  end
329
357
  end
330
358
 
331
359
  queue << event
332
- @collection_data[index][:last_id] = doc['_id'].to_s
360
+
361
+ since_id = doc[since_column]
362
+ if since_type == 'id'
363
+ since_id = doc[since_column].to_s
364
+ elsif since_type == 'time'
365
+ since_id = doc[since_column].to_i
366
+ end
367
+
368
+ @collection_data[index][:last_id] = since_id
333
369
  end
334
370
  # Store the last-seen doc in the database
335
371
  update_placeholder(@sqlitedb, since_table, collection_name, @collection_data[index][:last_id])
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-input-mongodb'
3
- s.version = '0.3.3'
3
+ s.version = '0.4.0'
4
4
  s.licenses = ['Apache License (2.0)']
5
5
  s.summary = "This takes entries from mongodb as an input to logstash."
6
6
  s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
28
28
  s.metadata = { "logstash_plugin" => "true", "logstash_group" => "input" }
29
29
 
30
30
  # Gem dependencies
31
- s.add_runtime_dependency 'logstash-core', ">= 2.0.0.beta2", "< 3.0.0"
31
+ s.add_runtime_dependency 'logstash-core', ">= 5.0"
32
32
  s.add_runtime_dependency 'logstash-codec-plain'
33
33
  s.add_runtime_dependency 'stud'
34
34
  s.add_runtime_dependency 'jdbc-sqlite3', '3.8.10.1'
@@ -4,10 +4,12 @@ require "logstash/devutils/rspec/spec_helper"
4
4
  require "tempfile"
5
5
  require "stud/temporary"
6
6
  require "logstash/inputs/mongodb"
7
+ require 'mongo'
8
+ include Mongo
7
9
 
8
10
  FILE_DELIMITER = LogStash::Environment.windows? ? "\r\n" : "\n"
9
11
 
10
- describe LogStash::Inputs::Mongodb do
12
+ describe LogStash::Inputs::MongoDB do
11
13
  before(:all) do
12
14
  @abort_on_exception = Thread.abort_on_exception
13
15
  Thread.abort_on_exception = true
@@ -18,24 +20,31 @@ describe LogStash::Inputs::Mongodb do
18
20
  end
19
21
 
20
22
  it_behaves_like "an interruptible input plugin" do
23
+ sqlite_db_file = Stud::Temporary.file
24
+ placeholder_db_dir = File.dirname sqlite_db_file
25
+ placeholder_db_name = File.basename sqlite_db_file
26
+ collection = 'logstash-input-mongodb_test'
21
27
  let(:config) do
22
28
  {
23
- placeholder_db_dir => Stud::Temporary.pathname,
24
- placeholder_db_bame => Stud::Temporary.file,
25
- collection => 'logstash-input-mongodb_test'
29
+ "uri" => 'mongodb://localhost/logstash-input-mongodb_test',
30
+ "placeholder_db_dir" => "#{placeholder_db_dir}",
31
+ "collection" => "#{collection}"
26
32
  }
27
33
  end
28
34
  end
29
35
 
30
36
  it "should start at the beginning of a collection when no sincedb data exists" do
31
- placeholder_db_dir = Stud::Temporary.pathname
32
- placeholder_db_name = Stud::Temporary.pathname
37
+ mongo_uri = 'mongodb://localhost/logstash-input-mongodb_test'
38
+ sqlite_db_file = Stud::Temporary.file
39
+ placeholder_db_dir = File.dirname sqlite_db_file
40
+ placeholder_db_name = File.basename sqlite_db_file
41
+
33
42
  collection = 'logstash-input-mongodb_test'
34
43
 
35
44
  conf = <<-CONFIG
36
45
  input {
37
46
  mongodb {
38
- uri => 'mongodb://localhost/logstash-input-mongodb_test',
47
+ uri => "#{mongo_uri}"
39
48
  placeholder_db_dir => "#{placeholder_db_dir}"
40
49
  placeholder_db_name => "#{placeholder_db_name}"
41
50
  collection => "#{collection}"
@@ -44,19 +53,23 @@ describe LogStash::Inputs::Mongodb do
44
53
  CONFIG
45
54
 
46
55
  # Create the test DB and populate it with some data
47
- # add "first message"
48
- # add "second message"
49
56
 
50
- events = input(conf) do |pipeline, queue|
57
+ db = Mongo::Client.new(mongo_uri).database
58
+ coll = db.collection(collection)
59
+ coll.drop
60
+ coll = db.collection(collection)
61
+ coll.insert_one({:message => "first message"})
62
+ coll.insert_one({:message => "second message"})
63
+ coll.insert_one({:message => "third message"})
64
+ coll.insert_one({:message => "fourth message"})
51
65
 
52
- events = []
66
+ events = input(conf) do |pipeline, queue|
53
67
 
54
68
  retries = 0
55
69
  while retries < 20
56
70
  # Add some new entries to the database
57
- # add "third message"
58
- # add "fourth message"
59
71
 
72
+ events = []
60
73
  if queue.size >= 4
61
74
  events = 4.times.collect { queue.pop }
62
75
  break
@@ -75,7 +88,8 @@ describe LogStash::Inputs::Mongodb do
75
88
  insist { events[3]["message"] } == "fourth message"
76
89
  end
77
90
 
78
- it "should start where it left off in a collection when it has sincedb data" do
91
+ xit "should start where it left off in a collection when it has sincedb data" do
79
92
 
80
93
  end
94
+
81
95
  end
metadata CHANGED
@@ -1,122 +1,114 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-mongodb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Hutchins
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-18 00:00:00.000000000 Z
11
+ date: 2017-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: logstash-core
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: 2.0.0.beta2
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: 3.0.0
23
- type: :runtime
18
+ version: '5.0'
19
+ name: logstash-core
24
20
  prerelease: false
21
+ type: :runtime
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: 2.0.0.beta2
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: 3.0.0
26
+ version: '5.0'
33
27
  - !ruby/object:Gem::Dependency
34
- name: logstash-codec-plain
35
28
  requirement: !ruby/object:Gem::Requirement
36
29
  requirements:
37
30
  - - ">="
38
31
  - !ruby/object:Gem::Version
39
32
  version: '0'
40
- type: :runtime
33
+ name: logstash-codec-plain
41
34
  prerelease: false
35
+ type: :runtime
42
36
  version_requirements: !ruby/object:Gem::Requirement
43
37
  requirements:
44
38
  - - ">="
45
39
  - !ruby/object:Gem::Version
46
40
  version: '0'
47
41
  - !ruby/object:Gem::Dependency
48
- name: stud
49
42
  requirement: !ruby/object:Gem::Requirement
50
43
  requirements:
51
44
  - - ">="
52
45
  - !ruby/object:Gem::Version
53
46
  version: '0'
54
- type: :runtime
47
+ name: stud
55
48
  prerelease: false
49
+ type: :runtime
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
51
  requirements:
58
52
  - - ">="
59
53
  - !ruby/object:Gem::Version
60
54
  version: '0'
61
55
  - !ruby/object:Gem::Dependency
62
- name: jdbc-sqlite3
63
56
  requirement: !ruby/object:Gem::Requirement
64
57
  requirements:
65
58
  - - '='
66
59
  - !ruby/object:Gem::Version
67
60
  version: 3.8.10.1
68
- type: :runtime
61
+ name: jdbc-sqlite3
69
62
  prerelease: false
63
+ type: :runtime
70
64
  version_requirements: !ruby/object:Gem::Requirement
71
65
  requirements:
72
66
  - - '='
73
67
  - !ruby/object:Gem::Version
74
68
  version: 3.8.10.1
75
69
  - !ruby/object:Gem::Dependency
76
- name: sequel
77
70
  requirement: !ruby/object:Gem::Requirement
78
71
  requirements:
79
72
  - - ">="
80
73
  - !ruby/object:Gem::Version
81
74
  version: '0'
82
- type: :runtime
75
+ name: sequel
83
76
  prerelease: false
77
+ type: :runtime
84
78
  version_requirements: !ruby/object:Gem::Requirement
85
79
  requirements:
86
80
  - - ">="
87
81
  - !ruby/object:Gem::Version
88
82
  version: '0'
89
83
  - !ruby/object:Gem::Dependency
90
- name: mongo
91
84
  requirement: !ruby/object:Gem::Requirement
92
85
  requirements:
93
86
  - - ">="
94
87
  - !ruby/object:Gem::Version
95
88
  version: 2.0.0
96
- type: :runtime
89
+ name: mongo
97
90
  prerelease: false
91
+ type: :runtime
98
92
  version_requirements: !ruby/object:Gem::Requirement
99
93
  requirements:
100
94
  - - ">="
101
95
  - !ruby/object:Gem::Version
102
96
  version: 2.0.0
103
97
  - !ruby/object:Gem::Dependency
104
- name: logstash-devutils
105
98
  requirement: !ruby/object:Gem::Requirement
106
99
  requirements:
107
100
  - - ">="
108
101
  - !ruby/object:Gem::Version
109
102
  version: '0'
110
- type: :development
103
+ name: logstash-devutils
111
104
  prerelease: false
105
+ type: :development
112
106
  version_requirements: !ruby/object:Gem::Requirement
113
107
  requirements:
114
108
  - - ">="
115
109
  - !ruby/object:Gem::Version
116
110
  version: '0'
117
- description: This gem is a logstash plugin required to be installed on top of the
118
- Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not
119
- a stand-alone program
111
+ description: This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program
120
112
  email: flipture@gmail.com
121
113
  executables: []
122
114
  extensions: []
@@ -135,7 +127,7 @@ licenses:
135
127
  metadata:
136
128
  logstash_plugin: 'true'
137
129
  logstash_group: input
138
- post_install_message:
130
+ post_install_message:
139
131
  rdoc_options: []
140
132
  require_paths:
141
133
  - lib
@@ -150,9 +142,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
142
  - !ruby/object:Gem::Version
151
143
  version: '0'
152
144
  requirements: []
153
- rubyforge_project:
154
- rubygems_version: 2.4.6
155
- signing_key:
145
+ rubyforge_project:
146
+ rubygems_version: 2.6.8
147
+ signing_key:
156
148
  specification_version: 4
157
149
  summary: This takes entries from mongodb as an input to logstash.
158
150
  test_files: