logstash-output-elasticsearch 7.0.0-java → 7.1.0-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: 76021c7104485b80a897db193e8bcb698bcb3e88
4
- data.tar.gz: f4f3bcec4e2f448a1f424b53c03c6c96ca46f5dc
3
+ metadata.gz: fd81205081e6b05250ed7f01c930149b6947b7d8
4
+ data.tar.gz: 66d17e9dae1b92b2053ce814bc3e0e17285afcf0
5
5
  SHA512:
6
- metadata.gz: d1e75e1711a6e2f376d1e69e2bceeb029a617e96195841dd1673a4bf4d151223336816a967fde9a9be6d71edacd2f727f60f0f50162ce48dba17b2fbdf01f770
7
- data.tar.gz: 53ace3cb794f69182d6eae22c3041879a587b682a5fb9939c76d4a64f5e5e042928943edcd08966496250903dc1f78f997bddb0f8a80bb676e7d97c7c7f76387
6
+ metadata.gz: f6263b223df958da29405a47756848072f1fa83cfb50e7e334246e95362e43765e1cce246ab84fc29513b0f78b65f950f41f42205e266d7602b207dab3a10478
7
+ data.tar.gz: 34956e72d80592e44341f24210d894c9f9ffc2ef007367bd5bfee009b1cb3b17b2b826d3ce168c6088c01896409d3a6d733114b7a359faa0dfd6cc6059ddb5f6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 7.1.0
2
+ - Add support to compress requests using the new `http_compression` option.
3
+
1
4
  ## 7.0.0
2
5
  - introduce customization of bulk, healthcheck and sniffing paths with the behaviour:
3
6
  - if not set: the default value will be used
@@ -62,6 +62,17 @@ require "forwardable"
62
62
  #
63
63
  # Keep in mind that a connection with keepalive enabled will
64
64
  # not reevaluate its DNS value while the keepalive is in effect.
65
+ #
66
+ # ==== HTTP Compression
67
+ #
68
+ # This plugin supports request and response compression. Response compression is enabled by default and
69
+ # for Elasticsearch versions 5.0 and later, the user doesn't have to set any configs in Elasticsearch for
70
+ # it to send back compressed response. For versions before 5.0, `http.compression` must be set to `true` in
71
+ # Elasticsearch[https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-http.html#modules-http] to take advantage of response compression when using this plugin
72
+ #
73
+ # For requests compression, regardless of the Elasticsearch version, users have to enable `http_compression`
74
+ # setting in their Logstash config file.
75
+ #
65
76
  class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
66
77
  declare_threadsafe!
67
78
 
@@ -202,6 +213,9 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
202
213
  # See https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.html#setValidateAfterInactivity(int)[these docs for more info]
203
214
  config :validate_after_inactivity, :validate => :number, :default => 10000
204
215
 
216
+ # Enable gzip compression on requests. Note that response compression is on by default for Elasticsearch v5.0 and beyond
217
+ config :http_compression, :validate => :boolean, :default => false
218
+
205
219
  def build_client
206
220
  @client ||= ::LogStash::Outputs::ElasticSearch::HttpClientBuilder.build(@logger, @hosts, params)
207
221
  end
@@ -82,8 +82,7 @@ module LogStash; module Outputs; class ElasticSearch;
82
82
  begin
83
83
  submit_actions = submit(submit_actions)
84
84
  if submit_actions && submit_actions.size > 0
85
- @logger.error("Retrying individual actions")
86
- submit_actions.each {|action| @logger.error("Action", action) }
85
+ @logger.info("Retrying individual bulk actions that failed or were rejected by the previous bulk request.", :count => submit_actions.size)
87
86
  end
88
87
  rescue => e
