fluent-plugin-elasticsearch 2.7.0 → 2.8.0

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: 6c45d1357073cd62a59770c94e106099a367b504e4fcc306868a51cad18b76a1
4
- data.tar.gz: ffeb4647996e9da73b432d7b9baae5766e4973801b7ee59e097e26bf927aff38
3
+ metadata.gz: bdf35ea1b2e3e85372e0f5af8febdc9920e38090053b7e818d714d32d9df6428
4
+ data.tar.gz: f43d98b89ee686f14bfe3b544f929cefc2b50d28d064cd9c40a3502aadf0774b
5
5
  SHA512:
6
- metadata.gz: 82bc86a0116891984e93587d77f39fcd8e86112a6688bcc10e52b99114a0d98bcade90643083815f0929533802cb956ac1f3aa8fa150cf7bba4e2d55094fb9f1
7
- data.tar.gz: f74034825181ddfa92968de7eaa041ff35e17797a5aa496e396f645bae25f57ee5b9eff5cc86bd1c82ea0fc306f5991232fef5ff927d06130b5f61229ec40d29
6
+ metadata.gz: 8d4b5829f6bfcc13d8e25a60fca57422068a1449376690776dbe6623346ae058226563b215ad4926b97680b632515516309e6d50414d2d030e4d559359ae077a
7
+ data.tar.gz: 763d3a4838093c99d92a2b4f3382335ff95ddd4e20d0c4a2378a42b3cb830a4c6654501662920035f9299a28e492372d5671792f0098f9f9e4566035d24533af
data/History.md CHANGED
@@ -4,6 +4,10 @@
4
4
  - Log ES response errors (#230)
5
5
  - Use latest elasticsearch-ruby (#240)
6
6
 
7
+ ### 2.8.0
8
+ - Remove outdated generating hash id support module (#373)
9
+ - Check Elasticsearch major version (#371)
10
+
7
11
  ### 2.7.0
8
12
  - Configureable content type (#367)
9
13
 
@@ -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 = '2.7.0'
6
+ s.version = '2.8.0'
7
7
  s.authors = ['diogo', 'pitr']
8
8
  s.email = ['pitr.vern@gmail.com', 'me@diogoterror.com']
9
9
  s.description = %q{Elasticsearch output plugin for Fluent event collector}
@@ -13,7 +13,6 @@ require 'fluent/plugin/output'
13
13
  require_relative 'elasticsearch_constants'
14
14
  require_relative 'elasticsearch_error_handler'
15
15
  require_relative 'elasticsearch_index_template'
16
- require_relative 'generate_hash_id_support'
17
16
 
18
17
  module Fluent::Plugin
19
18
  class ElasticsearchOutput < Output
@@ -24,6 +23,8 @@ module Fluent::Plugin
24
23
  Fluent::Plugin.register_output('elasticsearch', self)
25
24
 
26
25
  DEFAULT_BUFFER_TYPE = "memory"
26
+ DEFAULT_ELASTICSEARCH_VERSION = 5 # For compatibility.
27
+ DEFAULT_TYPE_NAME = "_doc".freeze
27
28
 
28
29
  config_param :host, :string, :default => 'localhost'
29
30
  config_param :port, :integer, :default => 9200
@@ -33,7 +34,10 @@ module Fluent::Plugin
33
34
  config_param :scheme, :string, :default => 'http'
34
35
  config_param :hosts, :string, :default => nil
35
36
  config_param :target_index_key, :string, :default => nil
36
- config_param :target_type_key, :string, :default => nil
37
+ config_param :target_type_key, :string, :default => nil,
38
+ :deprecated => <<EOC
39
+ Elasticsearch 7.x or above will ignore this config. Please use fixed type_name instead.
40
+ EOC
37
41
  config_param :time_key_format, :string, :default => nil
38
42
  config_param :time_precision, :integer, :default => 9
39
43
  config_param :include_timestamp, :bool, :default => false
@@ -42,7 +46,7 @@ module Fluent::Plugin
42
46
  config_param :logstash_prefix_separator, :string, :default => '-'
43
47
  config_param :logstash_dateformat, :string, :default => "%Y.%m.%d"
44
48
  config_param :utc_index, :bool, :default => true
45
- config_param :type_name, :string, :default => "fluentd"
49
+ config_param :type_name, :string, :default => DEFAULT_TYPE_NAME
46
50
  config_param :index_name, :string, :default => "fluentd"
47
51
  config_param :id_key, :string, :default => nil
48
52
  config_param :write_operation, :string, :default => "index"
@@ -84,7 +88,6 @@ module Fluent::Plugin
84
88
  end
85
89
 
86
90
  include Fluent::ElasticsearchIndexTemplate
87
- include Fluent::Plugin::GenerateHashIdSupport
88
91
  include Fluent::Plugin::ElasticsearchConstants
89
92
 
90
93
  def initialize
@@ -151,6 +154,17 @@ module Fluent::Plugin
151
154
  log_level = conf['@log_level'] || conf['log_level']
152
155
  log.warn "Consider to specify log_level with @log_level." unless log_level
153
156
  end
157
+
158
+ @last_seen_major_version = detect_es_major_version rescue DEFAULT_ELASTICSEARCH_VERSION
159
+ if @last_seen_major_version >= 7 && @type_name != DEFAULT_TYPE_NAME
160
+ log.warn "Detected ES 7.x or above: `_doc` will be used as the document `_type`."
161
+ @type_name = '_doc'.freeze
162
+ end
163
+ end
164
+
165
+ def detect_es_major_version
166
+ @_es_info ||= client.info
167
+ @_es_info["version"]["number"].to_i
154
168
  end
155
169
 
156
170
  def convert_compat_id_key(key)
@@ -356,6 +370,7 @@ module Fluent::Plugin
356
370
  tag = chunk.metadata.tag
357
371
  logstash_prefix, index_name, type_name = expand_placeholders(chunk.metadata)
358
372
  @error = Fluent::Plugin::ElasticsearchErrorHandler.new(self)
373
+ @last_seen_major_version = detect_es_major_version rescue DEFAULT_ELASTICSEARCH_VERSION
359
374
 
360
375
  chunk.msgpack_each do |time, record|
361
376
  @error.records += 1
@@ -404,8 +419,20 @@ module Fluent::Plugin
404
419
  target_type_parent, target_type_child_key = @target_type_key ? get_parent_of(record, @target_type_key) : nil
405
420
  if target_type_parent && target_type_parent[target_type_child_key]
406
421
  target_type = target_type_parent.delete(target_type_child_key)
422
+ if @last_seen_major_version == 6
423
+ log.warn "Detected ES 6.x: `@type_name` will be used as the document `_type`."
424
+ target_type = type_name
425
+ elsif @last_seen_major_version >= 7
426
+ log.warn "Detected ES 7.x or above: `_doc` will be used as the document `_type`."
427
+ target_type = '_doc'.freeze
428
+ end
407
429
  else
408
- target_type = type_name
430
+ if @last_seen_major_version >= 7 && target_type != DEFAULT_TYPE_NAME
431
+ log.warn "Detected ES 7.x or above: `_doc` will be used as the document `_type`."
432
+ target_type = '_doc'.freeze
433
+ else
434
+ target_type = type_name
435
+ end
409
436
  end
410
437
 
411
438
  meta.clear
@@ -453,6 +480,7 @@ module Fluent::Plugin
453
480
  if retries < 2
454
481
  retries += 1
455
482
  @_es = nil
483
+ @_es_info = nil
456
484
  log.warn "Could not push logs to Elasticsearch, resetting connection and trying again. #{e.message}"
457
485
  sleep 2**retries
458
486
  retry
@@ -460,6 +488,7 @@ module Fluent::Plugin
460
488
  raise ConnectionFailure, "Could not push logs to Elasticsearch after #{retries} retries. #{e.message}"
461
489
  rescue Exception
462
490
  @_es = nil if @reconnect_on_error
491
+ @_es_info = nil if @reconnect_on_error
463
492
  raise
464
493
  end
465
494
  end
@@ -13,8 +13,6 @@ module Fluent::Plugin
13
13
  DYNAMIC_PARAM_NAMES = %W[hosts host port include_timestamp logstash_format logstash_prefix logstash_dateformat time_key utc_index index_name tag_key type_name id_key parent_key routing_key write_operation]
14
14
  DYNAMIC_PARAM_SYMBOLS = DYNAMIC_PARAM_NAMES.map { |n| "@#{n}".to_sym }
15
15
 
16
- include Fluent::Plugin::GenerateHashIdSupport
17
-
18
16
  attr_reader :dynamic_config
19
17
 
20
18
  def configure(conf)
@@ -19,7 +19,14 @@ class ElasticsearchOutput < Test::Unit::TestCase
19
19
  log.out.logs.slice!(0, log.out.logs.length)
20
20
  end
21
21
 
22
- def driver(conf='')
22
+ def driver(conf='', es_version=5)
23
+ # For request stub to detect compatibility.
24
+ @es_version ||= es_version
25
+ Fluent::Plugin::ElasticsearchOutput.module_eval(<<-CODE)
26
+ def detect_es_major_version
27
+ #{@es_version}
28
+ end
29
+ CODE
23
30
  @driver ||= Fluent::Test::Driver::Output.new(Fluent::Plugin::ElasticsearchOutput) {
24
31
  # v0.12's test driver assume format definition. This simulates ObjectBufferedOutput format
25
32
  if !defined?(Fluent::Plugin::Output)
@@ -232,6 +239,14 @@ class ElasticsearchOutput < Test::Unit::TestCase
232
239
  }
233
240
  end
234
241
 
242
+ test 'Detected Elasticsearch 7' do
243
+ config = %{
244
+ type_name changed
245
+ }
246
+ instance = driver(config, 7).instance
247
+ assert_equal '_doc', instance.type_name
248
+ end
249
+
235
250
  test 'lack of tag in chunk_keys' do
236
251
  assert_raise_message(/'tag' in chunk_keys is required./) do
237
252
  driver(Fluent::Config::Element.new(
@@ -252,21 +267,6 @@ class ElasticsearchOutput < Test::Unit::TestCase
252
267
  end
253
268
  end
254
269
 
255
- test 'with invaild generate id config' do
256
- assert_raise_message(/Use bundled filter-elasticsearch-genid instead./) do
257
- driver.configure(Fluent::Config::Element.new(
258
- 'ROOT', '', {
259
- '@type' => 'elasticsearch',
260
- 'id_key' =>'id_mismatch',
261
- }, [
262
- Fluent::Config::Element.new('hash', '', {
263
- 'hash_id_key' => '_hash',
264
- }, [])
265
- ]
266
- ))
267
- end
268
- end
269
-
270
270
  def test_template_already_present
271
271
  config = %{
272
272
  host logs.google.com
@@ -665,7 +665,7 @@ class ElasticsearchOutput < Test::Unit::TestCase
665
665
  driver.run(default_tag: 'test') do
666
666
  driver.feed(sample_record)
667
667
  end
668
- assert_equal('fluentd', index_cmds.first['index']['_type'])
668
+ assert_equal('_doc', index_cmds.first['index']['_type'])
669
669
  end
670
670
 
671
671
  def test_writes_to_speficied_index
@@ -678,27 +678,6 @@ class ElasticsearchOutput < Test::Unit::TestCase
678
678
  assert_equal('myindex', index_cmds.first['index']['_index'])
679
679
  end
680
680
 
681
- class AdditionalHashIdMechanismTest < self
682
- data("default" => {"hash_id_key" => '_id'},
683
- "custom hash_id_key" => {"hash_id_key" => '_hash_id'},
684
- )
685
- def test_writes_with_genrate_hash(data)
686
- assert_raise_message(/Use bundled filter-elasticsearch-genid instead./) do
687
- driver.configure(Fluent::Config::Element.new(
688
- 'ROOT', '', {
689
- '@type' => 'elasticsearch',
690
- 'id_key' => data["hash_id_key"],
691
- }, [
692
- Fluent::Config::Element.new('hash', '', {
693
- 'keys' => ['request_id'],
694
- 'hash_id_key' => data["hash_id_key"],
695
- }, [])
696
- ]
697
- ))
698
- end
699
- end
700
- end
701
-
702
681
  class IndexNamePlaceholdersTest < self
703
682
  def test_writes_to_speficied_index_with_tag_placeholder
704
683
  driver.configure("index_name myindex.${tag}\n")
@@ -836,35 +815,46 @@ class ElasticsearchOutput < Test::Unit::TestCase
836
815
  assert_equal(logstash_index, index_cmds.first['index']['_index'])
837
816
  end
838
817
 
839
- def test_writes_to_speficied_type
840
- driver.configure("type_name mytype\n")
818
+ data("border" => {"es_version" => 6, "_type" => "mytype"},
819
+ "fixed_behavior"=> {"es_version" => 7, "_type" => "_doc"},
820
+ )
821
+ def test_writes_to_speficied_type(data)
822
+ driver('', data["es_version"]).configure("type_name mytype\n")
841
823
  stub_elastic_ping
842
824
  stub_elastic
843
825
  driver.run(default_tag: 'test') do
844
826
  driver.feed(sample_record)
845
827
  end
846
- assert_equal('mytype', index_cmds.first['index']['_type'])
828
+ assert_equal(data['_type'], index_cmds.first['index']['_type'])
847
829
  end
848
830
 
849
- def test_writes_to_speficied_type_with_placeholders
850
- driver.configure("type_name mytype.${tag}\n")
831
+ data("border" => {"es_version" => 6, "_type" => "mytype.test"},
832
+ "fixed_behavior"=> {"es_version" => 7, "_type" => "_doc"},
833
+ )
834
+ def test_writes_to_speficied_type_with_placeholders(data)
835
+ driver('', data["es_version"]).configure("type_name mytype.${tag}\n")
851
836
  stub_elastic_ping
852
837
  stub_elastic
853
838
  driver.run(default_tag: 'test') do
854
839
  driver.feed(sample_record)
855
840
  end
856
- assert_equal('mytype.test', index_cmds.first['index']['_type'])
841
+ assert_equal(data['_type'], index_cmds.first['index']['_type'])
857
842
  end
858
843
 
859
- def test_writes_to_target_type_key
860
- driver.configure("target_type_key @target_type\n")
844
+ data("old" => {"es_version" => 2, "_type" => "local-override"},
845
+ "old_behavior" => {"es_version" => 5, "_type" => "local-override"},
846
+ "border" => {"es_version" => 6, "_type" => "_doc"},
847
+ "fixed_behavior"=> {"es_version" => 7, "_type" => "_doc"},
848
+ )
849
+ def test_writes_to_target_type_key(data)
850
+ driver('', data["es_version"]).configure("target_type_key @target_type\n")
861
851
  stub_elastic_ping
862
852
  stub_elastic
863
853
  record = sample_record.clone
864
854
  driver.run(default_tag: 'test') do
865
855
  driver.feed(sample_record.merge('@target_type' => 'local-override'))
866
856
  end
867
- assert_equal('local-override', index_cmds.first['index']['_type'])
857
+ assert_equal(data["_type"], index_cmds.first['index']['_type'])
868
858
  assert_nil(index_cmds[1]['@target_type'])
869
859
  end
870
860
 
@@ -875,7 +865,7 @@ class ElasticsearchOutput < Test::Unit::TestCase
875
865
  driver.run(default_tag: 'test') do
876
866
  driver.feed(sample_record)
877
867
  end
878
- assert_equal('fluentd', index_cmds.first['index']['_type'])
868
+ assert_equal('_doc', index_cmds.first['index']['_type'])
879
869
  end
880
870
 
881
871
  def test_writes_to_target_type_key_fallack_to_type_name
@@ -889,8 +879,13 @@ class ElasticsearchOutput < Test::Unit::TestCase
889
879
  assert_equal('mytype', index_cmds.first['index']['_type'])
890
880
  end
891
881
 
892
- def test_writes_to_target_type_key_nested
893
- driver.configure("target_type_key kubernetes.labels.log_type\n")
882
+ data("old" => {"es_version" => 2, "_type" => "local-override"},
883
+ "old_behavior" => {"es_version" => 5, "_type" => "local-override"},
884
+ "border" => {"es_version" => 6, "_type" => "_doc"},
885
+ "fixed_behavior"=> {"es_version" => 7, "_type" => "_doc"},
886
+ )
887
+ def test_writes_to_target_type_key_nested(data)
888
+ driver('', data["es_version"]).configure("target_type_key kubernetes.labels.log_type\n")
894
889
  stub_elastic_ping
895
890
  stub_elastic
896
891
  driver.run(default_tag: 'test') do
@@ -900,7 +895,7 @@ class ElasticsearchOutput < Test::Unit::TestCase
900
895
  }
901
896
  }))
902
897
  end
903
- assert_equal('local-override', index_cmds.first['index']['_type'])
898
+ assert_equal(data["_type"], index_cmds.first['index']['_type'])
904
899
  assert_nil(index_cmds[1]['kubernetes']['labels']['log_type'])
905
900
  end
906
901
 
@@ -915,7 +910,7 @@ class ElasticsearchOutput < Test::Unit::TestCase
915
910
  }
916
911
  }))
