logstash-output-elasticsearch 2.4.2-java → 2.5.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 +4 -4
- data/CHANGELOG.md +4 -0
- data/lib/logstash/outputs/elasticsearch.rb +5 -3
- data/lib/logstash/outputs/elasticsearch/common_configs.rb +3 -0
- data/lib/logstash/outputs/elasticsearch/http_client.rb +57 -10
- data/logstash-output-elasticsearch.gemspec +1 -1
- data/spec/unit/outputs/elasticsearch/http_client_spec.rb +129 -0
- metadata +4 -4
- data/spec/unit/outputs/elasticsearch/protocol_spec.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 94080174a41d46422a7f94b0e9354554d3e0d66a
|
4
|
+
data.tar.gz: bddb86d2a5bbbae75734c41610588c3cf5c04f71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d59bc4d44c2b1918519e286efb995805abd63dd8d411ae87b82551750182b743ee56ed453d557e12769c21a3535496aa02d79ff77580ba9508499914edc61e2
|
7
|
+
data.tar.gz: fdba23ed47b9414ca87d2d7bd75a3c07c440fce5d86c49adcdb4be1a95884266e908f0b73ef55a1c895947714cd2fc19ec6bf0c8887274b9dc9ffab5c51190cc
|
data/CHANGELOG.md
CHANGED
@@ -16,7 +16,7 @@ require "uri" # for escaping user input
|
|
16
16
|
# We strongly encourage the use of HTTP over the node protocol for a number of reasons. HTTP is only marginally slower,
|
17
17
|
# yet far easier to administer and work with. When using the HTTP protocol one may upgrade Elasticsearch versions without having
|
18
18
|
# to upgrade Logstash in lock-step. For those still wishing to use the node or transport protocols please see
|
19
|
-
# the
|
19
|
+
# the <<plugins-outputs-elasticsearch_java,elasticsearch_java output plugin>>.
|
20
20
|
#
|
21
21
|
# You can learn more about Elasticsearch at <https://www.elastic.co/products/elasticsearch>
|
22
22
|
#
|
@@ -81,8 +81,10 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
|
|
81
81
|
# the root path for the Elasticsearch HTTP API lives.
|
82
82
|
config :path, :validate => :string, :default => "/"
|
83
83
|
|
84
|
-
# Enable SSL/TLS secured communication to Elasticsearch cluster
|
85
|
-
|
84
|
+
# Enable SSL/TLS secured communication to Elasticsearch cluster. Leaving this unspecified will use whatever scheme
|
85
|
+
# is specified in the URLs listed in 'hosts'. If no explicit protocol is specified plain HTTP will be used.
|
86
|
+
# If SSL is explicitly disabled here the plugin will refuse to start if an HTTPS URL is given in 'hosts'
|
87
|
+
config :ssl, :validate => :boolean
|
86
88
|
|
87
89
|
# Option to validate the server's certificate. Disabling this severely compromises security.
|
88
90
|
# For more information on disabling certificate verification please read
|
@@ -74,6 +74,9 @@ module LogStash; module Outputs; class ElasticSearch
|
|
74
74
|
# Remember the `http` protocol uses the http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-http.html#modules-http[http] address (eg. 9200, not 9300).
|
75
75
|
# `"127.0.0.1"`
|
76
76
|
# `["127.0.0.1:9200","127.0.0.2:9200"]`
|
77
|
+
# `["http://127.0.0.1"]`
|
78
|
+
# `["https://127.0.0.1:9200"]`
|
79
|
+
# `["https://127.0.0.1:9200/mypath"]` (If using a proxy on a subpath)
|
77
80
|
# It is important to exclude http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html[dedicated master nodes] from the `hosts` list
|
78
81
|
# to prevent LS from sending bulk requests to the master nodes. So this parameter should only reference either data or client nodes in Elasticsearch.
|
79
82
|
mod.config :hosts, :validate => :array, :default => ["127.0.0.1"]
|
@@ -105,18 +105,10 @@ module LogStash; module Outputs; class ElasticSearch;
|
|
105
105
|
client_settings = options[:client_settings] || {}
|
106
106
|
timeout = options[:timeout] || 0
|
107
107
|
|
108
|
-
|
109
|
-
proto = client_settings[:ssl] ? "https" : "http"
|
110
|
-
if host =~ /:\d+\z/
|
111
|
-
"#{proto}://#{host}#{client_settings[:path]}"
|
112
|
-
else
|
113
|
-
# Use default port of 9200 if none provided with host.
|
114
|
-
"#{proto}://#{host}:9200#{client_settings[:path]}"
|
115
|
-
end
|
116
|
-
end
|
108
|
+
urls = hosts.map {|host| host_to_url(host, client_settings[:ssl], client_settings[:path])}
|
117
109
|
|
118
110
|
@client_options = {
|
119
|
-
:hosts =>
|
111
|
+
:hosts => urls,
|
120
112
|
:ssl => client_settings[:ssl],
|
121
113
|
:transport_options => {
|
122
114
|
:socket_timeout => timeout,
|
@@ -136,6 +128,61 @@ module LogStash; module Outputs; class ElasticSearch;
|
|
136
128
|
Elasticsearch::Client.new(client_options)
|
137
129
|
end
|
138
130
|
|
131
|
+
HOSTNAME_PORT_REGEX=/\A(?<hostname>([A-Za-z0-9\.\-]+)|\[[0-9A-Fa-f\:]+\])(:(?<port>\d+))?\Z/
|
132
|
+
URL_REGEX=/\A#{URI::regexp(['http', 'https'])}\z/
|
133
|
+
# Parse a configuration host to a normalized URL
|
134
|
+
def host_to_url(host, ssl=nil, path=nil)
|
135
|
+
explicit_scheme = case ssl
|
136
|
+
when true
|
137
|
+
"https"
|
138
|
+
when false
|
139
|
+
"http"
|
140
|
+
else
|
141
|
+
nil
|
142
|
+
end
|
143
|
+
|
144
|
+
# Ensure path starts with a /
|
145
|
+
if path && path[0] != '/'
|
146
|
+
path = "/#{path}"
|
147
|
+
end
|
148
|
+
|
149
|
+
url = nil
|
150
|
+
if host =~ URL_REGEX
|
151
|
+
url = URI.parse(host)
|
152
|
+
|
153
|
+
# Please note that the ssl == nil case is different! If you didn't make an explicit
|
154
|
+
# choice we don't complain!
|
155
|
+
if url.scheme == "http" && ssl == true
|
156
|
+
raise LogStash::ConfigurationError, "You specified a plain 'http' URL '#{host}' but set 'ssl' to true! Aborting!"
|
157
|
+
elsif url.scheme == "https" && ssl == false
|
158
|
+
raise LogStash::ConfigurationError, "You have explicitly disabled SSL but passed in an https URL '#{host}'! Aborting!"
|
159
|
+
end
|
160
|
+
|
161
|
+
url.scheme = explicit_scheme if explicit_scheme
|
162
|
+
elsif (match_results = HOSTNAME_PORT_REGEX.match(host))
|
163
|
+
hostname = match_results["hostname"]
|
164
|
+
port = match_results["port"] || 9200
|
165
|
+
url = URI.parse("#{explicit_scheme || 'http'}://#{hostname}:#{port}")
|
166
|
+
else
|
167
|
+
raise LogStash::ConfigurationError, "Host '#{host}' was specified, but is not valid! Use either a full URL or a hostname:port string!"
|
168
|
+
end
|
169
|
+
|
170
|
+
if path && url.path && url.path != "/" && url.path != ''
|
171
|
+
raise LogStash::ConfigurationError, "A path '#{url.path}' has been explicitly specified in the url '#{url}', but you also specified a path of '#{path}'. This is probably a mistake, please remove one setting."
|
172
|
+
end
|
173
|
+
|
174
|
+
if path
|
175
|
+
url.path = path # The URI library cannot stringify if it holds a nil
|
176
|
+
end
|
177
|
+
|
178
|
+
if url.password || url.user
|
179
|
+
raise LogStash::ConfigurationError, "We do not support setting the user password in the URL directly as " +
|
180
|
+
"this may be logged to disk thus leaking credentials. Use the 'user' and 'password' options respectively"
|
181
|
+
end
|
182
|
+
|
183
|
+
url.to_s
|
184
|
+
end
|
185
|
+
|
139
186
|
def template_exists?(name)
|
140
187
|
@client.indices.get_template(:name => name)
|
141
188
|
return true
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require "logstash/devutils/rspec/spec_helper"
|
2
|
+
require "logstash/outputs/elasticsearch/http_client"
|
3
|
+
require "java"
|
4
|
+
|
5
|
+
describe LogStash::Outputs::ElasticSearch::HttpClient do
|
6
|
+
let(:base_options) { {:hosts => ["127.0.0.1"], :logger => Cabin::Channel.get }}
|
7
|
+
|
8
|
+
describe "Host/URL Parsing" do
|
9
|
+
subject { described_class.new(base_options) }
|
10
|
+
|
11
|
+
let(:true_hostname) { "my-dash.hostname" }
|
12
|
+
let(:ipv6_hostname) { "[::1]" }
|
13
|
+
let(:ipv4_hostname) { "127.0.0.1" }
|
14
|
+
let(:port) { 9202 }
|
15
|
+
let(:hostname_port) { "#{hostname}:#{port}"}
|
16
|
+
let(:http_hostname_port) { "http://#{hostname_port}"}
|
17
|
+
let(:https_hostname_port) { "https://#{hostname_port}"}
|
18
|
+
let(:http_hostname_port_path) { "http://#{hostname_port}/path"}
|
19
|
+
|
20
|
+
shared_examples("proper host handling") do
|
21
|
+
it "should properly transform a host:port string to a URL" do
|
22
|
+
expect(subject.send(:host_to_url, hostname_port)).to eql(http_hostname_port)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should raise an error when a partial URL is an invalid format" do
|
26
|
+
expect {
|
27
|
+
subject.send(:host_to_url, "#{hostname_port}/")
|
28
|
+
}.to raise_error(LogStash::ConfigurationError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should not raise an error with a / for a path" do
|
32
|
+
expect(subject.send(:host_to_url, "#{http_hostname_port}/")).to eql("#{http_hostname_port}/")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should parse full URLs correctly" do
|
36
|
+
expect(subject.send(:host_to_url, http_hostname_port)).to eql(http_hostname_port)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should reject full URLs with usernames and passwords" do
|
40
|
+
expect {
|
41
|
+
subject.send(:host_to_url, "http://user:password@host.domain")
|
42
|
+
}.to raise_error(LogStash::ConfigurationError)
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "ssl" do
|
46
|
+
it "should refuse to handle an http url when ssl is true" do
|
47
|
+
expect {
|
48
|
+
subject.send(:host_to_url, http_hostname_port, true)
|
49
|
+
}.to raise_error(LogStash::ConfigurationError)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should refuse to handle an https url when ssl is false" do
|
53
|
+
expect {
|
54
|
+
subject.send(:host_to_url, https_hostname_port, false)
|
55
|
+
}.to raise_error(LogStash::ConfigurationError)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should handle an ssl url correctly when SSL is nil" do
|
59
|
+
expect(subject.send(:host_to_url, https_hostname_port, nil)).to eql(https_hostname_port)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "path" do
|
64
|
+
it "should allow paths in a url" do
|
65
|
+
expect(subject.send(:host_to_url, http_hostname_port_path, nil)).to eql(http_hostname_port_path)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should not allow paths in two places" do
|
69
|
+
expect {
|
70
|
+
subject.send(:host_to_url, http_hostname_port_path, false, "/otherpath")
|
71
|
+
}.to raise_error(LogStash::ConfigurationError)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should automatically insert a / in front of path overlays if needed" do
|
75
|
+
expect(subject.send(:host_to_url, http_hostname_port, false, "otherpath")).to eql(http_hostname_port + "/otherpath")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "an regular hostname" do
|
81
|
+
let(:hostname) { true_hostname }
|
82
|
+
include_examples("proper host handling")
|
83
|
+
end
|
84
|
+
|
85
|
+
describe "an ipv4 host" do
|
86
|
+
let(:hostname) { ipv4_hostname }
|
87
|
+
include_examples("proper host handling")
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "an ipv6 host" do
|
91
|
+
let(:hostname) { ipv6_hostname }
|
92
|
+
include_examples("proper host handling")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "sniffing" do
|
97
|
+
let(:client) { LogStash::Outputs::ElasticSearch::HttpClient.new(base_options.merge(client_opts)) }
|
98
|
+
let(:transport) { client.client.transport }
|
99
|
+
|
100
|
+
before do
|
101
|
+
allow(transport).to receive(:reload_connections!)
|
102
|
+
end
|
103
|
+
|
104
|
+
context "with sniffing enabled" do
|
105
|
+
let(:client_opts) { {:sniffing => true, :sniffing_delay => 1 } }
|
106
|
+
|
107
|
+
after do
|
108
|
+
client.stop_sniffing!
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should start the sniffer" do
|
112
|
+
expect(client.sniffer_thread).to be_a(Thread)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should periodically sniff the client" do
|
116
|
+
sleep 2
|
117
|
+
expect(transport).to have_received(:reload_connections!).at_least(:once)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "with sniffing disabled" do
|
122
|
+
let(:client_opts) { {:sniffing => false} }
|
123
|
+
|
124
|
+
it "should not start the sniffer" do
|
125
|
+
expect(client.sniffer_thread).to be_nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
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: 2.
|
4
|
+
version: 2.5.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-02-
|
11
|
+
date: 2016-02-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -223,7 +223,7 @@ files:
|
|
223
223
|
- spec/integration/outputs/update_spec.rb
|
224
224
|
- spec/unit/buffer_spec.rb
|
225
225
|
- spec/unit/http_client_builder_spec.rb
|
226
|
-
- spec/unit/outputs/elasticsearch/
|
226
|
+
- spec/unit/outputs/elasticsearch/http_client_spec.rb
|
227
227
|
- spec/unit/outputs/elasticsearch_proxy_spec.rb
|
228
228
|
- spec/unit/outputs/elasticsearch_spec.rb
|
229
229
|
- spec/unit/outputs/elasticsearch_ssl_spec.rb
|
@@ -268,7 +268,7 @@ test_files:
|
|
268
268
|
- spec/integration/outputs/update_spec.rb
|
269
269
|
- spec/unit/buffer_spec.rb
|
270
270
|
- spec/unit/http_client_builder_spec.rb
|
271
|
-
- spec/unit/outputs/elasticsearch/
|
271
|
+
- spec/unit/outputs/elasticsearch/http_client_spec.rb
|
272
272
|
- spec/unit/outputs/elasticsearch_proxy_spec.rb
|
273
273
|
- spec/unit/outputs/elasticsearch_spec.rb
|
274
274
|
- spec/unit/outputs/elasticsearch_ssl_spec.rb
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require "logstash/devutils/rspec/spec_helper"
|
2
|
-
require "logstash/outputs/elasticsearch/http_client"
|
3
|
-
require "java"
|
4
|
-
|
5
|
-
describe LogStash::Outputs::ElasticSearch::HttpClient do
|
6
|
-
describe "sniffing" do
|
7
|
-
let(:base_options) { {:hosts => ["127.0.0.1"], :logger => Cabin::Channel.get }}
|
8
|
-
let(:client) { LogStash::Outputs::ElasticSearch::HttpClient.new(base_options.merge(client_opts)) }
|
9
|
-
let(:transport) { client.client.transport }
|
10
|
-
|
11
|
-
before do
|
12
|
-
allow(transport).to receive(:reload_connections!)
|
13
|
-
end
|
14
|
-
|
15
|
-
context "with sniffing enabled" do
|
16
|
-
let(:client_opts) { {:sniffing => true, :sniffing_delay => 1 } }
|
17
|
-
|
18
|
-
after do
|
19
|
-
client.stop_sniffing!
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should start the sniffer" do
|
23
|
-
expect(client.sniffer_thread).to be_a(Thread)
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should periodically sniff the client" do
|
27
|
-
sleep 2
|
28
|
-
expect(transport).to have_received(:reload_connections!).at_least(:once)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
context "with sniffing disabled" do
|
33
|
-
let(:client_opts) { {:sniffing => false} }
|
34
|
-
|
35
|
-
it "should not start the sniffer" do
|
36
|
-
expect(client.sniffer_thread).to be_nil
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
41
|
-
end
|