89
88
  @logger.error("Encountered an unexpected error submitting a bulk request! Will retry.",
@@ -4,6 +4,8 @@ require "base64"
4
4
  require 'logstash/outputs/elasticsearch/http_client/pool'
5
5
  require 'logstash/outputs/elasticsearch/http_client/manticore_adapter'
6
6
  require 'cgi'
7
+ require 'zlib'
8
+ require 'stringio'
7
9
 
8
10
  module LogStash; module Outputs; class ElasticSearch;
9
11
  # This is a constant instead of a config option because
@@ -101,24 +103,25 @@ module LogStash; module Outputs; class ElasticSearch;
101
103
  end
102
104
  end
103
105
 
104
- bulk_body = ""
106
+ body_stream = StringIO.new
107
+ if http_compression
108
+ body_stream.set_encoding "BINARY"
109
+ stream_writer = Zlib::GzipWriter.new(body_stream, Zlib::DEFAULT_COMPRESSION, Zlib::DEFAULT_STRATEGY)
110
+ else
111
+ stream_writer = body_stream
112
+ end
105
113
  bulk_responses = []
106
114
  bulk_actions.each do |action|
107
115
  as_json = action.is_a?(Array) ?
108
116
  action.map {|line| LogStash::Json.dump(line)}.join("\n") :
109
117
  LogStash::Json.dump(action)
110
118
  as_json << "\n"
111
-
112
- if (bulk_body.bytesize + as_json.bytesize) > TARGET_BULK_BYTES
113
- bulk_responses << bulk_send(bulk_body)
114
- bulk_body = as_json
115
- else
116
- bulk_body << as_json
117
- end
119
+ bulk_responses << bulk_send(body_stream) if (body_stream.size + as_json.bytesize) > TARGET_BULK_BYTES
120
+ stream_writer.write(as_json)
118
121
  end
119
-
120
- bulk_responses << bulk_send(bulk_body) if bulk_body.size > 0
121
-
122
+ stream_writer.close if http_compression
123
+ bulk_responses << bulk_send(body_stream) if body_stream.size > 0
124
+ body_stream.close if !http_compression
122
125
  join_bulk_responses(bulk_responses)
123
126
  end
124
127
 
@@ -129,8 +132,14 @@ module LogStash; module Outputs; class ElasticSearch;
129
132
  }
130
133
  end
131
134
 
132
- def bulk_send(bulk_body)
133
- _, response = @pool.post(@bulk_path, nil, bulk_body)
135
+ def bulk_send(body_stream)
136
+ params = http_compression ? {:headers => {"Content-Encoding" => "gzip"}} : {}
137
+ # Discard the URL
138
+ _, response = @pool.post(@bulk_path, params, body_stream.string)
139
+ if !body_stream.closed?
140
+ body_stream.truncate(0)
141
+ body_stream.seek(0)
142
+ end
134
143
  LogStash::Json.load(response.body)
135
144
  end
136
145
 
@@ -214,6 +223,10 @@ module LogStash; module Outputs; class ElasticSearch;
214
223
  client_settings.fetch(:ssl, {})
215
224
  end
216
225
 
226
+ def http_compression
227
+ client_settings.fetch(:http_compression, {})
228
+ end
229
+
217
230
  def build_adapter(options)
218
231
  timeout = options[:timeout] || 0
219
232
 
@@ -47,7 +47,11 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
47
47
  # @see Transport::Base#perform_request
48
48
  #
49
49
  def perform_request(url, method, path, params={}, body=nil)
50
- params = (params || {}).merge(@client_params)
50
+ # Perform 2-level deep merge on the params, so if the passed params and client params will both have hashes stored on a key they
51
+ # will be merged as well, instead of choosing just one of the values
52
+ params = (params || {}).merge(@client_params) { |key, oldval, newval|
53
+ (oldval.is_a?(Hash) && newval.is_a?(Hash)) ? oldval.merge(newval) : newval
54
+ }
51
55
  params[:body] = body if body
52
56
 
53
57
  if url.user
@@ -6,7 +6,8 @@ module LogStash; module Outputs; class ElasticSearch;
6
6
  client_settings = {
7
7
  :pool_max => params["pool_max"],
8
8
  :pool_max_per_route => params["pool_max_per_route"],
9
- :check_connection_timeout => params["validate_after_inactivity"]
9
+ :check_connection_timeout => params["validate_after_inactivity"],
10
+ :http_compression => params["http_compression"]
10
11
  }
11
12
 
12
13
  client_settings[:proxy] = params["proxy"] if params["proxy"]
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-elasticsearch'
3
- s.version = '7.0.0'
3
+ s.version = '7.1.0'
4
4
  s.licenses = ['apache-2.0']
5
5
  s.summary = "Logstash Output to Elasticsearch"
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/logstash-plugin install gemname. This gem is not a stand-alone program"
@@ -25,6 +25,7 @@ Gem::Specification.new do |s|
25
25
  s.add_development_dependency 'addressable', "~> 2.3.0" # used by FTW. V 2.5.0 is ruby 2.0 only.
26
26
  s.add_development_dependency 'logstash-codec-plain'
27
27
  s.add_development_dependency 'json' # used by spec/unit/outputs/elasticsearch/http_client/pool_spec.rb
28
+ s.add_development_dependency 'gzip' # used by spec/integration/outputs/index_spec.rb
28
29
 
29
30
  if RUBY_PLATFORM == 'java'
30
31
  s.platform = RUBY_PLATFORM
@@ -0,0 +1,66 @@
1
+ require_relative "../../../spec/es_spec_helper"
2
+ require "logstash/outputs/elasticsearch"
3
+ require "stringio"
4
+ require "gzip"
5
+
6
+ RSpec::Matchers.define :a_valid_gzip_encoded_string do
7
+ match { |data|
8
+ expect { Zlib::GzipReader.new(StringIO.new(data)).read }.not_to raise_error
9
+ }
10
+ end
11
+
12
+ describe "indexing with http_compression turned on", :integration => true, :version_greater_than_equal_to_5x => true do
13
+ let(:event) { LogStash::Event.new("message" => "Hello World!", "type" => type) }
14
+ let(:index) { 10.times.collect { rand(10).to_s }.join("") }
15
+ let(:type) { 10.times.collect { rand(10).to_s }.join("") }
16
+ let(:event_count) { 10000 + rand(500) }
17
+ let(:events) { event_count.times.map { event }.to_a }
18
+ let(:config) {
19
+ {
20
+ "hosts" => get_host_port,
21
+ "index" => index,
22
+ "http_compression" => true
23
+ }
24
+ }
25
+ subject { LogStash::Outputs::ElasticSearch.new(config) }
26
+
27
+ let(:es_url) { "http://#{get_host_port}" }
28
+ let(:index_url) {"#{es_url}/#{index}"}
29
+ let(:http_client_options) { {} }
30
+ let(:http_client) do
31
+ Manticore::Client.new(http_client_options)
32
+ end
33
+
34
+ before do
35
+ subject.register
36
+ end
37
+
38
+ shared_examples "an indexer" do
39
+ it "ships events" do
40
+ subject.multi_receive(events)
41
+
42
+ http_client.post("#{es_url}/_refresh").call
43
+
44
+ response = http_client.get("#{index_url}/_count?q=*")
45
+ result = LogStash::Json.load(response.body)
46
+ cur_count = result["count"]
47
+ expect(cur_count).to eq(event_count)
48
+
49
+ response = http_client.get("#{index_url}/_search?q=*&size=1000")
50
+ result = LogStash::Json.load(response.body)
51
+ result["hits"]["hits"].each do |doc|
52
+ expect(doc["_type"]).to eq(type)
53
+ expect(doc["_index"]).to eq(index)
54
+ end
55
+ end
56
+ end
57
+
58
+ it "sets the correct content-encoding header and body is compressed" do
59
+ expect(subject.client.pool.adapter.client).to receive(:send).
60
+ with(anything, anything, {:headers=>{"Content-Encoding"=>"gzip", "Content-Type"=>"application/json"}, :body => a_valid_gzip_encoded_string}).
61
+ and_call_original
62
+ subject.multi_receive(events)
63
+ end
64
+
65
+ it_behaves_like("an indexer")
66
+ 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: 7.0.0
4
+ version: 7.1.0
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-21 00:00:00.000000000 Z
11
+ date: 2017-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -120,6 +120,20 @@ dependencies:
120
120
  - - ">="
121
121
  - !ruby/object:Gem::Version
122
122
  version: '0'
123
+ - !ruby/object:Gem::Dependency
124
+ requirement: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ name: gzip
130
+ prerelease: false
131
+ type: :development
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
123
137
  - !ruby/object:Gem::Dependency
124
138
  requirement: !ruby/object:Gem::Requirement
125
139
  requirements:
@@ -211,6 +225,7 @@ files:
211
225
  - spec/fixtures/scripts/scripted_update.groovy
212
226
  - spec/fixtures/scripts/scripted_update_nested.groovy
213
227
  - spec/fixtures/scripts/scripted_upsert.groovy
228
+ - spec/integration/outputs/compressed_indexing_spec.rb
214
229
  - spec/integration/outputs/create_spec.rb
215
230
  - spec/integration/outputs/delete_spec.rb
216
231
  - spec/integration/outputs/index_spec.rb
@@ -265,6 +280,7 @@ test_files:
265
280
  - spec/fixtures/scripts/scripted_update.groovy
266
281
  - spec/fixtures/scripts/scripted_update_nested.groovy
267
282
  - spec/fixtures/scripts/scripted_upsert.groovy
283
+ - spec/integration/outputs/compressed_indexing_spec.rb
268
284
  - spec/integration/outputs/create_spec.rb
269
285
  - spec/integration/outputs/delete_spec.rb
270
286
  - spec/integration/outputs/index_spec.rb