logstash-output-elasticsearch 12.1.2-java → 12.1.5-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
  SHA256:
3
- metadata.gz: 59124c8f411f8bcb4742b43cc81cc075676732feef3275eac6898e3bf2341021
4
- data.tar.gz: 26a524985bbf66a83b19807b6ebcb9fab824b3172a1718c1cedd85cc8f142be6
3
+ metadata.gz: 84a9fb2d6f4345422640ad3b59e9c0cb59b330569cbd33dc79cc1356b828bd34
4
+ data.tar.gz: 73375c880a26de3986cc1b984f3f898af055f040e1b3ea8e9772c1be78c03a3f
5
5
  SHA512:
6
- metadata.gz: c9afff55af20a6b184a5ec912b8f96387bf3310b4de884972a3e98b7146bf2873b4a60e18f6781692cfa4c92c99fd25ef6da9ccc8a0ea4391c70eb41e81a9b5c
7
- data.tar.gz: 1599a3d08006c0ca14c7b671eea25772aeb0f6b419682ac5d6ee030fd2dfda2aef34a68dea12cd30e6f0643260b81e360063f28b46278ccb2b4be2232dfe1b1b
6
+ metadata.gz: b5c8e15da6a79b51df996e6295687281d1dd19d668b6443455aeee3218e2c88f1aea271560cdad6bbde6a5c1ce44085e9bac4acb8dd65f4b84a596f589be1369
7
+ data.tar.gz: 5ae3d4135fd0f18460b7872b58f8385ed254c9154cd150116f43cae5b54557e92a0ac7403fac7e51161b1ffc24171cf49571662c25684a46adb02a866e73e720
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 12.1.5
2
+ - Support Elastic Cloud API keys in the `api_key` option, which now accepts an `id:api_key` pair, its base64-encoded form, or an `essu_` Cloud API key, and rejects an unrecognized format at startup [#1274](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1274)
3
+
4
+ ## 12.1.4
5
+ - [Doc] Add note for index option [#1269](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1269)
6
+
7
+ ## 12.1.3
8
+ - Improves the logging experience when DLQ used [#1253](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1253)
9
+
1
10
  ## 12.1.2
2
11
  - Fix: replace deprecated `File.exists?` with `File.exist?` for Ruby 3.4 (JRuby 10) compatibility [#1238](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1238)
3
12
 
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # Logstash Plugin
2
2
 
3
- [![Travis Build Status](https://travis-ci.com/logstash-plugins/logstash-output-elasticsearch.svg)](https://travis-ci.com/logstash-plugins/logstash-output-elasticsearch)
3
+ [![Unit Tests](https://github.com/logstash-plugins/logstash-output-elasticsearch/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/logstash-plugins/logstash-output-elasticsearch/actions/workflows/unit-tests.yml)
4
+ [![Secure Integration Tests](https://github.com/logstash-plugins/logstash-output-elasticsearch/actions/workflows/secure-integration-tests.yml/badge.svg)](https://github.com/logstash-plugins/logstash-output-elasticsearch/actions/workflows/secure-integration-tests.yml)
5
+ [![Integration Tests](https://github.com/logstash-plugins/logstash-output-elasticsearch/actions/workflows/integration-tests.yml/badge.svg)](https://github.com/logstash-plugins/logstash-output-elasticsearch/actions/workflows/integration-tests.yml)
4
6
 
5
7
  This is a plugin for [Logstash](https://github.com/elastic/logstash).
6
8
 
data/docs/index.asciidoc CHANGED
@@ -467,8 +467,11 @@ For more details on actions, check out the {ref}/docs-bulk.html[Elasticsearch bu
467
467
  Authenticate using Elasticsearch API key.
468
468
  Note that this option also requires SSL/TLS, which can be enabled by supplying a <<plugins-{type}s-{plugin}-cloud_id>>, a list of HTTPS <<plugins-{type}s-{plugin}-hosts>>, or by setting <<plugins-{type}s-{plugin}-ssl_enabled,`ssl_enabled => true`>>.
469
469
 
470
- Format is `id:api_key` where `id` and `api_key` are as returned by the
471
- Elasticsearch {ref}/security-api-create-api-key.html[Create API key API].
470
+ The format is `id:api_key`, where `id` and `api_key` are as returned by the
471
+ Elasticsearch {ref}/security-api-create-api-key.html[Create API key API]. The
472
+ base64-encoded form of that pair is also accepted, as is an
473
+ https://www.elastic.co/docs/deploy-manage/api-keys/elastic-cloud-api-keys[Elastic Cloud API key]
474
+ (prefixed with `essu_`), which is used as-is.
472
475
 
473
476
  [id="plugins-{type}s-{plugin}-bulk_path"]
474
477
  ===== `bulk_path`
@@ -842,10 +845,15 @@ NOTE: `ilm_rollover_alias` does NOT support dynamic variable substitution as
842
845
  The indexing target to write events to.
843
846
  Can point to an {ref}/index-mgmt.html[index], {ref}/aliases.html[alias], or {ref}/data-streams.html[data stream].
844
847
  This can be dynamic using the `%{foo}` syntax.
848
+
849
+ NOTE: When using dynamic syntax, verify that the resolved index names align with your cluster index templates and Index Lifecycle Management (ILM) configuration.
850
+
851
+ WARNING: Date math (e.g. `%{+yyyy.MM.dd}`) is not recommended for use with aliases or data streams.
852
+
845
853
  The default value will partition your indices by day so you can more easily
846
854
  delete old data or only search specific date ranges.
847
855
  Indexes may not contain uppercase characters.
848
- For weekly indexes ISO 8601 format is recommended, eg. logstash-%{+xxxx.ww}.
856
+ For weekly indexes ISO 8601 format is recommended, eg. `logstash-%{+xxxx.ww}`.
849
857
  Logstash uses
850
858
  http://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html[Joda
851
859
  formats] and the `@timestamp` field of each event is being used as source for the date.
@@ -190,8 +190,7 @@ module LogStash; module Outputs; class ElasticSearch;
190
190
 
191
191
  return {} unless (api_key&.value)
192
192
 
193
- value = is_base64?(api_key.value) ? api_key.value : Base64.strict_encode64(api_key.value)
194
-
193
+ value = resolve_api_key(api_key.value)
195
194
  { "Authorization" => "ApiKey #{value}" }
196
195
  end
197
196
 
@@ -212,6 +211,28 @@ module LogStash; module Outputs; class ElasticSearch;
212
211
  url.match?(/\?[^\s#]+/) ? '&' : '?'
213
212
  end
214
213
 
214
+ # Resolves the `api_key` value into the credential used in the
215
+ # `Authorization: ApiKey` header. An already base64-encoded key and an
216
+ # Elastic Cloud API key are used as-is; a raw `id:api_key` pair is
217
+ # base64-encoded. An unrecognized value is rejected so a malformed key
218
+ # surfaces at startup rather than as a later authentication failure.
219
+ def resolve_api_key(key_value)
220
+ if is_base64?(key_value) || cloud_api_key?(key_value)
221
+ key_value
222
+ elsif key_value.match?(/\A[^:]+:[^:]+\z/)
223
+ Base64.strict_encode64(key_value)
224
+ else
225
+ raise LogStash::ConfigurationError, "Invalid api_key format. Expected a base64-encoded key, an 'id:api_key' pair, or a Cloud API key (essu_ prefix)."
226
+ end
227
+ end
228
+
229
+ # Elastic Cloud API keys (such as the unified Serverless keys) are opaque
230
+ # tokens prefixed with `essu_` that Elasticsearch accepts verbatim in the
231
+ # `Authorization: ApiKey` header, with no base64 encoding.
232
+ def cloud_api_key?(string)
233
+ string.match?(/\Aessu_.+/)
234
+ end
235
+
215
236
  def is_base64?(string)
216
237
  begin
217
238
  string == Base64.strict_encode64(Base64.strict_decode64(string))
@@ -16,7 +16,8 @@ module LogStash; module PluginMixins; module ElasticSearch
16
16
  :password => { :validate => :password },
17
17
 
18
18
  # Authenticate using Elasticsearch API key.
19
- # format is id:api_key (as returned by https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html[Create API key])
19
+ # Format is either the `id:api_key` pair (as returned by https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html[Create API key]),
20
+ # its base64-encoded form, or an https://www.elastic.co/docs/deploy-manage/api-keys/elastic-cloud-api-keys[Elastic Cloud API key] (prefixed with `essu_`) can be used.
20
21
  :api_key => { :validate => :password },
21
22
 
22
23
  # Cloud authentication string ("<username>:<password>" format) is an alternative for the `user`/`password` configuration.
@@ -241,7 +241,6 @@ module LogStash; module PluginMixins; module ElasticSearch
241
241
  @dlq_writer.write(event, "#{detailed_message}")
242
242
  else
243
243
  log_level = dig_value(response, 'index', 'error', 'type') == 'invalid_index_name_exception' ? :error : :warn
244
-
245
244
  @logger.public_send(log_level, message, status: status, action: action_params, response: response)
246
245
  end
247
246
  end
@@ -273,6 +272,7 @@ module LogStash; module PluginMixins; module ElasticSearch
273
272
  end
274
273
 
275
274
  actions_to_retry = []
275
+ dlq_routed_stats = {}
276
276
  responses.each_with_index do |response,idx|
277
277
  action_type, action_props = response.first
278
278
 
@@ -296,6 +296,11 @@ module LogStash; module PluginMixins; module ElasticSearch
296
296
  elsif @dlq_codes.include?(status)
297
297
  handle_dlq_response("Could not index event to Elasticsearch.", action, status, response)
298
298
  @document_level_metrics.increment(:dlq_routed)
299
+ if dlq_routed_stats.key?(status)
300
+ dlq_routed_stats[status][:count] += 1
301
+ else
302
+ dlq_routed_stats[status] = { :count => 1, :sample_event => { :action => action, :response => response } }
303
+ end
299
304
  next
300
305
  else
301
306
  # only log what the user whitelisted
@@ -305,6 +310,11 @@ module LogStash; module PluginMixins; module ElasticSearch
305
310
  end
306
311
  end
307
312
 
313
+ if @dlq_writer && !dlq_routed_stats.empty?
314
+ total = dlq_routed_stats.values.sum { |entry| entry[:count] }
315
+ @logger.warn("Events could not be indexed and routing to DLQ", :count => total, :dlq_routed_stats => dlq_routed_stats)
316
+ end
317
+
308
318
  actions_to_retry
309
319
  end
310
320
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-elasticsearch'
3
- s.version = '12.1.2'
3
+ s.version = ::File.read('version').split("\n").first
4
4
  s.licenses = ['apache-2.0']
5
5
  s.summary = "Stores logs in Elasticsearch"
6
6
  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"
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.platform = RUBY_PLATFORM
13
13
 
14
14
  # Files
15
- s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "VERSION", "docs/**/*"]
15
+ s.files = Dir["lib/**/*","spec/**/*","*.gemspec","*.md","CONTRIBUTORS","Gemfile","LICENSE","NOTICE.TXT", "vendor/jar-dependencies/**/*.jar", "vendor/jar-dependencies/**/*.rb", "VERSION", "version", "docs/**/*"]
16
16
 
17
17
  # Tests
18
18
  s.test_files = s.files.grep(%r{^(test|spec|features)/})
@@ -62,6 +62,40 @@ describe LogStash::Outputs::ElasticSearch::HttpClientBuilder do
62
62
  expect(api_key_header["Authorization"]).to eql(expected)
63
63
  end
64
64
  end
65
+
66
+ context "when api-key is an Elastic Cloud API key (essu_ prefix)" do
67
+ # The suffix is intentionally not canonical base64: a Cloud key is opaque
68
+ # and must be forwarded verbatim regardless of its payload encoding.
69
+ let(:api_key) { "essu_VFZGblZreFhTekJ4ZDB4M2NHUnZRMEU2YzNWd1pYSnpaV055WlhRPQ==AAAAAAAA" }
70
+ let(:api_key_secured) do
71
+ secured = double("api_key")
72
+ allow(secured).to receive(:value).and_return(api_key)
73
+ secured
74
+ end
75
+ let(:options) { { "api_key" => api_key_secured } }
76
+ let(:logger) { double("logger") }
77
+ let(:api_key_header) { klass.setup_api_key(logger, options) }
78
+
79
+ it "returns the cloud api-key header verbatim without re-encoding" do
80
+ expected = "ApiKey #{api_key}"
81
+ expect(api_key_header["Authorization"]).to eql(expected)
82
+ end
83
+ end
84
+
85
+ context "when api-key has an unrecognized format" do
86
+ let(:api_key) { "not-a-valid-key" }
87
+ let(:api_key_secured) do
88
+ secured = double("api_key")
89
+ allow(secured).to receive(:value).and_return(api_key)
90
+ secured
91
+ end
92
+ let(:options) { { "api_key" => api_key_secured } }
93
+ let(:logger) { double("logger") }
94
+
95
+ it "raises a configuration error" do
96
+ expect { klass.setup_api_key(logger, options) }.to raise_error(LogStash::ConfigurationError, /Invalid api_key format/)
97
+ end
98
+ end
65
99
  end
66
100
 
67
101
  describe "customizing action paths" do
@@ -901,6 +901,9 @@ describe LogStash::Outputs::ElasticSearch do
901
901
 
902
902
  before(:each) do
903
903
  allow(elasticsearch_output_instance.client).to receive(:logger).and_return(logger_stub)
904
+ # Stub the output plugin's own @logger to prevent submit()/retrying_submit()
905
+ # from logging the full 15MB action payload on each retry, which floods stdout.
906
+ elasticsearch_output_instance.instance_variable_set(:@logger, logger_stub)
904
907
 
905
908
  allow(elasticsearch_output_instance.client).to receive(:bulk).and_call_original
906
909
 
@@ -1475,7 +1478,7 @@ describe LogStash::Outputs::ElasticSearch do
1475
1478
  expect( event ).to be_a LogStash::Event
1476
1479
  expect( event ).to be events.first
1477
1480
  expect( reason ).to start_with "Could not index event to Elasticsearch. status: #{error_code}, action: [\"index\""
1478
- expect( reason ).to match /_id=>"bar".*"foo"=>"bar".*response:.*"reason"=>"TEST"/
1481
+ expect( reason ).to match /_id(?::| ?=>) ?"bar".*"foo" ?=> ?"bar".*response:.*"reason" ?=> ?"TEST"/
1479
1482
 
1480
1483
  method.call(*args) # won't hurt to call LogStash::Util::DummyDeadLetterQueueWriter
1481
1484
  end.once
data/version ADDED
@@ -0,0 +1 @@
1
+ 12.1.5
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-output-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.1.2
4
+ version: 12.1.5
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-02-11 00:00:00.000000000 Z
10
+ date: 2026-07-03 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: manticore
@@ -334,6 +334,7 @@ files:
334
334
  - spec/unit/outputs/elasticsearch_ssl_spec.rb
335
335
  - spec/unit/outputs/error_whitelist_spec.rb
336
336
  - spec/unit/outputs/license_check_spec.rb
337
+ - version
337
338
  homepage: https://www.elastic.co/guide/en/logstash/current/index.html
338
339
  licenses:
339
340
  - apache-2.0