logstash-output-elasticsearch 11.2.2-java → 11.3.2-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
  SHA256:
3
- metadata.gz: 1875fec2480eb6333ab5468fcab7310efef1327b20c1d7908cb8e1cc83d3d98a
4
- data.tar.gz: f7ba2a0bffd9f4205a887bbafd277f254d9b63138f4b24da96e0eb74847c2a88
3
+ metadata.gz: b716e89a4ab884412f633b3c0e745ab787006466a44b09ca0c20c45410603eea
4
+ data.tar.gz: '09387e7905fcb56e033cf3b9d8c2db7df3f7d11d8e4dc8e638d3e9ff570f4231'
5
5
  SHA512:
6
- metadata.gz: 896ba67674bb5e589ae9f9ba622e98f9840d7c1823e8fbeafab946826c08d71438ce1e1d448258ca240c4704f734840ebb56e6fbd0bc7ba56067b23707396c42
7
- data.tar.gz: 8390add54b65038c916b7589bb02868450568e7e647008a2e68216a4f47168fe6c79ee9ac945f466898667b1bde7f71d9076fc528c2d7d24b01b0e9eafa58cf0
6
+ metadata.gz: df0e1ef992ead1c347ef7d528309c732092037186310623aa2b538e086c6eea5cba24bb9aa354d7deeb1718904ff1965a40b3bed2d4c5597c14a8d3f64276a58
7
+ data.tar.gz: bec8153c3242e4de19410eac06f8e1ee716df545a0d0a2d49b69023901a8b928315409d863581a16f3fb1feb6648ec623ef5f35faf6f707fea64cceddf136e6b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
+ ## 11.3.2
2
+ - Refactor: review manticore error handling/logging, logging originating cause in case of connection related error when debug level is enabled [#1029](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1029)
3
+ - Java causes on connection related exceptions will now be extra logged when plugin is logging at debug level
4
+
5
+ ## 11.3.1
6
+ - ECS-related fixes [#1046](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1046)
7
+ - Data Streams requirement on ECS is properly enforced when running on Logstash 8, and warned about when running on Logstash 7.
8
+ - ECS Compatibility v8 can now be selected
9
+
10
+ ## 11.3.0
11
+ - Adds ECS templates [#1048](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1048)
12
+ - Adds templates for ECS v1 for Elasticsearch 8.x
13
+ - Adds templates for BETA preview of ECS v8 for both Elasticsearch 7.x and 8.x
14
+
15
+ ## 11.2.3
16
+ - Downgrade ECS templates, pinning to v1.10.0 of upstream; fixes an issue where ECS templates cannot be installed in Elasticsearch 6.x or 7.1-7.2, since the generated templates include fields of `type: flattened` that was introduced in Elasticsearch 7.3. [#1049](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1049)
17
+
1
18
  ## 11.2.2
2
- - Update ECS templates from upstream; `ecs_compatiblity => v1` now resolves to templates for ECS v1.12.1 [#1027](https://github.com/logstash-plugins/logstash-output-elasticsearch/issues/1027)
19
+ - Update ECS templates from upstream; `ecs_compatiblity => v1` now resolves to templates for ECS v1.12.1 [#1047](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1047). Fixes [#1027](https://github.com/logstash-plugins/logstash-output-elasticsearch/issues/1027)
3
20
 
4
21
  ## 11.2.1
5
22
  - Fix referencing Gem classes from global lexical scope [#1044](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1044)
data/docs/index.asciidoc CHANGED
@@ -117,12 +117,8 @@ output {
117
117
 
118
118
  ==== Writing to different indices: best practices
119
119
 
120
- [NOTE]
121
- ================================================================================
122
- You cannot use dynamic variable substitution when `ilm_enabled` is `true` and
123
- when using `ilm_rollover_alias`.
124
-
125
- ================================================================================
120
+ NOTE: You cannot use dynamic variable substitution when `ilm_enabled` is `true`
121
+ and when using `ilm_rollover_alias`.
126
122
 
127
123
  If you're sending events to the same Elasticsearch cluster, but you're targeting different indices you can:
128
124
 
@@ -2,6 +2,15 @@ module LogStash module Outputs class ElasticSearch
2
2
  # DS specific behavior/configuration.
3
3
  module DataStreamSupport
4
4
 
5
+ # @api private
6
+ ENABLING_ECS_GUIDANCE = <<~END.tr("\n", " ")
7
+ Elasticsearch data streams require that events adhere to the Elastic Common Schema.
8
+ While `ecs_compatibility` can be set for this individual Elasticsearch output plugin, doing so will not fix schema conflicts caused by upstream plugins in your pipeline.
9
+ To avoid mapping conflicts, you will need to use ECS-compatible field names and datatypes throughout your pipeline.
10
+ Many plugins support an `ecs_compatibility` mode, and the `pipeline.ecs_compatibility` setting can be used to opt-in for all plugins in a pipeline.
11
+ END
12
+ private_constant :ENABLING_ECS_GUIDANCE
13
+
5
14
  def self.included(base)
6
15
  # Defines whether data will be indexed into an Elasticsearch data stream,
7
16
  # `data_stream_*` settings will only be used if this setting is enabled!
@@ -36,6 +45,8 @@ module LogStash module Outputs class ElasticSearch
36
45
  "#{type}-#{dataset}-#{namespace}"
37
46
  end
38
47
 
48
+ DATA_STREAMS_REQUIRES_ECS_LS_VERSION = '8.0.0'
49
+
39
50
  # @param params the user configuration for the ES output
40
51
  # @note LS initialized configuration (with filled defaults) won't detect as data-stream
41
52
  # compatible, only explicit (`original_params`) config should be tested.
@@ -56,14 +67,26 @@ module LogStash module Outputs class ElasticSearch
56
67
  @logger.error "Invalid data stream configuration, following parameters are not supported:", invalid_data_stream_params
57
68
  raise LogStash::ConfigurationError, "Invalid data stream configuration: #{invalid_data_stream_params.keys}"
58
69
  end
70
+ if ecs_compatibility == :disabled
71
+ if ::Gem::Version.create(LOGSTASH_VERSION) < ::Gem::Version.create(DATA_STREAMS_REQUIRES_ECS_LS_VERSION)
72
+ @deprecation_logger.deprecated "In a future release of Logstash, the Elasticsearch output plugin's `data_stream => true` will require the plugin to be run in ECS compatibility mode. " + ENABLING_ECS_GUIDANCE
73
+ else
74
+ @logger.error "Invalid data stream configuration; `ecs_compatibility` must not be `disabled`. " + ENABLING_ECS_GUIDANCE
75
+ raise LogStash::ConfigurationError, "Invalid data stream configuration: `ecs_compatibility => disabled`"
76
+ end
77
+ end
59
78
  return true
60
79
  else
61
- use_data_stream = data_stream_default(data_stream_params, invalid_data_stream_params.empty?)
62
- if !use_data_stream && data_stream_params.any?
80
+ use_data_stream = data_stream_default(data_stream_params, invalid_data_stream_params)
81
+ if use_data_stream
82
+ @logger.info("Config is compliant with data streams. `data_stream => auto` resolved to `true`")
83
+ elsif data_stream_params.any?
63
84
  # DS (auto) disabled but there's still some data-stream parameters (and no `data_stream => false`)
64
85
  @logger.error "Ambiguous configuration; data stream settings are present, but data streams are not enabled", data_stream_params
65
86
  raise LogStash::ConfigurationError, "Ambiguous configuration, please set data_stream => true " +
66
87
  "or remove data stream specific settings: #{data_stream_params.keys}"
88
+ else
89
+ @logger.info("Config is not compliant with data streams. `data_stream => auto` resolved to `false`")
67
90
  end
68
91
  use_data_stream
69
92
  end
@@ -93,6 +116,7 @@ module LogStash module Outputs class ElasticSearch
93
116
  true
94
117
  when 'data_stream'
95
118
  value.to_s == 'true'
119
+ when 'ecs_compatibility' then true # required for LS <= 6.x
96
120
  else
97
121
  name.start_with?('data_stream_') ||
98
122
  shared_params.include?(name) ||
@@ -110,8 +134,8 @@ module LogStash module Outputs class ElasticSearch
110
134
  # @return [Gem::Version] if ES supports DS nil (or raise) otherwise
111
135
  def assert_es_version_supports_data_streams
112
136
  fail 'no last_es_version' unless last_es_version # assert - should not happen
113
- es_version = Gem::Version.create(last_es_version)
114
- if es_version < Gem::Version.create(DATA_STREAMS_ORIGIN_ES_VERSION)
137
+ es_version = ::Gem::Version.create(last_es_version)
138
+ if es_version < ::Gem::Version.create(DATA_STREAMS_ORIGIN_ES_VERSION)
115
139
  @logger.error "Elasticsearch version does not support data streams, Logstash might end up writing to an index", es_version: es_version.version
116
140
  # NOTE: when switching to synchronous check from register, this should be a ConfigurationError
117
141
  raise LogStash::Error, "A data_stream configuration is only supported since Elasticsearch #{DATA_STREAMS_ORIGIN_ES_VERSION} " +
@@ -123,18 +147,28 @@ module LogStash module Outputs class ElasticSearch
123
147
  DATA_STREAMS_ENABLED_BY_DEFAULT_LS_VERSION = '8.0.0'
124
148
 
125
149
  # when data_stream => is either 'auto' or not set
126
- def data_stream_default(data_stream_params, valid_data_stream_config)
127
- ds_default = Gem::Version.create(LOGSTASH_VERSION) >= Gem::Version.create(DATA_STREAMS_ENABLED_BY_DEFAULT_LS_VERSION)
150
+ # @param data_stream_params [#any?]
151
+ # @param invalid_data_stream_config [#any?#inspect]
152
+ def data_stream_default(data_stream_params, invalid_data_stream_config)
153
+ if ecs_compatibility == :disabled
154
+ @logger.debug("Not eligible for data streams because ecs_compatibility is not enabled. " + ENABLING_ECS_GUIDANCE)
155
+ return false
156
+ end
157
+
158
+ ds_default = ::Gem::Version.create(LOGSTASH_VERSION) >= ::Gem::Version.create(DATA_STREAMS_ENABLED_BY_DEFAULT_LS_VERSION)
128
159
 
129
160
  if ds_default # LS 8.0
130
- return false unless valid_data_stream_config
161
+ if invalid_data_stream_config.any?
162
+ @logger.debug("Not eligible for data streams because config contains one or more settings that are not compatible with data streams: #{invalid_data_stream_config.inspect}")
163
+ return false
164
+ end
131
165
 
132
166
  @logger.debug 'Configuration is data stream compliant'
133
167
  return true
134
168
  end
135
169
 
136
170
  # LS 7.x
137
- if valid_data_stream_config && !data_stream_params.any?
171
+ if !invalid_data_stream_config.any? && !data_stream_params.any?
138
172
  @logger.warn "Configuration is data stream compliant but due backwards compatibility Logstash 7.x will not assume " +
139
173
  "writing to a data-stream, default behavior will change on Logstash 8.0 " +
140
174
  "(set `data_stream => true/false` to disable this warning)"
@@ -7,9 +7,9 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
7
7
  class ManticoreAdapter
8
8
  attr_reader :manticore, :logger
9
9
 
10
- def initialize(logger, options={})
10
+ def initialize(logger, options)
11
11
  @logger = logger
12
- options = options.clone || {}
12
+ options = options.dup
13
13
  options[:ssl] = options[:ssl] || {}
14
14
 
15
15
  # We manage our own retries directly, so let's disable them here
@@ -66,23 +66,53 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
66
66
 
67
67
  request_uri = format_url(url, path)
68
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
69
+ begin
70
+ resp = @manticore.send(method.downcase, request_uri_as_string, params)
71
+ # Manticore returns lazy responses by default
72
+ # We want to block for our usage, this will wait for the response to finish
73
+ resp.call
74
+ rescue ::Manticore::ManticoreException => e
75
+ log_request_error(e)
76
+ raise ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::HostUnreachableError.new(e, request_uri_as_string)
77
+ end
75
78
 
76
79
  # 404s are excluded because they are valid codes in the case of
77
80
  # template installation. We might need a better story around this later
78
81
  # 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)
82
+ code = resp.code
83
+ if code < 200 || code > 299 && code != 404
84
+ raise ::LogStash::Outputs::ElasticSearch::HttpClient::Pool::BadResponseCodeError.new(code, request_uri, body, resp.body)
81
85
  end
82
86
 
83
87
  resp
84
88
  end
85
89
 
90
+ def log_request_error(e)
91
+ details = { message: e.message, exception: e.class }
92
+ details[:cause] = e.cause if e.respond_to?(:cause)
93
+ details[:backtrace] = e.backtrace if @logger.debug?
94
+
95
+ level = case e
96
+ when ::Manticore::Timeout
97
+ :debug
98
+ when ::Manticore::UnknownException
99
+ :warn
100
+ else
101
+ :info
102
+ end
103
+
104
+ @logger.send level, "Failed to perform request", details
105
+ log_java_exception(details[:cause], :debug) if details[:cause] && @logger.debug?
106
+ end
107
+
108
+ def log_java_exception(e, level = :debug)
109
+ return unless e.is_a?(java.lang.Exception)
110
+ # @logger.name using the same convention as LS does
111
+ logger = self.class.name.gsub('::', '.').downcase
112
+ logger = org.apache.logging.log4j.LogManager.getLogger(logger)
113
+ logger.send(level, '', e) # logger.error('', e) - prints nested causes
114
+ end
115
+
86
116
  # Returned urls from this method should be checked for double escaping.
87
117
  def format_url(url, path_and_query=nil)
88
118
  request_uri = url.clone
@@ -96,9 +126,6 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
96
126
 
97
127
  parsed_path_and_query = java.net.URI.new(path_and_query)
98
128
 
99
- query = request_uri.query
100
- parsed_query = parsed_path_and_query.query
101
-
102
129
  new_query_parts = [request_uri.query, parsed_path_and_query.query].select do |part|
103
130
  part && !part.empty? # Skip empty nil and ""
104
131
  end
@@ -124,8 +151,5 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
124
151
  @manticore.close
125
152
  end
126
153
 
127
- def host_unreachable_exceptions
128
- [::Manticore::Timeout,::Manticore::SocketException, ::Manticore::ClientProtocolException, ::Manticore::ResolutionFailure, Manticore::SocketTimeout]
129
- end
130
154
  end
131
155
  end; end; end; end
@@ -8,27 +8,25 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
8
8
  attr_reader :url, :response_code, :request_body, :response_body
9
9
 
10
10
  def initialize(response_code, url, request_body, response_body)
11
+ super("Got response code '#{response_code}' contacting Elasticsearch at URL '#{url}'")
12
+
11
13
  @response_code = response_code
12
14
  @url = url
13
15
  @request_body = request_body
14
16
  @response_body = response_body
15
17
  end
16
18
 
17
- def message
18
- "Got response code '#{response_code}' contacting Elasticsearch at URL '#{@url}'"
19
- end
20
19
  end
21
20
  class HostUnreachableError < Error;
22
21
  attr_reader :original_error, :url
23
22
 
24
23
  def initialize(original_error, url)
24
+ super("Elasticsearch Unreachable: [#{url}][#{original_error.class}] #{original_error.message}")
25
+
25
26
  @original_error = original_error
26
27
  @url = url
27
28
  end
28
29
 
29
- def message
30
- "Elasticsearch Unreachable: [#{@url}][#{original_error.class}] #{original_error.message}"
31
- end
32
30
  end
33
31
 
34
32
  attr_reader :logger, :adapter, :sniffing, :sniffer_delay, :resurrect_delay, :healthcheck_path, :sniffing_path, :bulk_path
@@ -323,9 +321,7 @@ module LogStash; module Outputs; class ElasticSearch; class HttpClient;
323
321
  end
324
322
 
325
323
  def perform_request_to_url(url, method, path, params={}, body=nil)
326
- res = @adapter.perform_request(url, method, path, params, body)
327
- rescue *@adapter.host_unreachable_exceptions => e
328
- raise HostUnreachableError.new(e, url), "Could not reach host #{e.class}: #{e.message}"
324
+ @adapter.perform_request(url, method, path, params, body)
329
325
  end
330
326
 
331
327
  def normalize_url(uri)
@@ -322,8 +322,7 @@ module LogStash; module Outputs; class ElasticSearch;
322
322
 
323
323
  adapter_options[:headers] = client_settings[:headers] if client_settings[:headers]
324
324
 
325
- adapter_class = ::LogStash::Outputs::ElasticSearch::HttpClient::ManticoreAdapter
326
- adapter = adapter_class.new(@logger, adapter_options)
325
+ ::LogStash::Outputs::ElasticSearch::HttpClient::ManticoreAdapter.new(@logger, adapter_options)
327
326
  end
328
327
 
329
328
  def prepare_user_agent