fluent-plugin-elasticsearch 5.4.2 → 5.4.4

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: d654e4c24122a1f08b7440556ff43eca647e9aae360c4ebc43f4e29d7a8abfec
4
- data.tar.gz: 961f8dab627d2628e854e4b6b64a30fb3719c8387dfd73a67aa6da8f059eb447
3
+ metadata.gz: 5808f1d08b2a774e67ea22cbf9b678100a1a630c22f6d27ed4c2c656b396f32c
4
+ data.tar.gz: 836d9697ba68a2b86875429abd31fd09b8d4533d26b2dab4ede5ebdf64a9aad7
5
5
  SHA512:
6
- metadata.gz: 78d3e7ab001e326c47a192798da97b9d44956db46869b807589818469b8c74cfc36bc936c67f2fdffed3c2f2967d4c9ede1737c8c6d774362f524861eee74186
7
- data.tar.gz: 85e1144f3b227d28772cf785932a44bdf6d73307b7cc0401098acd97083b9638089d5a1e5ad2343cc9a7f64f4d93e274db99419fe07fdfe5b785176d667e6592
6
+ metadata.gz: 3c349e163f308a421d5bc7f74f170def2a1b3845650680b93479a01fcdcd32b2a89dfcb49903ca6c3eaea041beb9dcead4ce5735189f83aa95f9151c2ce3433a
7
+ data.tar.gz: 0cb7d133409a0289a00fd3e09e9447ac92a3ab72d74cefe92e191477e3bbba0673a322448d8828bb0adc37fcb6f7c523469ec9a95273a5a86fade6fb0dc9cdc8
@@ -11,7 +11,7 @@ jobs:
11
11
  strategy:
12
12
  fail-fast: false
13
13
  matrix:
14
- ruby: [ '3.0', '3.1', '3.2' ]
14
+ ruby: [ '3.0', '3.1', '3.2', '3.3', '3.4' ]
15
15
  os:
16
16
  - ubuntu-latest
17
17
  name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
@@ -11,7 +11,7 @@ jobs:
11
11
  strategy:
12
12
  fail-fast: false
13
13
  matrix:
14
- ruby: [ '3.0', '3.1', '3.2' ]
14
+ ruby: [ '3.0', '3.1', '3.2', '3.3', '3.4' ]
15
15
  os:
16
16
  - macOS-latest
17
17
  name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
@@ -11,7 +11,7 @@ jobs:
11
11
  strategy:
12
12
  fail-fast: false
13
13
  matrix:
14
- ruby: [ '3.0', '3.1', '3.2' ]
14
+ ruby: [ '3.0', '3.1', '3.2', '3.3', '3.4' ]
15
15
  os:
16
16
  - windows-latest
17
17
  name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
data/History.md CHANGED
@@ -2,7 +2,16 @@
2
2
 
3
3
  ### [Unreleased]
4
4
 
