logstash-input-mongodb 0.3.3 → 0.4.0

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: 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: