logstash-output-elasticsearch 11.20.1-java → 11.22.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3f3f97949dede5ce24e127df3a0cf4c809f1436d1ff34831cea6d0b873784968
4
- data.tar.gz: cadc8d310da90f1cc853b24734520859101cd787efe29b5371394248303999f9
3
+ metadata.gz: 717e2454d150e9f3ae5c7ad9a7cd6d7e4e4451f538e276c1fa1e42a0b6c37f71
4
+ data.tar.gz: 714e7b7df621a80edd1a0e3eb0978b7a5b8a3789b2652e76c3336fcf8b7a6dfe
5
5
  SHA512:
6
- metadata.gz: 9ef570b20433e6b3d69c24c9e402c39aa59a9f5556cb8c03f5643be65a7800b1a66b744be3095d11fe640a262902506fa78a7a10c3ea5b6ce1dfa81da98ea4e9
7
- data.tar.gz: c323b23e45dfa795df06fdd206134ba340c5745529c690543bf94cfdb81526306c415723bb7a9cba759df658f38cbe6b6c62a4e6d1bbc6d777b224da830e8613
6
+ metadata.gz: 4d84c7f34a39b0566770881161f50c41f1270ab94131d6d70a35f4264a8e32631ac2da4e607dc61acc565b8e2ab87ca539949046233bce135ffc52c2caf6870e
7
+ data.tar.gz: b544f8e2e0f577970464e1bf72adda1e10254c361e3c749c0bfd84ca0184e59736d53dc5e6891f8e8369d2cc101a87af661aec90cc3038aaf2261893cf25eba2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 11.22.0
2
+ - Added support for propagating event processing metadata when this output is downstream of an Elastic Integration Filter and configured _without_ explicit `version`, `version_type`, or `routing` directives [#1158](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1158)
3
+
4
+ ## 11.21.0
5
+ - Added support for propagating event processing metadata when this output is downstream of an Elastic Integration Filter and configured _without_ explicit `index`, `document_id`, or `pipeline` directives [#1155](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1155)
6
+
1
7
  ## 11.20.1
2
8
  - Doc: Replace `document_already_exist_exception` with `version_conflict_engine_exception` in the `silence_errors_in_log` setting example [#1159](https://github.com/logstash-plugins/logstash-output-elasticsearch/pull/1159)
3
9
 
@@ -499,9 +499,6 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
499
499
  params[retry_on_conflict_action_name] = @retry_on_conflict
500
500
  end
501
501
 
502
- params[:version] = event.sprintf(@version) if @version
503
- params[:version_type] = event.sprintf(@version_type) if @version_type
504
-
505
502
  EventActionTuple.new(action, params, event)
506
503
  end
507
504
 
@@ -540,15 +537,16 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
540
537
  # @return Hash (initial) parameters for given event
541
538
  # @private shared event params factory between index and data_stream mode
542
539
  def common_event_params(event)
543
- sprintf_index = @event_target.call(event)
544
- raise IndexInterpolationError, sprintf_index if sprintf_index.match(/%{.*?}/) && dlq_on_failed_indexname_interpolation
540
+ event_control = event.get("[@metadata][_ingest_document]")
541
+ event_id, event_pipeline, event_index, event_routing, event_version, event_version_type = event_control&.values_at("id","pipeline","index", "routing", "version", "version_type") rescue nil
542
+
545
543
  params = {
546
- :_id => @document_id ? event.sprintf(@document_id) : nil,
547
- :_index => sprintf_index,
548
- routing_field_name => @routing ? event.sprintf(@routing) : nil
544
+ :_id => resolve_document_id(event, event_id),
545
+ :_index => resolve_index!(event, event_index),
546
+ routing_field_name => resolve_routing(event, event_routing)
549
547
  }
550
548
 
551
- target_pipeline = resolve_pipeline(event)
549
+ target_pipeline = resolve_pipeline(event, event_pipeline)
552
550
  # convention: empty string equates to not using a pipeline
553
551
  # this is useful when using a field reference in the pipeline setting, e.g.
554
552
  # elasticsearch {
@@ -556,10 +554,53 @@ class LogStash::Outputs::ElasticSearch < LogStash::Outputs::Base
556
554
  # }
557
555
  params[:pipeline] = target_pipeline unless (target_pipeline.nil? || target_pipeline.empty?)
558
556
 
557
+ resolved_version = resolve_version(event, event_version)
558
+ resolved_version_type = resolve_version_type(event, event_version_type)
559
+ # avoid to add nil valued key-value pairs
560
+ params[:version] = resolved_version unless resolved_version.nil?
561
+ params[:version_type] = resolved_version_type unless resolved_version_type.nil?
562
+
559
563
  params
560
564
  end
561
565
 
562
- def resolve_pipeline(event)
566
+ def resolve_version(event, event_version)
567
+ return event_version if event_version && !@version
568
+ event.sprintf(@version) if @version
569
+ end
570
+ private :resolve_version
571
+
572
+ def resolve_version_type(event, event_version_type)
573
+ return event_version_type if event_version_type && !@version_type
574
+ event.sprintf(@version_type) if @version_type
575
+ end
576
+ private :resolve_version_type
577
+
578
+ def resolve_routing(event, event_routing)
579
+ return event_routing if event_routing && !@routing
580
+ @routing ? event.sprintf(@routing) : nil
581
+ end
582
+ private :resolve_routing
583
+
584
+ def resolve_document_id(event, event_id)
585
+ return event.sprintf(@document_id) if @document_id
586
+ return event_id || nil
587
+ end
588
+ private :resolve_document_id
589
+
590
+ def resolve_index!(event, event_index)
591
+ sprintf_index = @event_target.call(event)
592
+ raise IndexInterpolationError, sprintf_index if sprintf_index.match(/%{.*?}/) && dlq_on_failed_indexname_interpolation
593
+ # if it's not a data stream, sprintf_index is the @index with resolved placeholders.
594
+ # if is a data stream, sprintf_index could be either the name of a data stream or the value contained in
595
+ # @index without placeholders substitution. If event's metadata index is provided, it takes precedence
596
+ # on datastream name or whatever is returned by the event_target provider.
597
+ return event_index if @index == @default_index && event_index
598
+ return sprintf_index
599
+ end
600
+ private :resolve_index!
601
+
602
+ def resolve_pipeline(event, event_pipeline)
603
+ return event_pipeline if event_pipeline && !@pipeline
563
604
  pipeline_template = @pipeline || event.get("[@metadata][target_ingest_pipeline]")&.to_s
564
605
  pipeline_template && event.sprintf(pipeline_template)
565
606
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-output-elasticsearch'
3
- s.version = '11.20.1'
3
+ s.version = '11.22.0'
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"
@@ -271,6 +271,260 @@ describe LogStash::Outputs::ElasticSearch do
271
271
  end
272
272
  end
273
273
 
274
+ describe "with event integration metadata" do
275
+ let(:event_fields) {{}}
276
+ let(:event) { LogStash::Event.new(event_fields)}
277
+
278
+ context "when plugin's version is specified" do
279
+ let(:options) { super().merge("version" => "123")}
280
+
281
+ context "when the event contains an integration metadata version" do
282
+ let(:event) { LogStash::Event.new({"@metadata" => {"_ingest_document" => {"version" => "456"}}}) }
283
+
284
+ it "plugin's version is used" do
285
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:version => "123")
286
+ end
287
+ end
288
+
289
+ context "when the event DOESN'T contains an integration metadata version" do
290
+ it "plugin's version is used" do
291
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:version => "123")
292
+ end
293
+ end
294
+ end
295
+
296
+ context "when plugin's version is NOT specified" do
297
+ context "when the event contains an integration metadata version" do
298
+ let(:event) { LogStash::Event.new({"@metadata" => {"_ingest_document" => {"version" => "456"}}}) }
299
+
300
+ it "event's metadata version is used" do
301
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:version => "456")
302
+ end
303
+ end
304
+
305
+ context "when the event DOESN'T contain an integration metadata version" do
306
+ it "plugin's default id mechanism is used" do
307
+ expect(subject.send(:event_action_tuple, event)[1]).to_not include(:version)
308
+ end
309
+ end
310
+ end
311
+
312
+ context "when plugin's version_type is specified" do
313
+ let(:options) { super().merge("version_type" => "internal")}
314
+
315
+ context "when the event contains an integration metadata version_type" do
316
+ let(:event) { LogStash::Event.new({"@metadata" => {"_ingest_document" => {"version_type" => "external"}}}) }
317
+
318
+ it "plugin's version_type is used" do
319
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:version_type => "internal")
320
+ end
321
+ end
322
+
323
+ context "when the event DOESN'T contains an integration metadata version_type" do
324
+ it "plugin's version_type is used" do
325
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:version_type => "internal")
326
+ end
327
+ end
328
+ end
329
+
330
+ context "when plugin's version_type is NOT specified" do
331
+ context "when the event contains an integration metadata version_type" do
332
+ let(:event) { LogStash::Event.new({"@metadata" => {"_ingest_document" => {"version_type" => "external"}}}) }
333
+
334
+ it "event's metadata version_type is used" do
335
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:version_type => "external")
336
+ end
337
+ end
338
+
339
+ context "when the event DOESN'T contain an integration metadata version_type" do
340
+ it "plugin's default id mechanism is used" do
341
+ expect(subject.send(:event_action_tuple, event)[1]).to_not include(:version_type)
342
+ end
343
+ end
344
+ end
345
+
346
+ context "when plugin's routing is specified" do
347
+ let(:options) { super().merge("routing" => "settings_routing")}
348
+
349
+ context "when the event contains an integration metadata routing" do
350
+ let(:event) { LogStash::Event.new({"@metadata" => {"_ingest_document" => {"routing" => "meta-document-routing"}}}) }
351
+
352
+ it "plugin's routing is used" do
353
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:routing => "settings_routing")
354
+ end
355
+ end
356
+
357
+ context "when the event DOESN'T contains an integration metadata routing" do
358
+ it "plugin's routing is used" do
359
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:routing => "settings_routing")
360
+ end
361
+ end
362
+ end
363
+
364
+ context "when plugin's routing is NOT specified" do
365
+ context "when the event contains an integration metadata routing" do
366
+ let(:event) { LogStash::Event.new({"@metadata" => {"_ingest_document" => {"routing" => "meta-document-routing"}}}) }
367
+
368
+ it "event's metadata routing is used" do
369
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:routing => "meta-document-routing")
370
+ end
371
+ end
372
+
373
+ context "when the event DOESN'T contain an integration metadata routing" do
374
+ it "plugin's default id mechanism is used" do
375
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:routing => nil)
376
+ end
377
+ end
378
+ end
379
+
380
+ context "when plugin's index is specified" do
381
+ let(:options) { super().merge("index" => "index_from_settings")}
382
+
383
+ context "when the event contains an integration metadata index" do
384
+ let(:event_fields) { super().merge({"@metadata" => {"_ingest_document" => {"index" => "meta-document-index"}}}) }
385
+
386
+ it "plugin's index is used" do
387
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_index => "index_from_settings")
388
+ end
389
+ end
390
+
391
+ context "when the event doesn't contains an integration metadata index" do
392
+ it "plugin's index is used" do
393
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_index => "index_from_settings")
394
+ end
395
+ end
396
+ end
397
+
398
+ context "when plugin's index is NOT specified" do
399
+ let(:options) { super().merge("index" => nil)}
400
+
401
+ context "when the event contains an integration metadata index" do
402
+ let(:event_fields) { super().merge({"@metadata" => {"_ingest_document" => {"index" => "meta-document-index"}}}) }
403
+
404
+ it "event's metadata index is used" do
405
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_index => "meta-document-index")
406
+ end
407
+
408
+ context "when datastream settings are NOT configured" do
409
+ it "event's metadata index is used" do
410
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_index => "meta-document-index")
411
+ end
412
+ end
413
+
414
+ context "when datastream settings are configured" do
415
+ let(:event_fields) { super().merge({"data_stream" => {"type" => "logs", "dataset" => "generic", "namespace" => "default"}}) }
416
+
417
+ it "event's metadata index is used" do
418
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_index => "meta-document-index")
419
+ end
420
+ end
421
+ end
422
+
423
+ context "when the event DOESN'T contain integration metadata index" do
424
+ let(:default_index_resolved) { event.sprintf(subject.default_index) }
425
+
426
+ it "default index is used" do
427
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_index => default_index_resolved)
428
+ end
429
+
430
+ context "when datastream settings are NOT configured" do
431
+ it "default index is used" do
432
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_index => default_index_resolved)
433
+ end
434
+ end
435
+
436
+ context "when datastream settings are configured" do
437
+ let(:event_fields) { super().merge({"data_stream" => {"type" => "logs", "dataset" => "generic", "namespace" => "default"}}) }
438
+
439
+ it "default index is used" do
440
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_index => default_index_resolved)
441
+ end
442
+ end
443
+ end
444
+ end
445
+
446
+ context "when plugin's document_id is specified" do
447
+ let(:options) { super().merge("document_id" => "id_from_settings")}
448
+
449
+ context "when the event contains an integration metadata document_id" do
450
+ let(:event) { LogStash::Event.new({"@metadata" => {"_ingest_document" => {"id" => "meta-document-id"}}}) }
451
+
452
+ it "plugin's document_id is used" do
453
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_id => "id_from_settings")
454
+ end
455
+ end
456
+
457
+ context "when the event DOESN'T contains an integration metadata document_id" do
458
+ it "plugin's document_id is used" do
459
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_id => "id_from_settings")
460
+ end
461
+ end
462
+ end
463
+
464
+ context "when plugin's document_id is NOT specified" do
465
+ let(:options) { super().merge("document_id" => nil)}
466
+
467
+ context "when the event contains an integration metadata document_id" do
468
+ let(:event) { LogStash::Event.new({"@metadata" => {"_ingest_document" => {"id" => "meta-document-id"}}}) }
469
+
470
+ it "event's metadata document_id is used" do
471
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_id => "meta-document-id")
472
+ end
473
+ end
474
+
475
+ context "when the event DOESN'T contains an integration metadata document_id" do
476
+ it "plugin's default id mechanism is used" do
477
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:_id => nil)
478
+ end
479
+ end
480
+ end
481
+
482
+ context "when plugin's pipeline is specified" do
483
+ let(:options) { {"pipeline" => "pipeline_from_settings" } }
484
+
485
+ context "when the event contains an integration metadata pipeline" do
486
+ let(:event) { LogStash::Event.new({"@metadata" => {"_ingest_document" => {"pipeline" => "integration-pipeline"}}}) }
487
+
488
+ it "plugin's pipeline is used" do
489
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:pipeline => "pipeline_from_settings")
490
+ end
491
+ end
492
+
493
+ context "when the event DOESN'T contains an integration metadata pipeline" do
494
+ it "plugin's pipeline is used" do
495
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:pipeline => "pipeline_from_settings")
496
+ end
497
+ end
498
+ end
499
+
500
+ context "when plugin's pipeline is NOT specified" do
501
+ let(:options) { super().merge("pipeline" => nil)}
502
+
503
+ context "when the event contains an integration metadata pipeline" do
504
+ let(:metadata) { {"_ingest_document" => {"pipeline" => "integration-pipeline"}} }
505
+ let(:event) { LogStash::Event.new({"@metadata" => metadata}) }
506
+
507
+ it "event's metadata pipeline is used" do
508
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:pipeline => "integration-pipeline")
509
+ end
510
+
511
+ context "when also target_ingest_pipeline id defined" do
512
+ let(:metadata) { super().merge({"target_ingest_pipeline" => "meta-ingest-pipeline"}) }
513
+
514
+ it "then event's pipeline from _ingest_document is used" do
515
+ expect(subject.send(:event_action_tuple, event)[1]).to include(:pipeline => "integration-pipeline")
516
+ end
517
+ end
518
+ end
519
+
520
+ context "when the event DOESN'T contains an integration metadata pipeline" do
521
+ it "plugin's default pipeline mechanism is used" do
522
+ expect(subject.send(:event_action_tuple, event)[1]).to_not have_key(:pipeline)
523
+ end
524
+ end
525
+ end
526
+ end
527
+
274
528
  describe "with auth" do
275
529
  let(:user) { "myuser" }
276
530
  let(:password) { ::LogStash::Util::Password.new("mypassword") }
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: 11.20.1
4
+ version: 11.22.0
5
5
  platform: java
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-09 00:00:00.000000000 Z
11
+ date: 2023-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement