logstash-output-elasticsearch 1.0.6-java → 1.0.7-java

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: ac1e8c0d30366df1953643db0a74114fde945b6c
4
- data.tar.gz: c204a762798c0168acd124e17610d699e73b2244
3
+ metadata.gz: 6859ba9736d257c039dd16c08ee0d9e6e233c914
4
+ data.tar.gz: f645572dac0a860dce40e09d5f81e732b37abab3
5
5
  SHA512:
6
- metadata.gz: ff724d09052909f07c31175b8606ee0173fd63120ab447fbad768dcece005a59f97fd36297096b4349141f8b2ac8b97dcf86e261d45220fe01b7c180351f8ee7
7
- data.tar.gz: 111550510df082e50e2b9a3fe591137a610fd75dca925f2ae032f5c7f62c03c1b8a213ae1191dbcafe3f9e1a6475abb69819475e494854d846ea3391c9bd1300
6
+ metadata.gz: 3fb6d1a7ecb3c40b2f376cb50f00db79e9573cd2cdad844d71e4aae3523aa76a2d2e018fa72916625d9eab414a4bfdd16733b1a8ec01add0020fe530268622ae
7
+ data.tar.gz: f05821d1741b5b478090cbcb328aa4e33141d2b796b0dcf02bccaea3ab7c18910564f54bdc631b23effb7063e25d4f2c1b119f8febc5b5cb6c9f9d3d924d079c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 1.0.7
2
+ - Add update API support
3
+
1
4
  ## 1.0.6
2
5
  - Fix warning about Concurrent lib deprecation
3
6
 
@@ -102,6 +102,19 @@ module LogStash::Outputs::Elasticsearch
102
102
 
103
103
  def bulk(actions)
104
104
  bulk_response = @client.bulk(:body => actions.collect do |action, args, source|
105
+ if action == 'update'
106
+ if args[:_id]
107
+ source = { 'doc' => source }
108
+ if @options[:doc_as_upsert]
109
+ source['doc_as_upsert'] = true
110
+ else
111
+ source['upsert'] = args[:_upsert] if args[:_upsert]
112
+ end
113
+ else
114
+ raise(LogStash::ConfigurationError, "Specifying action => 'update' without a document '_id' is not supported.")
115
+ end
116
+ end
117
+ args.delete(:_upsert)
105
118
  if source
106
119
  next [ { action => args }, source ]
107
120
  else
@@ -254,9 +267,21 @@ module LogStash::Outputs::Elasticsearch
254
267
  else
255
268
  raise(LogStash::ConfigurationError, "Specifying action => 'create_unless_exists' without a document '_id' is not supported.")
256
269
  end
270
+ when "update"
271
+ unless args[:_id].nil?
272
+ request = org.elasticsearch.action.update.UpdateRequest.new(args[:_index], args[:_type], args[:_id])
273
+ request.routing(args[:_routing]) if args[:_routing]
274
+ request.doc(source)
275
+ if @options[:doc_as_upsert]
276
+ request.docAsUpsert(true)
277
+ else
278
+ request.upsert(args[:_upsert]) if args[:_upsert]
279
+ end
280
+ else
281
+ raise(LogStash::ConfigurationError, "Specifying action => 'update' without a document '_id' is not supported.")
282
+ end
257
283
  else
258
284
  raise(LogStash::ConfigurationError, "action => '#{action_name}' is not currently supported.")
259
- #when "update"
260
285
  end # case action
261
286
 
262
287
  request.type(args[:_type]) if args[:_type]
@@ -65,7 +65,7 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
65
65
  attr_reader :client
66
66
 
67
67
  include Stud::Buffer
68
- RETRYABLE_CODES = [429, 503]
68
+ RETRYABLE_CODES = [409, 429, 503]
69
69
  SUCCESS_CODES = [200, 201]
70
70
 
71
71
  config_name "elasticsearch"
@@ -257,6 +257,7 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
257
257
  # - index: indexes a document (an event from Logstash).
258
258
  # - delete: deletes a document by id
259
259
  # - create: indexes a document, fails if a document by that id already exists in the index.
260
+ # - update: updates a document by id
260
261
  # following action is not supported by HTTP protocol
261
262
  # - create_unless_exists: creates a document, fails if no id is provided
262
263
  #
@@ -317,6 +318,14 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
317
318
  # Note, this is NOT a SOCKS proxy, but a plain HTTP proxy
318
319
  config :proxy
319
320
 
321
+ # Enable doc_as_upsert for update mode
322
+ # create a new document with source if document_id doesn't exists
323
+ config :doc_as_upsert, :validate => :boolean, :default => false
324
+
325
+ # Set upsert content for update mode
326
+ # create a new document with this parameter as json string if document_id doesn't exists
327
+ config :upsert, :validate => :string, :default => ""
328
+
320
329
  public
321
330
  def register
322
331
  @submit_mutex = Mutex.new
@@ -389,6 +398,13 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
389
398
 
390
399
  common_options.merge! setup_basic_auth()
391
400
 
401
+ # Update API setup
402
+ update_options = {
403
+ :upsert => @upsert,
404
+ :doc_as_upsert => @doc_as_upsert
405
+ }
406
+ common_options.merge! update_options if @action == 'update'
407
+
392
408
  client_class = case @protocol
393
409
  when "transport"
394
410
  LogStash::Outputs::Elasticsearch::Protocols::TransportClient
@@ -503,11 +519,16 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
503
519
  event["type"] || "logs"
504
520
  end
505
521
 
506
- index = event.sprintf(@index)
522
+ params = {
523
+ :_id => @document_id ? event.sprintf(@document_id) : nil,
524
+ :_index => event.sprintf(@index),
525
+ :_type => type,
526
+ :_routing => @routing ? event.sprintf(@routing) : nil
527
+ }
528
+
529
+ params[:_upsert] = LogStash::Json.load(event.sprintf(@upsert)) if @action == 'update' && @upsert != ""
507
530
 
508
- document_id = @document_id ? event.sprintf(@document_id) : nil
509
- routing = @routing ? event.sprintf(@routing) : nil
510
- buffer_receive([event.sprintf(@action), { :_id => document_id, :_index => index, :_type => type, :_routing => routing }, event])
531
+ buffer_receive([event.sprintf(@action), params, event])
511
532
  end # def receive
512
533
 
513
534
  public
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-output-elasticsearch'
4
- s.version = '1.0.6'
4
+ s.version = '1.0.7'
5
5
  s.licenses = ['apache-2.0']
6
6
  s.summary = "Logstash Output to Elasticsearch"
7
7
  s.description = "Output events to elasticsearch"
@@ -0,0 +1,87 @@
1
+ require_relative "../../../spec/es_spec_helper"
2
+
3
+ describe "all protocols update actions", :integration => true do
4
+ require "logstash/outputs/elasticsearch"
5
+ require "elasticsearch"
6
+
7
+ def get_es_output( protocol, id = nil, upsert = nil, doc_as_upsert=nil)
8
+ settings = {
9
+ "manage_template" => true,
10
+ "index" => "logstash-update",
11
+ "template_overwrite" => true,
12
+ "protocol" => protocol,
13
+ "host" => get_host(),
14
+ "port" => get_port(protocol),
15
+ "action" => "update"
16
+ }
17
+ settings['upsert'] = upsert unless upsert.nil?
18
+ settings['document_id'] = id unless id.nil?
19
+ settings['doc_as_upsert'] = doc_as_upsert unless doc_as_upsert.nil?
20
+ LogStash::Outputs::ElasticSearch.new(settings)
21
+ end
22
+
23
+ before :each do
24
+ @es = get_client
25
+ # Delete all templates first.
26
+ # Clean ES of data before we start.
27
+ @es.indices.delete_template(:name => "*")
28
+ # This can fail if there are no indexes, ignore failure.
29
+ @es.indices.delete(:index => "*") rescue nil
30
+ @es.index(
31
+ :index => 'logstash-update',
32
+ :type => 'logs',
33
+ :id => "123",
34
+ :body => { :message => 'Test' }
35
+ )
36
+ @es.indices.refresh
37
+ end
38
+
39
+ ["node", "transport", "http"].each do |protocol|
40
+ context "update only with #{protocol} protocol" do
41
+ it "should failed without a document_id" do
42
+ event = LogStash::Event.new("somevalue" => 100, "@timestamp" => "2014-11-17T20:37:17.223Z", "@metadata" => {"retry_count" => 0})
43
+ action = ["update", {:_id=>nil, :_index=>"logstash-2014.11.17", :_type=>"logs"}, event]
44
+ subject = get_es_output(protocol)
45
+ subject.register
46
+ expect { subject.flush([action]) }.to raise_error
47
+ end
48
+
49
+ it "should not create new document" do
50
+ subject = get_es_output(protocol, "456")
51
+ subject.register
52
+ subject.receive(LogStash::Event.new("message" => "sample message here"))
53
+ subject.buffer_flush(:final => true)
54
+ expect {@es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)}.to raise_error(Elasticsearch::Transport::Transport::Errors::NotFound)
55
+ end
56
+
57
+ it "should update existing document" do
58
+ subject = get_es_output(protocol, "123")
59
+ subject.register
60
+ subject.receive(LogStash::Event.new("message" => "updated message here"))
61
+ subject.buffer_flush(:final => true)
62
+ r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "123", :refresh => true)
63
+ insist { r["_source"]["message"] } == 'updated message here'
64
+ end
65
+ end
66
+
67
+ context "upsert with #{protocol} protocol" do
68
+ it "should create new documents with upsert content" do
69
+ subject = get_es_output(protocol, "456", '{"message": "upsert message"}')
70
+ subject.register
71
+ subject.receive(LogStash::Event.new("message" => "sample message here"))
72
+ subject.buffer_flush(:final => true)
73
+ r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
74
+ insist { r["_source"]["message"] } == 'upsert message'
75
+ end
76
+
77
+ it "should create new documents with event/doc as upsert" do
78
+ subject = get_es_output(protocol, "456", nil, true)
79
+ subject.register
80
+ subject.receive(LogStash::Event.new("message" => "sample message here"))
81
+ subject.buffer_flush(:final => true)
82
+ r = @es.get(:index => 'logstash-update', :type => 'logs', :id => "456", :refresh => true)
83
+ insist { r["_source"]["message"] } == 'sample message here'
84
+ end
85
+ end
86
+ end
87
+ end
@@ -6,10 +6,12 @@ describe LogStash::Outputs::Elasticsearch::Protocols::NodeClient do
6
6
  context "successful" do
7
7
  it "should map correctly" do
8
8
  index_response = org.elasticsearch.action.index.IndexResponse.new("my_index", "my_type", "my_id", 123, true)
9
+ update_response = org.elasticsearch.action.update.UpdateResponse.new("my_index", "my_type", "my_id", 123, false)
9
10
  delete_response = org.elasticsearch.action.delete.DeleteResponse.new("my_index", "my_type", "my_id", 123, true)
10
11
  bulk_item_response_index = org.elasticsearch.action.bulk.BulkItemResponse.new(32, "index", index_response)
12
+ bulk_item_response_update = org.elasticsearch.action.bulk.BulkItemResponse.new(32, "update", update_response)
11
13
  bulk_item_response_delete = org.elasticsearch.action.bulk.BulkItemResponse.new(32, "delete", delete_response)
12
- bulk_response = org.elasticsearch.action.bulk.BulkResponse.new([bulk_item_response_index, bulk_item_response_delete], 0)
14
+ bulk_response = org.elasticsearch.action.bulk.BulkResponse.new([bulk_item_response_index, bulk_item_response_update, bulk_item_response_delete], 0)
13
15
  ret = LogStash::Outputs::Elasticsearch::Protocols::NodeClient.normalize_bulk_response(bulk_response)
14
16
  insist { ret } == {"errors" => false}
15
17
  end
@@ -19,10 +21,11 @@ describe LogStash::Outputs::Elasticsearch::Protocols::NodeClient do
19
21
  it "should map correctly" do
20
22
  failure = org.elasticsearch.action.bulk.BulkItemResponse::Failure.new("my_index", "my_type", "my_id", "error message", org.elasticsearch.rest.RestStatus::BAD_REQUEST)
21
23
  bulk_item_response_index = org.elasticsearch.action.bulk.BulkItemResponse.new(32, "index", failure)
24
+ bulk_item_response_update = org.elasticsearch.action.bulk.BulkItemResponse.new(32, "update", failure)
22
25
  bulk_item_response_delete = org.elasticsearch.action.bulk.BulkItemResponse.new(32, "delete", failure)
23
- bulk_response = org.elasticsearch.action.bulk.BulkResponse.new([bulk_item_response_index, bulk_item_response_delete], 0)
26
+ bulk_response = org.elasticsearch.action.bulk.BulkResponse.new([bulk_item_response_index, bulk_item_response_update, bulk_item_response_delete], 0)
24
27
  actual = LogStash::Outputs::Elasticsearch::Protocols::NodeClient.normalize_bulk_response(bulk_response)
25
- insist { actual } == {"errors" => true, "statuses" => [400, 400]}
28
+ insist { actual } == {"errors" => true, "statuses" => [400, 400, 400]}
26
29
  end
27
30
  end
28
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-03 00:00:00.000000000 Z
11
+ date: 2015-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -195,6 +195,7 @@ files:
195
195
  - spec/integration/outputs/secure_spec.rb
196
196
  - spec/integration/outputs/templates_spec.rb
197
197
  - spec/integration/outputs/transport_create_spec.rb
198
+ - spec/integration/outputs/update_spec.rb
198
199
  - spec/unit/outputs/elasticsearch/protocol_spec.rb
199
200
  - spec/unit/outputs/elasticsearch_proxy_spec.rb
200
201
  - spec/unit/outputs/elasticsearch_spec.rb
@@ -251,6 +252,7 @@ test_files:
251
252
  - spec/integration/outputs/secure_spec.rb
252
253
  - spec/integration/outputs/templates_spec.rb
253
254
  - spec/integration/outputs/transport_create_spec.rb
255
+ - spec/integration/outputs/update_spec.rb
254
256
  - spec/unit/outputs/elasticsearch/protocol_spec.rb
255
257
  - spec/unit/outputs/elasticsearch_proxy_spec.rb
256
258
  - spec/unit/outputs/elasticsearch_spec.rb