logstash-output-elasticsearch-test 10.3.0-x86_64-linux
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +397 -0
- data/CONTRIBUTORS +33 -0
- data/Gemfile +15 -0
- data/LICENSE +13 -0
- data/NOTICE.TXT +5 -0
- data/README.md +106 -0
- data/docs/index.asciidoc +899 -0
- data/lib/logstash/outputs/elasticsearch/common.rb +441 -0
- data/lib/logstash/outputs/elasticsearch/common_configs.rb +167 -0
- data/lib/logstash/outputs/elasticsearch/default-ilm-policy.json +14 -0
- data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es2x.json +95 -0
- data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es5x.json +46 -0
- data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es6x.json +45 -0
- data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es7x.json +44 -0
- data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es8x.json +44 -0
- data/lib/logstash/outputs/elasticsearch/http_client/manticore_adapter.rb +131 -0
- data/lib/logstash/outputs/elasticsearch/http_client/pool.rb +495 -0
- data/lib/logstash/outputs/elasticsearch/http_client.rb +432 -0
- data/lib/logstash/outputs/elasticsearch/http_client_builder.rb +159 -0
- data/lib/logstash/outputs/elasticsearch/ilm.rb +113 -0
- data/lib/logstash/outputs/elasticsearch/template_manager.rb +61 -0
- data/lib/logstash/outputs/elasticsearch.rb +263 -0
- data/logstash-output-elasticsearch.gemspec +33 -0
- data/spec/es_spec_helper.rb +189 -0
- data/spec/fixtures/_nodes/2x_1x.json +27 -0
- data/spec/fixtures/_nodes/5x_6x.json +81 -0
- data/spec/fixtures/_nodes/7x.json +92 -0
- data/spec/fixtures/htpasswd +2 -0
- data/spec/fixtures/nginx_reverse_proxy.conf +22 -0
- data/spec/fixtures/scripts/groovy/scripted_update.groovy +2 -0
- data/spec/fixtures/scripts/groovy/scripted_update_nested.groovy +2 -0
- data/spec/fixtures/scripts/groovy/scripted_upsert.groovy +2 -0
- data/spec/fixtures/scripts/painless/scripted_update.painless +2 -0
- data/spec/fixtures/scripts/painless/scripted_update_nested.painless +1 -0
- data/spec/fixtures/scripts/painless/scripted_upsert.painless +1 -0
- data/spec/fixtures/template-with-policy-es6x.json +48 -0
- data/spec/fixtures/template-with-policy-es7x.json +45 -0
- data/spec/fixtures/test_certs/ca/ca.crt +32 -0
- data/spec/fixtures/test_certs/ca/ca.key +51 -0
- data/spec/fixtures/test_certs/test.crt +36 -0
- data/spec/fixtures/test_certs/test.key +51 -0
- data/spec/integration/outputs/compressed_indexing_spec.rb +69 -0
- data/spec/integration/outputs/create_spec.rb +67 -0
- data/spec/integration/outputs/delete_spec.rb +65 -0
- data/spec/integration/outputs/groovy_update_spec.rb +150 -0
- data/spec/integration/outputs/ilm_spec.rb +531 -0
- data/spec/integration/outputs/index_spec.rb +178 -0
- data/spec/integration/outputs/index_version_spec.rb +102 -0
- data/spec/integration/outputs/ingest_pipeline_spec.rb +74 -0
- data/spec/integration/outputs/metrics_spec.rb +70 -0
- data/spec/integration/outputs/no_es_on_startup_spec.rb +58 -0
- data/spec/integration/outputs/painless_update_spec.rb +189 -0
- data/spec/integration/outputs/parent_spec.rb +102 -0
- data/spec/integration/outputs/retry_spec.rb +169 -0
- data/spec/integration/outputs/routing_spec.rb +61 -0
- data/spec/integration/outputs/sniffer_spec.rb +133 -0
- data/spec/integration/outputs/templates_5x_spec.rb +98 -0
- data/spec/integration/outputs/templates_spec.rb +98 -0
- data/spec/integration/outputs/update_spec.rb +116 -0
- data/spec/support/elasticsearch/api/actions/delete_ilm_policy.rb +19 -0
- data/spec/support/elasticsearch/api/actions/get_alias.rb +18 -0
- data/spec/support/elasticsearch/api/actions/get_ilm_policy.rb +18 -0
- data/spec/support/elasticsearch/api/actions/put_alias.rb +24 -0
- data/spec/support/elasticsearch/api/actions/put_ilm_policy.rb +25 -0
- data/spec/unit/http_client_builder_spec.rb +185 -0
- data/spec/unit/outputs/elasticsearch/http_client/manticore_adapter_spec.rb +149 -0
- data/spec/unit/outputs/elasticsearch/http_client/pool_spec.rb +274 -0
- data/spec/unit/outputs/elasticsearch/http_client_spec.rb +250 -0
- data/spec/unit/outputs/elasticsearch/template_manager_spec.rb +25 -0
- data/spec/unit/outputs/elasticsearch_proxy_spec.rb +72 -0
- data/spec/unit/outputs/elasticsearch_spec.rb +675 -0
- data/spec/unit/outputs/elasticsearch_ssl_spec.rb +82 -0
- data/spec/unit/outputs/error_whitelist_spec.rb +54 -0
- metadata +300 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
{
|
2
|
+
"template" : "logstash-*",
|
3
|
+
"settings" : {
|
4
|
+
"index.refresh_interval" : "5s"
|
5
|
+
},
|
6
|
+
"mappings" : {
|
7
|
+
"_default_" : {
|
8
|
+
"_all" : {"enabled" : true, "omit_norms" : true},
|
9
|
+
"dynamic_templates" : [ {
|
10
|
+
"message_field" : {
|
11
|
+
"path_match" : "message",
|
12
|
+
"match_mapping_type" : "string",
|
13
|
+
"mapping" : {
|
14
|
+
"type" : "string", "index" : "analyzed", "omit_norms" : true,
|
15
|
+
"fielddata" : { "format" : "disabled" }
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}, {
|
19
|
+
"string_fields" : {
|
20
|
+
"match" : "*",
|
21
|
+
"match_mapping_type" : "string",
|
22
|
+
"mapping" : {
|
23
|
+
"type" : "string", "index" : "analyzed", "omit_norms" : true,
|
24
|
+
"fielddata" : { "format" : "disabled" },
|
25
|
+
"fields" : {
|
26
|
+
"raw" : {"type": "string", "index" : "not_analyzed", "doc_values" : true, "ignore_above" : 256}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
}, {
|
31
|
+
"float_fields" : {
|
32
|
+
"match" : "*",
|
33
|
+
"match_mapping_type" : "float",
|
34
|
+
"mapping" : { "type" : "float", "doc_values" : true }
|
35
|
+
}
|
36
|
+
}, {
|
37
|
+
"double_fields" : {
|
38
|
+
"match" : "*",
|
39
|
+
"match_mapping_type" : "double",
|
40
|
+
"mapping" : { "type" : "double", "doc_values" : true }
|
41
|
+
}
|
42
|
+
}, {
|
43
|
+
"byte_fields" : {
|
44
|
+
"match" : "*",
|
45
|
+
"match_mapping_type" : "byte",
|
46
|
+
"mapping" : { "type" : "byte", "doc_values" : true }
|
47
|
+
}
|
48
|
+
}, {
|
49
|
+
"short_fields" : {
|
50
|
+
"match" : "*",
|
51
|
+
"match_mapping_type" : "short",
|
52
|
+
"mapping" : { "type" : "short", "doc_values" : true }
|
53
|
+
}
|
54
|
+
}, {
|
55
|
+
"integer_fields" : {
|
56
|
+
"match" : "*",
|
57
|
+
"match_mapping_type" : "integer",
|
58
|
+
"mapping" : { "type" : "integer", "doc_values" : true }
|
59
|
+
}
|
60
|
+
}, {
|
61
|
+
"long_fields" : {
|
62
|
+
"match" : "*",
|
63
|
+
"match_mapping_type" : "long",
|
64
|
+
"mapping" : { "type" : "long", "doc_values" : true }
|
65
|
+
}
|
66
|
+
}, {
|
67
|
+
"date_fields" : {
|
68
|
+
"match" : "*",
|
69
|
+
"match_mapping_type" : "date",
|
70
|
+
"mapping" : { "type" : "date", "doc_values" : true }
|
71
|
+
}
|
72
|
+
}, {
|
73
|
+
"geo_point_fields" : {
|
74
|
+
"match" : "*",
|
75
|
+
"match_mapping_type" : "geo_point",
|
76
|
+
"mapping" : { "type" : "geo_point", "doc_values" : true }
|
77
|
+
}
|
78
|
+
} ],
|
79
|
+
"properties" : {
|
80
|
+
"@timestamp": { "type": "date", "doc_values" : true },
|
81
|
+
"@version": { "type": "string", "index": "not_analyzed", "doc_values" : true },
|
82
|
+
"geoip" : {
|
83
|
+
"type" : "object",
|
84
|
+
"dynamic": true,
|
85
|
+
"properties" : {
|
86
|
+
"ip": { "type": "ip", "doc_values" : true },
|
87
|
+
"location" : { "type" : "geo_point", "doc_values" : true },
|
88
|
+
"latitude" : { "type" : "float", "doc_values" : true },
|
89
|
+
"longitude" : { "type" : "float", "doc_values" : true }
|
90
|
+
}
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
{
|
2
|
+
"template" : "logstash-*",
|
3
|
+
"version" : 50001,
|
4
|
+
"settings" : {
|
5
|
+
"index.refresh_interval" : "5s"
|
6
|
+
},
|
7
|
+
"mappings" : {
|
8
|
+
"_default_" : {
|
9
|
+
"_all" : {"enabled" : true, "norms" : false},
|
10
|
+
"dynamic_templates" : [ {
|
11
|
+
"message_field" : {
|
12
|
+
"path_match" : "message",
|
13
|
+
"match_mapping_type" : "string",
|
14
|
+
"mapping" : {
|
15
|
+
"type" : "text",
|
16
|
+
"norms" : false
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}, {
|
20
|
+
"string_fields" : {
|
21
|
+
"match" : "*",
|
22
|
+
"match_mapping_type" : "string",
|
23
|
+
"mapping" : {
|
24
|
+
"type" : "text", "norms" : false,
|
25
|
+
"fields" : {
|
26
|
+
"keyword" : { "type": "keyword", "ignore_above": 256 }
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
} ],
|
31
|
+
"properties" : {
|
32
|
+
"@timestamp": { "type": "date", "include_in_all": false },
|
33
|
+
"@version": { "type": "keyword", "include_in_all": false },
|
34
|
+
"geoip" : {
|
35
|
+
"dynamic": true,
|
36
|
+
"properties" : {
|
37
|
+
"ip": { "type": "ip" },
|
38
|
+
"location" : { "type" : "geo_point" },
|
39
|
+
"latitude" : { "type" : "half_float" },
|
40
|
+
"longitude" : { "type" : "half_float" }
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
{
|
2
|
+
"template" : "logstash-*",
|
3
|
+
"version" : 60001,
|
4
|
+
"settings" : {
|
5
|
+
"index.refresh_interval" : "5s"
|
6
|
+
},
|
7
|
+
"mappings" : {
|
8
|
+
"_default_" : {
|
9
|
+
"dynamic_templates" : [ {
|
10
|
+
"message_field" : {
|
11
|
+
"path_match" : "message",
|
12
|
+
"match_mapping_type" : "string",
|
13
|
+
"mapping" : {
|
14
|
+
"type" : "text",
|
15
|
+
"norms" : false
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}, {
|
19
|
+
"string_fields" : {
|
20
|
+
"match" : "*",
|
21
|
+
"match_mapping_type" : "string",
|
22
|
+
"mapping" : {
|
23
|
+
"type" : "text", "norms" : false,
|
24
|
+
"fields" : {
|
25
|
+
"keyword" : { "type": "keyword", "ignore_above": 256 }
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
} ],
|
30
|
+
"properties" : {
|
31
|
+
"@timestamp": { "type": "date"},
|
32
|
+
"@version": { "type": "keyword"},
|
33
|
+
"geoip" : {
|
34
|
+
"dynamic": true,
|
35
|
+
"properties" : {
|
36
|
+
"ip": { "type": "ip" },
|
37
|
+
"location" : { "type" : "geo_point" },
|
38
|
+
"latitude" : { "type" : "half_float" },
|
39
|
+
"longitude" : { "type" : "half_float" }
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
{
|
2
|
+
"index_patterns" : "logstash-*",
|
3
|
+
"version" : 60001,
|
4
|
+
"settings" : {
|
5
|
+
"index.refresh_interval" : "5s",
|
6
|
+
"number_of_shards": 1
|
7
|
+
},
|
8
|
+
"mappings" : {
|
9
|
+
"dynamic_templates" : [ {
|
10
|
+
"message_field" : {
|
11
|
+
"path_match" : "message",
|
12
|
+
"match_mapping_type" : "string",
|
13
|
+
"mapping" : {
|
14
|
+
"type" : "text",
|
15
|
+
"norms" : false
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}, {
|
19
|
+
"string_fields" : {
|
20
|
+
"match" : "*",
|
21
|
+
"match_mapping_type" : "string",
|
22
|
+
"mapping" : {
|
23
|
+
"type" : "text", "norms" : false,
|
24
|
+
"fields" : {
|
25
|
+
"keyword" : { "type": "keyword", "ignore_above": 256 }
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
} ],
|
30
|
+
"properties" : {
|
31
|
+
"@timestamp": { "type": "date"},
|
32
|
+
"@version": { "type": "keyword"},
|
33
|
+
"geoip" : {
|
34
|
+
"dynamic": true,
|
35
|
+
"properties" : {
|
36
|
+
"ip": { "type": "ip" },
|
37
|
+
"location" : { "type" : "geo_point" },
|
38
|
+
"latitude" : { "type" : "half_float" },
|
39
|
+
"longitude" : { "type" : "half_float" }
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
{
|
2
|
+
"index_patterns" : "logstash-*",
|
3
|
+
"version" : 80001,
|
4
|
+
"settings" : {
|
5
|
+
"index.refresh_interval" : "5s",
|
6
|
+
"number_of_shards": 1
|
7
|
+
},
|
8
|
+
"mappings" : {
|
9
|
+
"dynamic_templates" : [ {
|
10
|
+
"message_field" : {
|
11
|
+
"path_match" : "message",
|
12
|
+
"match_mapping_type" : "string",
|
13
|
+
"mapping" : {
|
14
|
+
"type" : "text",
|
15
|
+
"norms" : false
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}, {
|
19
|
+
"string_fields" : {
|
20
|
+
"match" : "*",
|
21
|
+
"match_mapping_type" : "string",
|
22
|
+
"mapping" : {
|
23
|
+
"type" : "text", "norms" : false,
|
24
|
+
"fields" : {
|
25
|
+
"keyword" : { "type": "keyword", "ignore_above": 256 }
|
26
|
+
}
|
27
|
+
}
|
28
|
+
}
|
29
|
+
} ],
|
30
|
+
"properties" : {
|
31
|
+
"@timestamp": { "type": "date"},
|
32
|
+
"@version": { "type": "keyword"},
|
33
|
+
"geoip" : {
|
34
|
+
"dynamic": true,
|
35
|
+
"properties" : {
|
36
|
+
"ip": { "type": "ip" },
|
37
|
+
"location" : { "type" : "geo_point" },
|
38
|
+
"latitude" : { "type" : "half_float" },
|
39
|
+
"longitude" : { "type" : "half_float" }
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'manticore'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
module LogStash; module Outputs; class ElasticSearch; class HttpClient;
|
5
|
+
DEFAULT_HEADERS = { "Content-Type" => "application/json" }
|
6
|
+
|
7
|
+
class ManticoreAdapter
|
8
|
+
attr_reader :manticore, :logger
|
9
|
+
|
10
|
+
def initialize(logger, options={})
|
11
|
+
@logger = logger
|
12
|
+
options = options.clone || {}
|
13
|
+
options[:ssl] = options[:ssl] || {}
|
14
|
+
|
15
|
+
# We manage our own retries directly, so let's disable them here
|
16
|
+
options[:automatic_retries] = 0
|
17
|
+
# We definitely don't need cookies
|
18
|
+
options[:cookies] = false
|
19
|
+
|
20
|
+
@client_params = {:headers => DEFAULT_HEADERS.merge(options[:headers] || {})}
|
21
|
+
|
22
|
+
if options[:proxy]
|
23
|
+
options[:proxy] = manticore_proxy_hash(options[:proxy])
|
24
|
+
end
|
25
|
+
|
26
|
+
@manticore = ::Manticore::Client.new(options)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Transform the proxy option to a hash. Manticore's support for non-hash
|
30
|
+
# proxy options is broken. This was fixed in https://github.com/cheald/manticore/commit/34a00cee57a56148629ed0a47c329181e7319af5
|
31
|
+
# but this is not yet released
|
32
|
+
def manticore_proxy_hash(proxy_uri)
|
33
|
+
[:scheme, :port, :user, :password, :path].reduce(:host => proxy_uri.host) do |acc,opt|
|
34
|
+
value = proxy_uri.send(opt)
|
35
|
+
acc[opt] = value unless value.nil? || (value.is_a?(String) && value.empty?)
|
36
|
+
acc
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def client
|
41
|
+
@manticore
|
42
|
+
end
|
43
|
+
|
44
|
+
# Performs the request by invoking {Transport::Base#perform_request} with a block.
|
45
|
+
#
|
46
|
+
# @return [Response]
|
47
|
+
# @see Transport::Base#perform_request
|
48
|
+
#
|
49
|
+
def perform_request(url, method, path, params={}, body=nil)
|
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
|
+
}
|
55
|
+
params[:body] = body if body
|
56
|
+
|
57
|
+
if url.user
|
58
|
+
params[:auth] = {
|
59
|
+
:user => CGI.unescape(url.user),
|
60
|
+
# We have to unescape the password here since manticore won't do it
|
61
|
+
# for us unless its part of the URL
|
62
|
+
:password => CGI.unescape(url.password),
|
63
|
+
:eager => true
|
64
|
+
}
|
65
|
+
end
|
66
|
+
|
67
|
+
request_uri = format_url(url, path)
|
68
|
+
request_uri_as_string = remove_double_escaping(request_uri.to_s)
|
69
|
+
resp = @manticore.send(method.downcase, request_uri_as_string, params)
|
70
|
+
|
71
|
+
# Manticore returns lazy responses by default
|
72
|
+
# We want to block for our usage, this will wait for the repsonse
|
73
|
+
# to finish
|
74
|
+
resp.call
|
75
|
+
|
76
|
+
# 404s are excluded because they are valid codes in the case of
|
77
|
+
# template installation. We might need a better story around this later
|
78
|
+
# but for our current purposes this is correct
|
79
|
+
if resp.code < 200 || resp.code > 299 && resp.code != 404
|
80
|
+
raise ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError.new(resp.code, request_uri, body, resp.body)
|
81
|
+
end
|
82
|
+
|
83
|
+
resp
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returned urls from this method should be checked for double escaping.
|
87
|
+
def format_url(url, path_and_query=nil)
|
88
|
+
request_uri = url.clone
|
89
|
+
|
90
|
+
# We excise auth info from the URL in case manticore itself tries to stick
|
91
|
+
# sensitive data in a thrown exception or log data
|
92
|
+
request_uri.user = nil
|
93
|
+
request_uri.password = nil
|
94
|
+
|
95
|
+
return request_uri.to_s if path_and_query.nil?
|
96
|
+
|
97
|
+
parsed_path_and_query = java.net.URI.new(path_and_query)
|
98
|
+
|
99
|
+
query = request_uri.query
|
100
|
+
parsed_query = parsed_path_and_query.query
|
101
|
+
|
102
|
+
new_query_parts = [request_uri.query, parsed_path_and_query.query].select do |part|
|
103
|
+
part && !part.empty? # Skip empty nil and ""
|
104
|
+
end
|
105
|
+
|
106
|
+
request_uri.query = new_query_parts.join("&") unless new_query_parts.empty?
|
107
|
+
|
108
|
+
# use `raw_path`` as `path` will unescape any escaped '/' in the path
|
109
|
+
request_uri.path = "#{request_uri.path}/#{parsed_path_and_query.raw_path}".gsub(/\/{2,}/, "/")
|
110
|
+
request_uri
|
111
|
+
end
|
112
|
+
|
113
|
+
# Later versions of SafeURI will also escape the '%' sign in an already escaped URI.
|
114
|
+
# (If the path variable is used, it constructs a new java.net.URI object using the multi-arg constructor,
|
115
|
+
# which will escape any '%' characters in the path, as opposed to the single-arg constructor which requires illegal
|
116
|
+
# characters to be already escaped, and will throw otherwise)
|
117
|
+
# The URI needs to have been previously escaped, as it does not play nice with an escaped '/' in the
|
118
|
+
# middle of a URI, as required by date math, treating it as a path separator
|
119
|
+
def remove_double_escaping(url)
|
120
|
+
url.gsub(/%25([0-9A-F]{2})/i, '%\1')
|
121
|
+
end
|
122
|
+
|
123
|
+
def close
|
124
|
+
@manticore.close
|
125
|
+
end
|
126
|
+
|
127
|
+
def host_unreachable_exceptions
|
128
|
+
[::Manticore::Timeout,::Manticore::SocketException, ::Manticore::ClientProtocolException, ::Manticore::ResolutionFailure, Manticore::SocketTimeout]
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end; end; end; end
|