logstash-output-elasticsearch 6.0.0-java → 6.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: 9c739e5dde0b8370dcc47e86b0dc2f92efb6bc6e
4
- data.tar.gz: efe8aebc49fb32623f0c8ed65f6427325357da1d
3
+ metadata.gz: f8df743661ac7aed2fb52dddaf677ce1705a0612
4
+ data.tar.gz: 10bcb6b88076eafe00aea65c6d9e01d4d3fd8648
5
5
  SHA512:
6
- metadata.gz: 3cdc83c314948cdc3ddf5323755a4e4ff44ffc9df004ca5deaa66fa34e1f6c86532cb368c426f68d27f910963563e0dcceef6baa625985e60259e5a681180f25
7
- data.tar.gz: dc6950d258a89c4b5dbc96150527de923606b1011e248f6ce145c703fc817614329cc964f21375a1f6ad69a46e35c463366209d58350d7257006065d29d7239b
6
+ metadata.gz: 605c1958b1b4d22e51132e71932174c86c3d1696b80a7f35e07ec147301072dec9befeb64fae5bd240cff7c38f791fa3ede8bfa8a4781cd705a956d4a6e5b6b4
7
+ data.tar.gz: 69fae6a096cfa00b41037800d7a09737d0fec46b9722796f746d2aa1074be49147b3d2e8f2ec9ca39fdabf35130a2d603f8f512f771bceb09b1afdc1ffa6d0e8
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 6.1.0
2
+ - Add option to use an absolute healthcheck path
3
+
1
4
  ## 6.0.0
2
5
  - Proxies requiring auth now always work when a URL is specified
3
6
  - It is no longer possible to specify a proxy as a hash due to security reasons
@@ -176,7 +176,11 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
176
176
  # to service requests. If you have custom firewall rules you may need to change
177
177
  # this
178
178
  config :healthcheck_path, :validate => :string, :default => "/"
179
-
179
+ # When a `healthcheck_path` config is provided, this additional flag can be used to
180
+ # specify whether it is an absolute URI or a relative path.
181
+ # If this flag is true, `healthcheck_path` is expected to be a fully formed URL
182
+ # with any basic auth credentials provided in the URL itself.
183
+ config :absolute_healthcheck_path, :validate => :boolean, :default => false
180
184
  # How frequently, in seconds, to wait between resurrection attempts.
181
185
  # Resurrection is the process by which backend endpoints marked 'down' are checked
182
186
  # to see if they have come back to life
@@ -250,6 +250,7 @@ module LogStash; module Outputs; class ElasticSearch;
250
250
  :sniffing => sniffing,
251
251
  :sniffer_delay => options[:sniffer_delay],
252
252
  :healthcheck_path => options[:healthcheck_path],
253
+ :absolute_healthcheck_path => options[:absolute_healthcheck_path],
253
254
  :resurrect_delay => options[:resurrect_delay],
254
255
  :url_normalizer => self.method(:host_to_url)
255
256
  }
@@ -46,26 +46,13 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
46
46
  def perform_request(url, method, path, params={}, body=nil)
47
47
  params = (params || {}).merge @request_options
48
48
  params[:body] = body if body
49
-
50
- request_uri = if path
51
- # Combine the paths using the minimal # of /s
52
- # First, we make sure the path is relative so URI.join does
53
- # the right thing
54
- relative_path = path && path.start_with?("/") ? path[1..-1] : path
55
- # Wrap this with a safe URI defensively against careless handling later
56
- ::LogStash::Util::SafeURI.new(URI.join(url.uri, relative_path))
57
- else
58
- ::LogStash::Util::SafeURI.new(url.uri.clone)
59
- end
60
-
61
- # We excise auth info from the URL in case manticore itself tries to stick
62
- # sensitive data in a thrown exception or log data
63
- if request_uri.user
64
- params[:auth] = { :user => request_uri.user, :password => request_uri.password, :eager => true }
65
- request_uri.user = nil
66
- request_uri.password = nil
49
+
50
+ if url.user
51
+ params[:auth] = { :user => url.user, :password => url.password, :eager => true }
67
52
  end
68
53
 
54
+ request_uri = format_url(url, path)
55
+
69
56
  resp = @manticore.send(method.downcase, request_uri.to_s, params)
70
57
 
71
58
  # Manticore returns lazy responses by default
@@ -83,6 +70,33 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
83
70
  resp
84
71
  end
85
72
 
73
+ def format_url(url, path)
74
+
75
+ request_uri = url.uri
76
+
77
+ if path
78
+ # Combine the paths using the minimal # of /s
79
+ # First, we make sure the path is relative so URI.join does
80
+ # the right thing
81
+ relative_path = path && path.start_with?("/") ? path[1..-1] : path
82
+ # because URI.join obliterates the query parameter, we need to save it
83
+ # and restore it after this operation
84
+ query = request_uri.query
85
+ request_uri = URI.join(request_uri, relative_path)
86
+ request_uri.query = query
87
+ else
88
+ request_uri = request_uri.clone
89
+ end
90
+
91
+ # We excise auth info from the URL in case manticore itself tries to stick
92
+ # sensitive data in a thrown exception or log data
93
+ request_uri.user = nil
94
+ request_uri.password = nil
95
+
96
+ # Wrap this with a safe URI defensively against careless handling later
97
+ ::LogStash::Util::SafeURI.new(request_uri)
98
+ end
99
+
86
100
  def close
87
101
  @manticore.close
88
102
  end
@@ -27,10 +27,13 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
27
27
  end
28
28
  end
29
29
 
30
- attr_reader :logger, :adapter, :sniffing, :sniffer_delay, :resurrect_delay, :healthcheck_path
30
+ attr_reader :logger, :adapter, :sniffing, :sniffer_delay, :resurrect_delay, :healthcheck_path, :absolute_healthcheck_path
31
+
32
+ ROOT_URI_PATH = '/'.freeze
31
33
 
32
34
  DEFAULT_OPTIONS = {
33
- :healthcheck_path => '/'.freeze,
35
+ :healthcheck_path => ROOT_URI_PATH,
36
+ :absolute_healthcheck_path => false,
34
37
  :scheme => 'http',
35
38
  :resurrect_delay => 5,
36
39
  :sniffing => false,
@@ -46,6 +49,7 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
46
49
  @url_normalizer = options[:url_normalizer]
47
50
  DEFAULT_OPTIONS.merge(options).tap do |merged|
48
51
  @healthcheck_path = merged[:healthcheck_path]
52
+ @absolute_healthcheck_path = merged[:absolute_healthcheck_path]
49
53
  @resurrect_delay = merged[:resurrect_delay]
50
54
  @sniffing = merged[:sniffing]
51
55
  @sniffer_delay = merged[:sniffer_delay]
@@ -225,11 +229,17 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
225
229
  # Try to keep locking granularity low such that we don't affect IO...
226
230
  @state_mutex.synchronize { @url_info.select {|url,meta| meta[:state] != :alive } }.each do |url,meta|
227
231
  begin
232
+ path = healthcheck_path
233
+ healthcheck_url = url
234
+ if @absolute_healthcheck_path
235
+ healthcheck_url = ::LogStash::Util::SafeURI.new(healthcheck_path)
236
+ path = ROOT_URI_PATH
237
+ end
228
238
  logger.info("Running health check to see if an Elasticsearch connection is working",
229
- url: url, healthcheck_path: healthcheck_path)
230
- response = perform_request_to_url(url, :head, healthcheck_path)
239
+ :healthcheck_url => healthcheck_url, :path => path)
240
+ response = perform_request_to_url(healthcheck_url, :head, path)
231
241
  # If no exception was raised it must have succeeded!
232
- logger.warn("Restored connection to ES instance", :url => url.sanitized)
242
+ logger.warn("Restored connection to ES instance", :url => healthcheck_url.sanitized)
233
243
  @state_mutex.synchronize { meta[:state] = :alive }
234
244
  rescue HostUnreachableError, BadResponseCodeError => e
235
245
  logger.warn("Attempted to resurrect connection to dead ES instance, but got an error.", url: url.sanitized, error_type: e.class, error: e.message)
@@ -12,7 +12,8 @@ module LogStash; module Outputs; class ElasticSearch;
12
12
  common_options = {
13
13
  :client_settings => client_settings,
14
14
  :resurrect_delay => params["resurrect_delay"],
15
- :healthcheck_path => params["healthcheck_path"]
15
+ :healthcheck_path => params["healthcheck_path"],
16
+ :absolute_healthcheck_path => params["absolute_healthcheck_path"]
16
17
  }
17
18
 
18
19
  if params["sniffing"]
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-output-elasticsearch'
4
- s.version = '6.0.0'
4
+ s.version = '6.1.0'
5
5
  s.licenses = ['apache-2.0']
6
6
  s.summary = "Logstash Output to Elasticsearch"
7
7
  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"
@@ -39,6 +39,34 @@ describe LogStash::Outputs::ElasticSearch::HttpClient::ManticoreAdapter do
39
39
  end
40
40
  end
41
41
 
42
+ describe "format_url" do
43
+ let(:url) { ::LogStash::Util::SafeURI.new("http://localhost:9200/path/") }
44
+ let(:path) { "_bulk" }
45
+ subject { described_class.new(double("logger"), {}) }
46
+
47
+ it "should add the path argument to the uri's path" do
48
+ expect(subject.format_url(url, path).path).to eq("/path/_bulk")
49
+ end
50
+
51
+ context "when uri contains query parameters" do
52
+ let(:query_params) { "query=value&key=value2" }
53
+ let(:url) { ::LogStash::Util::SafeURI.new("http://localhost:9200/path/?#{query_params}") }
54
+
55
+ it "should retain query_params after format" do
56
+ expect(subject.format_url(url, path).query).to eq(query_params)
57
+ end
58
+ end
59
+
60
+ context "when uri contains credentials" do
61
+ let(:url) { ::LogStash::Util::SafeURI.new("http://user:pass@localhost:9200") }
62
+
63
+ it "should remove credentials after format" do
64
+ expect(subject.format_url(url, path).user).to be_nil
65
+ expect(subject.format_url(url, path).password).to be_nil
66
+ end
67
+ end
68
+ end
69
+
42
70
  describe "integration specs", :integration => true do
43
71
  it "should perform correct tests without error" do
44
72
  resp = subject.perform_request(::LogStash::Util::SafeURI.new("http://localhost:9200"), :get, "/")
@@ -9,26 +9,25 @@ describe LogStash::Outputs::ElasticSearch::HttpClient::Pool do
9
9
  let(:options) { {:resurrect_delay => 2, :url_normalizer => proc {|u| u}} } # Shorten the delay a bit to speed up tests
10
10
 
11
11
  subject { described_class.new(logger, adapter, initial_urls, options) }
12
-
12
+
13
13
  let(:manticore_double) { double("manticore a") }
14
14
  before do
15
- allow(adapter).to receive(:perform_request).with(anything, :head, subject.healthcheck_path, {}, nil)
16
-
17
-
15
+
18
16
  response_double = double("manticore response").as_null_object
19
17
  # Allow healtchecks
20
18
  allow(manticore_double).to receive(:head).with(any_args).and_return(response_double)
21
19
  allow(manticore_double).to receive(:get).with(any_args).and_return(response_double)
22
-
20
+ allow(manticore_double).to receive(:close)
21
+
23
22
  allow(::Manticore::Client).to receive(:new).and_return(manticore_double)
24
23
 
25
24
  subject.start
26
25
  end
27
-
26
+
28
27
  after do
29
28
  subject.close
30
29
  end
31
-
30
+
32
31
  describe "initialization" do
33
32
  it "should be successful" do
34
33
  expect { subject }.not_to raise_error
@@ -44,6 +43,26 @@ describe LogStash::Outputs::ElasticSearch::HttpClient::Pool do
44
43
  expect(subject).to receive(:healthcheck!).once
45
44
  sleep(subject.resurrect_delay + 1)
46
45
  end
46
+
47
+ describe "absolute_healthcheck_path" do
48
+ let(:options) { super.merge(:absolute_healthcheck_path => true, :healthcheck_path => "http://abc:xyz@localhost:9200")}
49
+ let(:pool) { described_class.new(logger, adapter, initial_urls, options) }
50
+
51
+ before do
52
+ pool.start
53
+ end
54
+
55
+ after do
56
+ pool.close
57
+ end
58
+
59
+ context "when enabled" do
60
+ it "should use the healthcheck_path as URL to do a health check" do
61
+ expect(adapter).to receive(:perform_request).with(::LogStash::Util::SafeURI.new(subject.healthcheck_path), :head, "/", {}, nil)
62
+ pool.healthcheck!
63
+ end
64
+ end
65
+ end
47
66
  end
48
67
 
49
68
  describe "the sniffer" do
@@ -88,7 +107,7 @@ describe LogStash::Outputs::ElasticSearch::HttpClient::Pool do
88
107
  expect(subject).to have_received(:in_use_connections).twice
89
108
  end
90
109
  end
91
-
110
+
92
111
  describe "connection management" do
93
112
  context "with only one URL in the list" do
94
113
  it "should use the only URL in 'with_connection'" do
@@ -99,8 +118,11 @@ describe LogStash::Outputs::ElasticSearch::HttpClient::Pool do
99
118
  end
100
119
 
101
120
  context "with multiple URLs in the list" do
121
+ before :each do
122
+ allow(adapter).to receive(:perform_request).with(anything, :head, subject.healthcheck_path, {}, nil)
123
+ end
102
124
  let(:initial_urls) { [ ::LogStash::Util::SafeURI.new("http://localhost:9200"), ::LogStash::Util::SafeURI.new("http://localhost:9201"), ::LogStash::Util::SafeURI.new("http://localhost:9202") ] }
103
-
125
+
104
126
  it "should minimize the number of connections to a single URL" do
105
127
  connected_urls = []
106
128
 
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: 6.0.0
4
+ version: 6.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: 2016-12-20 00:00:00.000000000 Z
11
+ date: 2016-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement