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

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