917
912
  end
918
- assert_equal('fluentd', index_cmds.first['index']['_type'])
913
+ assert_equal('_doc', index_cmds.first['index']['_type'])
919
914
  end
920
915
 
921
916
  def test_writes_to_speficied_host
@@ -16,7 +16,14 @@ class ElasticsearchOutputDynamic < Test::Unit::TestCase
16
16
  @driver = nil
17
17
  end
18
18
 
19
- def driver(conf='')
19
+ def driver(conf='', es_version=5)
20
+ # For request stub to detect compatibility.
21
+ @es_version ||= es_version
22
+ Fluent::Plugin::ElasticsearchOutputDynamic.module_eval(<<-CODE)
23
+ def detect_es_major_version
24
+ #{@es_version}
25
+ end
26
+ CODE
20
27
  @driver ||= Fluent::Test::Driver::Output.new(Fluent::Plugin::ElasticsearchOutputDynamic) {
21
28
  # v0.12's test driver assume format definition. This simulates ObjectBufferedOutput format
22
29
  if !defined?(Fluent::Plugin::Output)
@@ -105,6 +112,14 @@ class ElasticsearchOutputDynamic < Test::Unit::TestCase
105
112
  }
106
113
  end
107
114
 
115
+ test 'Detected Elasticsearch 7' do
116
+ config = %{
117
+ type_name changed
118
+ }
119
+ instance = driver(config, 7).instance
120
+ assert_equal '_doc', instance.type_name
121
+ end
122
+
108
123
  def test_defaults
109
124
  config = %{
110
125
  host logs.google.com
@@ -260,7 +275,7 @@ class ElasticsearchOutputDynamic < Test::Unit::TestCase
260
275
  driver.run(default_tag: 'test') do
261
276
  driver.feed(sample_record)
262
277
  end
263
- assert_equal('fluentd', index_cmds.first['index']['_type'])
278
+ assert_equal('_doc', index_cmds.first['index']['_type'])
264
279
  end
265
280
 
266
281
  def test_writes_to_specified_index
@@ -343,27 +358,6 @@ class ElasticsearchOutputDynamic < Test::Unit::TestCase
343
358
  assert_equal(2000, total)
344
359
  end
345
360
 
346
- class AdditionalHashIdMechanismTest < self
347
- data("default" => {"hash_id_key" => '_id'},
348
- "custom hash_id_key" => {"hash_id_key" => '_hash_id'},
349
- )
350
- def test_writes_with_genrate_hash(data)
351
- assert_raise_message(/Use bundled filter-elasticsearch-genid instead./) do
352
- driver.configure(Fluent::Config::Element.new(
353
- 'ROOT', '', {
354
- '@type' => 'elasticsearch',
355
- 'id_key' => data["hash_id_key"],
356
- }, [
357
- Fluent::Config::Element.new('hash', '', {
358
- 'keys' => ['request_id'],
359
- 'hash_id_key' => data["hash_id_key"],
360
- }, [])
361
- ]
362
- ))
363
- end
364
- end
365
- end
366
-
367
361
  def test_makes_bulk_request
368
362
  stub_elastic_ping
369
363
  stub_elastic
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-elasticsearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - diogo
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-02-26 00:00:00.000000000 Z
12
+ date: 2018-03-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fluentd
@@ -148,7 +148,6 @@ files:
148
148
  - lib/fluent/plugin/elasticsearch_error_handler.rb
149
149
  - lib/fluent/plugin/elasticsearch_index_template.rb
150
150
  - lib/fluent/plugin/filter_elasticsearch_genid.rb
151
- - lib/fluent/plugin/generate_hash_id_support.rb
152
151
  - lib/fluent/plugin/out_elasticsearch.rb
153
152
  - lib/fluent/plugin/out_elasticsearch_dynamic.rb
154
153
  - test/helper.rb
@@ -1,24 +0,0 @@
1
- require 'securerandom'
2
- require 'base64'
3
-
4
- module Fluent
5
- module Plugin
6
- module GenerateHashIdSupport
7
- def self.included(klass)
8
- klass.instance_eval {
9
- config_section :hash, param_name: :hash_config, required: false, multi: false do
10
- config_param :hash_id_key, :string, default: '_hash',
11
- obsoleted: "Use bundled filter-elasticsearch-genid instead."
12
- end
13
- }
14
- end
15
-
16
- def generate_hash_id_key(record)
17
- s = ""
18
- s += Base64.strict_encode64(SecureRandom.uuid)
19
- record[@hash_config.hash_id_key] = s
20
- record
21
- end
22
- end
23
- end
24
- end