5
- ### 5.4.1
5
+ ### 5.4.4
6
+ - docs: Clarify README docs for template_name and templates (#1043)
7
+ - `out_elasticsearch_data_stream`: Avoid long worrying log line at info level (#1044)
8
+ - `out_elasticsearch_data_stream`: Support `id_key` and `remove_keys` (#1057)
9
+ - `out_elasticsearch`: Fix memory leaks when exception was raised frequently (#1065)
10
+
11
+ ### 5.4.3
12
+ - add data_stream_template\_use\_index\_patterns\_wildcard in elasticsearch\_data\_stream (#1040)
13
+
14
+ ### 5.4.2
6
15
  - in\_elasticsearch: Avoid to use deprecated endpoint for clear\_scroll (#1039)
7
16
 
8
17
  ### 5.4.1
data/README.md CHANGED
@@ -527,7 +527,7 @@ into same document with data1 as wanted and duplicated document is avoided.
527
527
 
528
528
  ### template_name
529
529
 
530
- The name of the template to define. If a template by the name given is already present, it will be left unchanged, unless [template_overwrite](#template_overwrite) is set, in which case the template will be updated.
530
+ The name of the index template to create on fluentd startup. If a template by the name given is already present, it will be left unchanged, unless [template_overwrite](#template_overwrite) is set, in which case the template will be updated.
531
531
 
532
532
  This parameter along with template_file allow the plugin to behave similarly to Logstash (it installs a template at creation time) so that raw records are available. See [https://github.com/uken/fluent-plugin-elasticsearch/issues/33](https://github.com/uken/fluent-plugin-elasticsearch/issues/33).
533
533
 
@@ -541,7 +541,7 @@ The path to the file containing the template to install.
541
541
 
542
542
  ### templates
543
543
 
544
- Specify index templates in form of hash. Can contain multiple templates.
544
+ Specify index templates (to be created on startup) in the form of a hash (accepts JSON dict). Can contain multiple templates.
545
545
 
546
546
  ```
547
547
  templates { "template_name_1": "path_to_template_1_file", "template_name_2": "path_to_template_2_file"}
@@ -1561,6 +1561,50 @@ Default value is `false`.
1561
1561
 
1562
1562
  **NOTE:** This parameter requests to install elasticsearch-xpack gem.
1563
1563
 
1564
+ ### data_stream_template_use_index_patterns_wildcard
1565
+
1566
+ Specify whether index patterns should include a wildcard (*) when creating an index template. This is particularly useful to prevent errors in scenarios where index templates are generated automatically, and multiple services with distinct suffixes are in use.
1567
+
1568
+ Default value is `true`.
1569
+
1570
+ Consider the following JSON error response when index patterns clash due to wildcard usage:
1571
+ ```json
1572
+ {
1573
+ "error": {
1574
+ "root_cause": [
1575
+ {
1576
+ "type": "illegal_argument_exception",
1577
+ "reason": "index template [eks-kube-apiserver] has index patterns [eks-kube-apiserver*] matching patterns from existing templates [eks-kube-apiserver-audit] with patterns (eks-kube-apiserver-audit => [eks-kube-apiserver-audit*]) that have the same priority [0], multiple index templates may not match during index creation, please use a different priority"
1578
+ }
1579
+ ],
1580
+ "type": "illegal_argument_exception",
1581
+ "reason": "index template [eks-kube-apiserver] has index patterns [eks-kube-apiserver*] matching patterns from existing templates [eks-kube-apiserver-audit] with patterns (eks-kube-apiserver-audit => [eks-kube-apiserver-audit*]) that have the same priority [0], multiple index templates may not match during index creation, please use a different priority"
1582
+ },
1583
+ "status": 400
1584
+ }
1585
+ ```
1586
+
1587
+ #### Usage Examples
1588
+
1589
+ When `data_stream_template_use_index_patterns_wildcard` is set to `true` (default):
1590
+
1591
+ ```
1592
+ data_stream_name: foo
1593
+ data_stream_template_use_index_patterns_wildcard: true
1594
+ ```
1595
+
1596
+ In this case, the resulting index patterns will be: `["foo*"]`
1597
+
1598
+ When `data_stream_template_use_index_patterns_wildcard` is set to `false`:
1599
+
1600
+ ```
1601
+ data_stream_name: foo
1602
+ data_stream_template_use_index_patterns_wildcard: false
1603
+ ```
1604
+
1605
+ The resulting index patterns will be: `["foo"]`
1606
+
1607
+
1564
1608
  ## Troubleshooting
1565
1609
 
1566
1610
  See [Troubleshooting document](README.Troubleshooting.md)
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'fluent-plugin-elasticsearch'
6
- s.version = '5.4.2'
6
+ s.version = '5.4.4'
7
7
  s.authors = ['diogo', 'pitr', 'Hiroshi Hatake']
8
8
  s.email = ['pitr.vern@gmail.com', 'me@diogoterror.com', 'cosmo0920.wp@gmail.com']
9
9
  s.description = %q{Elasticsearch output plugin for Fluent event collector}
@@ -883,11 +883,11 @@ EOC
883
883
  if split_request?(bulk_message, info)
884
884
  bulk_message.each do |info, msgs|
885
885
  send_bulk(msgs, tag, chunk, bulk_message_count[info], extracted_values, info, unpackedMsgArr[info]) unless msgs.empty?
886
+ ensure
886
887
  unpackedMsgArr[info].clear
887
888
  msgs.clear
888
889
  # Clear bulk_message_count for this info.
889
890
  bulk_message_count[info] = 0;
890
- next
891
891
  end
892
892
  end
893
893
 
@@ -907,7 +907,7 @@ EOC
907
907
 
908
908
  bulk_message.each do |info, msgs|
909
909
  send_bulk(msgs, tag, chunk, bulk_message_count[info], extracted_values, info, unpackedMsgArr[info]) unless msgs.empty?
910
-
910
+ ensure
911
911
  unpackedMsgArr[info].clear
912
912
  msgs.clear
913
913
  end
@@ -13,6 +13,7 @@ module Fluent::Plugin
13
13
  config_param :data_stream_template_name, :string, :default => nil
14
14
  config_param :data_stream_ilm_policy, :string, :default => nil
15
15
  config_param :data_stream_ilm_policy_overwrite, :bool, :default => false
16
+ config_param :data_stream_template_use_index_patterns_wildcard, :bool, :default => true
16
17
 
17
18
  # Elasticsearch 7.9 or later always support new style of index template.
18
19
  config_set_default :use_legacy_template, false
@@ -112,8 +113,9 @@ module Fluent::Plugin
112
113
 
113
114
  def create_index_template(datastream_name, template_name, ilm_name, host = nil)
114
115
  return if data_stream_exist?(datastream_name, host) or template_exists?(template_name, host)
116
+ wildcard = @data_stream_template_use_index_patterns_wildcard ? '*' : ''
115
117
  body = {
116
- "index_patterns" => ["#{datastream_name}*"],
118
+ "index_patterns" => ["#{datastream_name}#{wildcard}"],
117
119
  "data_stream" => {},
118
120
  "template" => {
119
121
  "settings" => {
@@ -140,7 +142,7 @@ module Fluent::Plugin
140
142
  response = client(host).indices.get_data_stream(params)
141
143
  return (not response.is_a?(TRANSPORT_CLASS::Transport::Errors::NotFound))
142
144
  rescue TRANSPORT_CLASS::Transport::Errors::NotFound => e
143
- log.info "Specified data stream does not exist. Will be created: <#{e}>"
145
+ log.info "Specified data stream does not exist. Will be created: <#{datastream_name}>"
144
146
  return false
145
147
  end
146
148
  end
@@ -217,6 +219,8 @@ module Fluent::Plugin
217
219
  data_stream_name = @data_stream_name
218
220
  data_stream_template_name = @data_stream_template_name
219
221
  data_stream_ilm_name = @data_stream_ilm_name
222
+ id_key = @id_key
223
+ remove_keys = @remove_keys
220
224
  host = nil
221
225
  if @use_placeholder
222
226
  host = if @hosts
@@ -255,7 +259,15 @@ module Fluent::Plugin
255
259
  unless record.has_key?("@timestamp")
256
260
  record.merge!({"@timestamp" => Time.at(time).iso8601(@time_precision)})
257
261
  end
258
- bulk_message = append_record_to_messages(CREATE_OP, {}, headers, record, bulk_message)
262
+
263
+ # meta variable to be appended in bulk_message
264
+ meta = {}
265
+ meta = {'_id' => record[id_key]} if id_key and record[id_key]
266
+
267
+ # Remove any key in remove_keys if defined
268
+ remove_keys.each { |key| record.delete(key) } if remove_keys
269
+
270
+ bulk_message = append_record_to_messages(CREATE_OP, meta, headers, record, bulk_message)
259
271
  rescue => e
260
272
  router.emit_error_event(tag, time, record, e)
261
273
  end
@@ -37,6 +37,10 @@ class TestElasticsearchIndexLifecycleManagement < Test::Unit::TestCase
37
37
  end
38
38
  end
39
39
 
40
+ def elasticsearch_miscellaneous_content_type?
41
+ Gem::Version.create(Elasticsearch::VERSION) >= Gem::Version.new("9.0.0")
42
+ end
43
+
40
44
  def ilm_existence_endpoint(policy_id)
41
45
  if Gem::Version.new(Elasticsearch::VERSION) >= Gem::Version.new("8.0.0")
42
46
  "_ilm/policy/#{policy_id}"
@@ -90,10 +94,20 @@ class TestElasticsearchIndexLifecycleManagement < Test::Unit::TestCase
90
94
  def test_create_ilm_policy
91
95
  stub_request(:get, "http://localhost:9200/#{ilm_creation_endpoint("fluent-policy")}").
92
96
  to_return(:status => 404, :body => "", :headers => {'x-elastic-product' => 'Elasticsearch'})
93
- stub_request(:put, "http://localhost:9200/#{ilm_creation_endpoint("fluent-policy")}").
94
- with(:body => "{\"policy\":{\"phases\":{\"hot\":{\"actions\":{\"rollover\":{\"max_size\":\"50gb\",\"max_age\":\"30d\"}}}}}}",
95
- :headers => {'Content-Type'=>'application/json'}).
96
- to_return(:status => 200, :body => "", :headers => {'x-elastic-product' => 'Elasticsearch'})
97
+ if elasticsearch_miscellaneous_content_type?
98
+ stub_request(:put, "http://localhost:9200/#{ilm_creation_endpoint("fluent-policy")}").
99
+ with(
100
+ body: "{\"policy\":{\"phases\":{\"hot\":{\"actions\":{\"rollover\":{\"max_size\":\"50gb\",\"max_age\":\"30d\"}}}}}}",
101
+ headers: {
102
+ 'Content-Type'=>'application/vnd.elasticsearch+json; compatible-with=9',
103
+ }).
104
+ to_return(:status => 200, :body => "", :headers => {'x-elastic-product' => 'Elasticsearch'})
105
+ else
106
+ stub_request(:put, "http://localhost:9200/#{ilm_creation_endpoint("fluent-policy")}").
107
+ with(:body => "{\"policy\":{\"phases\":{\"hot\":{\"actions\":{\"rollover\":{\"max_size\":\"50gb\",\"max_age\":\"30d\"}}}}}}",
108
+ :headers => {'Content-Type'=>'application/json'}).
109
+ to_return(:status => 200, :body => "", :headers => {'x-elastic-product' => 'Elasticsearch'})
110
+ end
97
111
  stub_elastic_info
98
112
  create_ilm_policy("fluent-policy")
99
113
 
@@ -65,6 +65,10 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
65
65
  Gem::Version.create(::TRANSPORT_CLASS::VERSION) >= Gem::Version.new("8.0.0")
66
66
  end
67
67
 
68
+ def elasticsearch_miscellaneous_content_type?
69
+ Gem::Version.create(Elasticsearch::VERSION) >= Gem::Version.new("9.0.0")
70
+ end
71
+
68
72
  def default_type_name
69
73
  Fluent::Plugin::ElasticsearchOutput::DEFAULT_TYPE_NAME
70
74
  end
@@ -3889,7 +3893,12 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
3889
3893
  def test_content_type_header
3890
3894
  stub_request(:head, "http://localhost:9200/").
3891
3895
  to_return(:status => 200, :body => "", :headers => {'x-elastic-product' => 'Elasticsearch'})
3892
- if Elasticsearch::VERSION >= "6.0.2"
3896
+
3897
+ if elasticsearch_miscellaneous_content_type?
3898
+ elastic_request = stub_request(:post, "http://localhost:9200/_bulk").
3899
+ with(headers: { "Content-Type" => "application/vnd.elasticsearch+x-ndjson; compatible-with=9" }).
3900
+ to_return(:status => 200, :body => "", :headers => {'x-elastic-product' => 'Elasticsearch'})
3901
+ elsif Elasticsearch::VERSION >= "6.0.2"
3893
3902
  elastic_request = stub_request(:post, "http://localhost:9200/_bulk").
3894
3903
  with(headers: { "Content-Type" => "application/x-ndjson" }).
3895
3904
  to_return(:status => 200, :body => "", :headers => {'x-elastic-product' => 'Elasticsearch'})
@@ -5005,7 +5014,8 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
5005
5014
  driver.feed(time.to_i, sample_record.merge({"pipeline_id" => pipeline_id}))
5006
5015
  end
5007
5016
  }
5008
- assert_equal("could not push logs to Elasticsearch cluster ({:host=>\"myhost-1\", :port=>9200, :scheme=>\"http\"}): [503] ", exception.message)
5017
+ params = {:host=> "myhost-1", :port=>9200, :scheme=>"http"}
5018
+ assert_equal("could not push logs to Elasticsearch cluster (#{params}): [503] ", exception.message)
5009
5019
  end
5010
5020
  end
5011
5021
 
@@ -19,6 +19,7 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
19
19
  @driver = nil
20
20
  log = Fluent::Engine.log
21
21
  log.out.logs.slice!(0, log.out.logs.length)
22
+ @bulk_meta = []
22
23
  @bulk_records = []
23
24
  end
24
25
 
@@ -34,6 +35,10 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
34
35
  '_ilm'.freeze
35
36
  end
36
37
 
38
+ def index_template_endpoint
39
+ '_index_template'.freeze
40
+ end
41
+
37
42
  def driver(conf='', es_version=elasticsearch_version.to_i, client_version=elasticsearch_version)
38
43
  # For request stub to detect compatibility.
39
44
  @es_version ||= es_version
@@ -83,6 +88,10 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
83
88
  {'message' => 'Sample record no timestamp'}
84
89
  end
85
90
 
91
+ def sample_record_with_hash
92
+ {'@timestamp' => SAMPLE_RECORD_TIMESTAMP, 'message' => 'Sample record', '_hash' => 'new_id_value'}
93
+ end
94
+
86
95
  RESPONSE_ACKNOWLEDGED = {"acknowledged": true}
87
96
  DUPLICATED_DATA_STREAM_EXCEPTION = {"error": {}, "status": 400}
88
97
  NONEXISTENT_DATA_STREAM_EXCEPTION = {"error": {}, "status": 404}
@@ -124,12 +133,15 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
124
133
  stub_request(:get, "#{url}/_index_template/#{name}").to_return(:status => [404, TRANSPORT_CLASS::Transport::Errors::NotFound], :headers => {'x-elastic-product' => 'Elasticsearch'})
125
134
  end
126
135
 
127
-
128
136
  def push_bulk_request(req_body)
129
137
  # bulk data must be pair of OP and records
130
138
  # {"create": {}}\nhttp://localhost:9200/_ilm/policy/foo_ilm_bar
131
139
  # {"@timestamp": ...}
132
140
  ops = req_body.split("\n")
141
+ @bulk_meta += ops.values_at(
142
+ * ops.each_index.select {|i| i.even? }
143
+ ).map{ |i| JSON.parse(i) }
144
+
133
145
  @bulk_records += ops.values_at(
134
146
  * ops.each_index.select {|i| i.odd? }
135
147
  ).map{ |i| JSON.parse(i) }
@@ -486,7 +498,8 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
486
498
  '@type' => ELASTIC_DATA_STREAM_TYPE,
487
499
  'data_stream_name' => 'foo',
488
500
  'data_stream_ilm_name' => "foo_ilm_policy",
489
- 'data_stream_template_name' => "foo_tpl"
501
+ 'data_stream_template_name' => "foo_tpl",
502
+ 'data_stream_template_use_index_patterns_wildcard' => false
490
503
  })
491
504
  assert_equal "foo", driver(conf).instance.data_stream_name
492
505
  end
@@ -556,6 +569,21 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
556
569
  assert_equal true, driver(config).instance.compression
557
570
  end
558
571
 
572
+ def test_configure_wildcard_usage
573
+ omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
574
+
575
+ config = %{
576
+ data_stream_name foo
577
+ data_stream_template_name foo_tpl
578
+ data_stream_ilm_name foo_ilm_policy
579
+ data_stream_template_use_index_patterns_wildcard false
580
+ }
581
+
582
+ stub_default
583
+
584
+ assert_equal false, driver(config).instance.data_stream_template_use_index_patterns_wildcard
585
+ end
586
+
559
587
  def test_check_compression_strategy
560
588
  omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
561
589
 
@@ -722,6 +750,72 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
722
750
  assert_equal "foo_policy", driver(conf).instance.data_stream_ilm_name
723
751
  end
724
752
 
753
+ def test_template_index_patterns_with_wildcard
754
+ omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
755
+
756
+ stub_existent_ilm?
757
+
758
+ stub_nonexistent_data_stream?
759
+ stub_data_stream
760
+
761
+ stub_nonexistent_template?("foo_template")
762
+ stub_request(:put, "http://localhost:9200/#{index_template_endpoint}/foo_template").with do |req|
763
+ # bulk data must be pair of OP and records
764
+ # {"create": {}}\nhttp://localhost:9200/_index_template//foo_template
765
+ # {"@timestamp": ...}
766
+ push_bulk_request(req.body)
767
+ end.to_return({:status => 200, :body => "{}", :headers => { 'Content-Type' => 'json', 'x-elastic-product' => 'Elasticsearch' } })
768
+
769
+ conf = config_element(
770
+ 'ROOT', '', {
771
+ '@type' => ELASTIC_DATA_STREAM_TYPE,
772
+ 'data_stream_name' => 'foo',
773
+ 'data_stream_ilm_name' => 'foo_ilm_policy',
774
+ 'data_stream_template_use_index_patterns_wildcard' => false
775
+ })
776
+
777
+ assert_nothing_raised {
778
+ driver(conf)
779
+ }
780
+
781
+ assert_requested(:put, "http://localhost:9200/#{index_template_endpoint}/foo_template",
782
+ body: '{"index_patterns":["foo"],"data_stream":{},"template":{"settings":{"index.lifecycle.name":"foo_ilm_policy"}}}',
783
+ times: 1)
784
+ end
785
+
786
+ def test_template_index_patterns_without_wildcard
787
+ omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
788
+
789
+ stub_existent_ilm?
790
+
791
+ stub_nonexistent_data_stream?
792
+ stub_data_stream
793
+
794
+ stub_nonexistent_template?("foo_template")
795
+ stub_request(:put, "http://localhost:9200/#{index_template_endpoint}/foo_template").with do |req|
796
+ # bulk data must be pair of OP and records
797
+ # {"create": {}}\nhttp://localhost:9200/_index_template//foo_template
798
+ # {"@timestamp": ...}
799
+ push_bulk_request(req.body)
800
+ end.to_return({:status => 200, :body => "{}", :headers => { 'Content-Type' => 'json', 'x-elastic-product' => 'Elasticsearch' } })
801
+
802
+ conf = config_element(
803
+ 'ROOT', '', {
804
+ '@type' => ELASTIC_DATA_STREAM_TYPE,
805
+ 'data_stream_name' => 'foo',
806
+ 'data_stream_ilm_name' => 'foo_ilm_policy',
807
+ 'data_stream_template_use_index_patterns_wildcard' => true
808
+ })
809
+
810
+ assert_nothing_raised {
811
+ driver(conf)
812
+ }
813
+
814
+ assert_requested(:put, "http://localhost:9200/#{index_template_endpoint}/foo_template",
815
+ body: '{"index_patterns":["foo*"],"data_stream":{},"template":{"settings":{"index.lifecycle.name":"foo_ilm_policy"}}}',
816
+ times: 1)
817
+ end
818
+
725
819
  def test_placeholder
726
820
  omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
727
821
 
@@ -1111,4 +1205,73 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
1111
1205
  assert_equal 1, @bulk_records.length
1112
1206
  assert(@bulk_records[0].has_key?('@timestamp'))
1113
1207
  end
1208
+
1209
+ def test_id_key_if_value_present_in_record
1210
+ omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
1211
+
1212
+ stub_default
1213
+ stub_bulk_feed
1214
+ conf = config_element(
1215
+ 'ROOT', '', {
1216
+ '@type' => ELASTIC_DATA_STREAM_TYPE,
1217
+ 'data_stream_name' => 'foo',
1218
+ 'data_stream_ilm_name' => 'foo_ilm_policy',
1219
+ 'data_stream_template_name' => 'foo_tpl',
1220
+ 'id_key' => '_hash'
1221
+ })
1222
+ driver(conf).run(default_tag: 'test') do
1223
+ driver.feed(sample_record_with_hash)
1224
+ end
1225
+ assert_equal 1, @bulk_records.length
1226
+ assert_equal 1, @bulk_meta.length
1227
+ assert(@bulk_meta[0].has_key?('create'))
1228
+ assert(@bulk_meta[0]['create'].has_key?('_id'))
1229
+ assert_equal 'new_id_value', @bulk_meta[0]['create']['_id']
1230
+
1231
+ end
1232
+
1233
+ def test_id_key_if_value_not_present_in_record
1234
+ omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
1235
+
1236
+ stub_default
1237
+ stub_bulk_feed
1238
+ conf = config_element(
1239
+ 'ROOT', '', {
1240
+ '@type' => ELASTIC_DATA_STREAM_TYPE,
1241
+ 'data_stream_name' => 'foo',
1242
+ 'data_stream_ilm_name' => 'foo_ilm_policy',
1243
+ 'data_stream_template_name' => 'foo_tpl',
1244
+ 'id_key' => '_hash'
1245
+ })
1246
+ driver(conf).run(default_tag: 'test') do
1247
+ driver.feed(sample_record)
1248
+ end
1249
+ assert_equal 1, @bulk_records.length
1250
+ assert_equal 1, @bulk_meta.length
1251
+ assert(@bulk_meta[0].has_key?('create'))
1252
+ assert_false(@bulk_meta[0]['create'].has_key?('_id'))
1253
+
1254
+ end
1255
+
1256
+ def test_remove_keys_if_key_present_in_record
1257
+ omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
1258
+
1259
+ stub_default
1260
+ stub_bulk_feed
1261
+ conf = config_element(
1262
+ 'ROOT', '', {
1263
+ '@type' => ELASTIC_DATA_STREAM_TYPE,
1264
+ 'data_stream_name' => 'foo',
1265
+ 'data_stream_ilm_name' => 'foo_ilm_policy',
1266
+ 'data_stream_template_name' => 'foo_tpl',
1267
+ 'remove_keys' => '_hash, message'
1268
+ })
1269
+ driver(conf).run(default_tag: 'test') do
1270
+ driver.feed(sample_record_with_hash)
1271
+ end
1272
+ assert_equal 1, @bulk_records.length
1273
+ assert_false(@bulk_records[0].has_key?('_hash'))
1274
+ assert_false(@bulk_records[0].has_key?('message'))
1275
+
1276
+ end
1114
1277
  end
@@ -50,6 +50,10 @@ class ElasticsearchOutputDynamic < Test::Unit::TestCase
50
50
  Gem::Version.create(::TRANSPORT_CLASS::VERSION) >= Gem::Version.new("8.0.0")
51
51
  end
52
52
 
53
+ def elasticsearch_miscellaneous_content_type?
54
+ Gem::Version.create(Elasticsearch::VERSION) >= Gem::Version.new("9.0.0")
55
+ end
56
+
53
57
  def default_type_name
54
58
  Fluent::Plugin::ElasticsearchOutput::DEFAULT_TYPE_NAME
55
59
  end
@@ -388,7 +392,11 @@ class ElasticsearchOutputDynamic < Test::Unit::TestCase
388
392
  def test_content_type_header
389
393
  stub_request(:head, "http://localhost:9200/").
390
394
  to_return(:status => 200, :body => "", :headers => {'x-elastic-product' => 'Elasticsearch'})
391
- if Elasticsearch::VERSION >= "6.0.2"
395
+ if elasticsearch_miscellaneous_content_type?
396
+ elastic_request = stub_request(:post, "http://localhost:9200/_bulk").
397
+ with(headers: { "Content-Type" => "application/vnd.elasticsearch+x-ndjson; compatible-with=9" }).
398
+ to_return(:status => 200, :body => "", :headers => {'x-elastic-product' => 'Elasticsearch'})
399
+ elsif Elasticsearch::VERSION >= "6.0.2"
392
400
  elastic_request = stub_request(:post, "http://localhost:9200/_bulk").
393
401
  with(headers: { "Content-Type" => "application/x-ndjson"}).
394
402
  to_return(:status => 200, :body => "", :headers => {'x-elastic-product' => 'Elasticsearch'})
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.4.2
4
+ version: 5.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - diogo
8
8
  - pitr
9
9
  - Hiroshi Hatake
10
- autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2023-12-05 00:00:00.000000000 Z
12
+ date: 1980-01-02 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: fluentd
@@ -236,7 +235,6 @@ licenses:
236
235
  - Apache-2.0
237
236
  metadata:
238
237
  changelog_uri: https://github.com/uken/fluent-plugin-elasticsearch/blob/master/History.md
239
- post_install_message:
240
238
  rdoc_options: []
241
239
  require_paths:
242
240
  - lib
@@ -251,8 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
251
249
  - !ruby/object:Gem::Version
252
250
  version: '0'
253
251
  requirements: []
254
- rubygems_version: 3.4.6
255
- signing_key:
252
+ rubygems_version: 3.6.7
256
253
  specification_version: 4
257
254
  summary: Elasticsearch output plugin for Fluent event collector
258
255
  test_files: