logstash-output-elasticsearch 7.0.0-java → 7.1.0-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: 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