logstash-output-elasticsearch-test 10.3.0-x86_64-linux

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.
Files changed (75) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +397 -0
  3. data/CONTRIBUTORS +33 -0
  4. data/Gemfile +15 -0
  5. data/LICENSE +13 -0
  6. data/NOTICE.TXT +5 -0
  7. data/README.md +106 -0
  8. data/docs/index.asciidoc +899 -0
  9. data/lib/logstash/outputs/elasticsearch/common.rb +441 -0
  10. data/lib/logstash/outputs/elasticsearch/common_configs.rb +167 -0
  11. data/lib/logstash/outputs/elasticsearch/default-ilm-policy.json +14 -0
  12. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es2x.json +95 -0
  13. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es5x.json +46 -0
  14. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es6x.json +45 -0
  15. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es7x.json +44 -0
  16. data/lib/logstash/outputs/elasticsearch/elasticsearch-template-es8x.json +44 -0
  17. data/lib/logstash/outputs/elasticsearch/http_client/manticore_adapter.rb +131 -0
  18. data/lib/logstash/outputs/elasticsearch/http_client/pool.rb +495 -0
  19. data/lib/logstash/outputs/elasticsearch/http_client.rb +432 -0
  20. data/lib/logstash/outputs/elasticsearch/http_client_builder.rb +159 -0
  21. data/lib/logstash/outputs/elasticsearch/ilm.rb +113 -0
  22. data/lib/logstash/outputs/elasticsearch/template_manager.rb +61 -0
  23. data/lib/logstash/outputs/elasticsearch.rb +263 -0
  24. data/logstash-output-elasticsearch.gemspec +33 -0
  25. data/spec/es_spec_helper.rb +189 -0
  26. data/spec/fixtures/_nodes/2x_1x.json +27 -0
  27. data/spec/fixtures/_nodes/5x_6x.json +81 -0
  28. data/spec/fixtures/_nodes/7x.json +92 -0
  29. data/spec/fixtures/htpasswd +2 -0
  30. data/spec/fixtures/nginx_reverse_proxy.conf +22 -0
  31. data/spec/fixtures/scripts/groovy/scripted_update.groovy +2 -0
  32. data/spec/fixtures/scripts/groovy/scripted_update_nested.groovy +2 -0
  33. data/spec/fixtures/scripts/groovy/scripted_upsert.groovy +2 -0
  34. data/spec/fixtures/scripts/painless/scripted_update.painless +2 -0
  35. data/spec/fixtures/scripts/painless/scripted_update_nested.painless +1 -0
  36. data/spec/fixtures/scripts/painless/scripted_upsert.painless +1 -0
  37. data/spec/fixtures/template-with-policy-es6x.json +48 -0
  38. data/spec/fixtures/template-with-policy-es7x.json +45 -0
  39. data/spec/fixtures/test_certs/ca/ca.crt +32 -0
  40. data/spec/fixtures/test_certs/ca/ca.key +51 -0
  41. data/spec/fixtures/test_certs/test.crt +36 -0
  42. data/spec/fixtures/test_certs/test.key +51 -0
  43. data/spec/integration/outputs/compressed_indexing_spec.rb +69 -0
  44. data/spec/integration/outputs/create_spec.rb +67 -0
  45. data/spec/integration/outputs/delete_spec.rb +65 -0
  46. data/spec/integration/outputs/groovy_update_spec.rb +150 -0
  47. data/spec/integration/outputs/ilm_spec.rb +531 -0
  48. data/spec/integration/outputs/index_spec.rb +178 -0
  49. data/spec/integration/outputs/index_version_spec.rb +102 -0
  50. data/spec/integration/outputs/ingest_pipeline_spec.rb +74 -0
  51. data/spec/integration/outputs/metrics_spec.rb +70 -0
  52. data/spec/integration/outputs/no_es_on_startup_spec.rb +58 -0
  53. data/spec/integration/outputs/painless_update_spec.rb +189 -0
  54. data/spec/integration/outputs/parent_spec.rb +102 -0
  55. data/spec/integration/outputs/retry_spec.rb +169 -0
  56. data/spec/integration/outputs/routing_spec.rb +61 -0
  57. data/spec/integration/outputs/sniffer_spec.rb +133 -0
  58. data/spec/integration/outputs/templates_5x_spec.rb +98 -0
  59. data/spec/integration/outputs/templates_spec.rb +98 -0
  60. data/spec/integration/outputs/update_spec.rb +116 -0
  61. data/spec/support/elasticsearch/api/actions/delete_ilm_policy.rb +19 -0
  62. data/spec/support/elasticsearch/api/actions/get_alias.rb +18 -0
  63. data/spec/support/elasticsearch/api/actions/get_ilm_policy.rb +18 -0
  64. data/spec/support/elasticsearch/api/actions/put_alias.rb +24 -0
  65. data/spec/support/elasticsearch/api/actions/put_ilm_policy.rb +25 -0
  66. data/spec/unit/http_client_builder_spec.rb +185 -0
  67. data/spec/unit/outputs/elasticsearch/http_client/manticore_adapter_spec.rb +149 -0
  68. data/spec/unit/outputs/elasticsearch/http_client/pool_spec.rb +274 -0
  69. data/spec/unit/outputs/elasticsearch/http_client_spec.rb +250 -0
  70. data/spec/unit/outputs/elasticsearch/template_manager_spec.rb +25 -0
  71. data/spec/unit/outputs/elasticsearch_proxy_spec.rb +72 -0
  72. data/spec/unit/outputs/elasticsearch_spec.rb +675 -0
  73. data/spec/unit/outputs/elasticsearch_ssl_spec.rb +82 -0
  74. data/spec/unit/outputs/error_whitelist_spec.rb +54 -0
  75. 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