fluent-plugin-elasticsearch 4.0.7 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/issue-auto-closer.yml +12 -0
- data/.github/workflows/linux.yml +26 -0
- data/.github/workflows/macos.yml +26 -0
- data/.github/workflows/windows.yml +26 -0
- data/History.md +25 -0
- data/README.ElasticsearchGenID.md +116 -0
- data/README.md +78 -3
- data/fluent-plugin-elasticsearch.gemspec +1 -1
- data/lib/fluent/plugin/elasticsearch_fallback_selector.rb +9 -0
- data/lib/fluent/plugin/elasticsearch_tls.rb +3 -3
- data/lib/fluent/plugin/filter_elasticsearch_genid.rb +52 -0
- data/lib/fluent/plugin/out_elasticsearch.rb +68 -31
- data/lib/fluent/plugin/out_elasticsearch_dynamic.rb +6 -4
- data/test/plugin/test_elasticsearch_fallback_selector.rb +73 -0
- data/test/plugin/test_elasticsearch_tls.rb +2 -2
- data/test/plugin/test_filter_elasticsearch_genid.rb +171 -0
- data/test/plugin/test_out_elasticsearch.rb +408 -5
- data/test/plugin/test_out_elasticsearch_dynamic.rb +21 -3
- metadata +10 -2
@@ -7,6 +7,13 @@ module Fluent::Plugin
|
|
7
7
|
Fluent::Plugin.register_filter('elasticsearch_genid', self)
|
8
8
|
|
9
9
|
config_param :hash_id_key, :string, :default => '_hash'
|
10
|
+
config_param :include_tag_in_seed, :bool, :default => false
|
11
|
+
config_param :include_time_in_seed, :bool, :default => false
|
12
|
+
config_param :use_record_as_seed, :bool, :default => false
|
13
|
+
config_param :use_entire_record, :bool, :default => false
|
14
|
+
config_param :record_keys, :array, :default => []
|
15
|
+
config_param :separator, :string, :default => '_'
|
16
|
+
config_param :hash_type, :enum, list: [:md5, :sha1, :sha256, :sha512], :default => :sha1
|
10
17
|
|
11
18
|
def initialize
|
12
19
|
super
|
@@ -14,12 +21,57 @@ module Fluent::Plugin
|
|
14
21
|
|
15
22
|
def configure(conf)
|
16
23
|
super
|
24
|
+
|
25
|
+
if !@use_entire_record
|
26
|
+
if @record_keys.empty? && @use_record_as_seed
|
27
|
+
raise Fluent::ConfigError, "When using record as hash seed, users must specify `record_keys`."
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
if @use_record_as_seed
|
32
|
+
class << self
|
33
|
+
alias_method :filter, :filter_seed_as_record
|
34
|
+
end
|
35
|
+
else
|
36
|
+
class << self
|
37
|
+
alias_method :filter, :filter_simple
|
38
|
+
end
|
39
|
+
end
|
17
40
|
end
|
18
41
|
|
19
42
|
def filter(tag, time, record)
|
43
|
+
# for safety.
|
44
|
+
end
|
45
|
+
|
46
|
+
def filter_simple(tag, time, record)
|
20
47
|
record[@hash_id_key] = Base64.strict_encode64(SecureRandom.uuid)
|
21
48
|
record
|
22
49
|
end
|
23
50
|
|
51
|
+
def filter_seed_as_record(tag, time, record)
|
52
|
+
seed = ""
|
53
|
+
seed += tag + separator if @include_tag_in_seed
|
54
|
+
seed += time.to_s + separator if @include_time_in_seed
|
55
|
+
if @use_entire_record
|
56
|
+
record.each {|k,v| seed += "|#{k}|#{v}"}
|
57
|
+
else
|
58
|
+
seed += record_keys.map {|k| record[k]}.join(separator)
|
59
|
+
end
|
60
|
+
record[@hash_id_key] = Base64.strict_encode64(encode_hash(@hash_type, seed))
|
61
|
+
record
|
62
|
+
end
|
63
|
+
|
64
|
+
def encode_hash(type, seed)
|
65
|
+
case type
|
66
|
+
when :md5
|
67
|
+
Digest::MD5.digest(seed)
|
68
|
+
when :sha1
|
69
|
+
Digest::SHA1.digest(seed)
|
70
|
+
when :sha256
|
71
|
+
Digest::SHA256.digest(seed)
|
72
|
+
when :sha512
|
73
|
+
Digest::SHA512.digest(seed)
|
74
|
+
end
|
75
|
+
end
|
24
76
|
end
|
25
77
|
end
|
@@ -25,6 +25,7 @@ require_relative 'elasticsearch_error_handler'
|
|
25
25
|
require_relative 'elasticsearch_index_template'
|
26
26
|
require_relative 'elasticsearch_index_lifecycle_management'
|
27
27
|
require_relative 'elasticsearch_tls'
|
28
|
+
require_relative 'elasticsearch_fallback_selector'
|
28
29
|
begin
|
29
30
|
require_relative 'oj_serializer'
|
30
31
|
rescue LoadError
|
@@ -55,6 +56,7 @@ module Fluent::Plugin
|
|
55
56
|
attr_reader :alias_indexes
|
56
57
|
attr_reader :template_names
|
57
58
|
attr_reader :ssl_version_options
|
59
|
+
attr_reader :compressable_connection
|
58
60
|
|
59
61
|
helpers :event_emitter, :compat_parameters, :record_accessor, :timer
|
60
62
|
|
@@ -89,6 +91,7 @@ EOC
|
|
89
91
|
config_param :logstash_dateformat, :string, :default => "%Y.%m.%d"
|
90
92
|
config_param :utc_index, :bool, :default => true
|
91
93
|
config_param :type_name, :string, :default => DEFAULT_TYPE_NAME
|
94
|
+
config_param :suppress_type_name, :bool, :default => false
|
92
95
|
config_param :index_name, :string, :default => "fluentd"
|
93
96
|
config_param :id_key, :string, :default => nil
|
94
97
|
config_param :write_operation, :string, :default => "index"
|
@@ -135,6 +138,7 @@ EOC
|
|
135
138
|
config_param :with_transporter_log, :bool, :default => false
|
136
139
|
config_param :emit_error_for_missing_id, :bool, :default => false
|
137
140
|
config_param :sniffer_class_name, :string, :default => nil
|
141
|
+
config_param :selector_class_name, :string, :default => nil
|
138
142
|
config_param :reload_after, :integer, :default => DEFAULT_RELOAD_AFTER
|
139
143
|
config_param :content_type, :enum, list: [:"application/json", :"application/x-ndjson"], :default => :"application/json",
|
140
144
|
:deprecated => <<EOC
|
@@ -159,6 +163,7 @@ EOC
|
|
159
163
|
config_param :enable_ilm, :bool, :default => false
|
160
164
|
config_param :ilm_policy_id, :string, :default => DEFAULT_POLICY_ID
|
161
165
|
config_param :ilm_policy, :hash, :default => {}
|
166
|
+
config_param :ilm_policies, :hash, :default => {}
|
162
167
|
config_param :ilm_policy_overwrite, :bool, :default => false
|
163
168
|
config_param :truncate_caches_interval, :time, :default => nil
|
164
169
|
|
@@ -219,6 +224,11 @@ EOC
|
|
219
224
|
log.info "host placeholder and template installation makes your Elasticsearch cluster a bit slow down(beta)."
|
220
225
|
end
|
221
226
|
|
227
|
+
raise Fluent::ConfigError, "You can't specify ilm_policy and ilm_policies at the same time" unless @ilm_policy.empty? or @ilm_policies.empty?
|
228
|
+
|
229
|
+
unless @ilm_policy.empty?
|
230
|
+
@ilm_policies = { @ilm_policy_id => @ilm_policy }
|
231
|
+
end
|
222
232
|
@alias_indexes = []
|
223
233
|
@template_names = []
|
224
234
|
if !dry_run?
|
@@ -227,14 +237,14 @@ EOC
|
|
227
237
|
raise Fluent::ConfigError, "deflector_alias is prohibited to use with 'logstash_format at same time." if @logstash_format and @deflector_alias
|
228
238
|
end
|
229
239
|
if @ilm_policy.empty? && @ilm_policy_overwrite
|
230
|
-
raise Fluent::ConfigError, "ilm_policy_overwrite
|
240
|
+
raise Fluent::ConfigError, "ilm_policy_overwrite requires a non empty ilm_policy."
|
231
241
|
end
|
232
242
|
if @logstash_format || placeholder_substitution_needed_for_template?
|
233
243
|
class << self
|
234
244
|
alias_method :template_installation, :template_installation_actual
|
235
245
|
end
|
236
246
|
else
|
237
|
-
template_installation_actual(@deflector_alias ? @deflector_alias : @index_name, @template_name, @customize_template, @application_name, @index_name)
|
247
|
+
template_installation_actual(@deflector_alias ? @deflector_alias : @index_name, @template_name, @customize_template, @application_name, @index_name, @ilm_policy_id)
|
238
248
|
end
|
239
249
|
verify_ilm_working if @enable_ilm
|
240
250
|
elsif @templates
|
@@ -292,21 +302,32 @@ EOC
|
|
292
302
|
raise Fluent::ConfigError, "Could not load sniffer class #{@sniffer_class_name}: #{ex}"
|
293
303
|
end
|
294
304
|
|
305
|
+
@selector_class = nil
|
306
|
+
begin
|
307
|
+
@selector_class = Object.const_get(@selector_class_name) if @selector_class_name
|
308
|
+
rescue Exception => ex
|
309
|
+
raise Fluent::ConfigError, "Could not load selector class #{@selector_class_name}: #{ex}"
|
310
|
+
end
|
311
|
+
|
295
312
|
@last_seen_major_version = if major_version = handle_last_seen_es_major_version
|
296
313
|
major_version
|
297
314
|
else
|
298
315
|
@default_elasticsearch_version
|
299
316
|
end
|
300
|
-
if @
|
301
|
-
log.info "Detected ES 6.x: ES 7.x will only accept `_doc` in type_name."
|
302
|
-
end
|
303
|
-
if @last_seen_major_version == 7 && @type_name != DEFAULT_TYPE_NAME_ES_7x
|
304
|
-
log.warn "Detected ES 7.x: `_doc` will be used as the document `_type`."
|
305
|
-
@type_name = '_doc'.freeze
|
306
|
-
end
|
307
|
-
if @last_seen_major_version >= 8 && @type_name != DEFAULT_TYPE_NAME_ES_7x
|
308
|
-
log.info "Detected ES 8.x or above: This parameter has no effect."
|
317
|
+
if @suppress_type_name && @last_seen_major_version >= 7
|
309
318
|
@type_name = nil
|
319
|
+
else
|
320
|
+
if @last_seen_major_version == 6 && @type_name != DEFAULT_TYPE_NAME_ES_7x
|
321
|
+
log.info "Detected ES 6.x: ES 7.x will only accept `_doc` in type_name."
|
322
|
+
end
|
323
|
+
if @last_seen_major_version == 7 && @type_name != DEFAULT_TYPE_NAME_ES_7x
|
324
|
+
log.warn "Detected ES 7.x: `_doc` will be used as the document `_type`."
|
325
|
+
@type_name = '_doc'.freeze
|
326
|
+
end
|
327
|
+
if @last_seen_major_version >= 8 && @type_name != DEFAULT_TYPE_NAME_ES_7x
|
328
|
+
log.info "Detected ES 8.x or above: This parameter has no effect."
|
329
|
+
@type_name = nil
|
330
|
+
end
|
310
331
|
end
|
311
332
|
|
312
333
|
if @validate_client_version && !dry_run?
|
@@ -343,6 +364,7 @@ EOC
|
|
343
364
|
@routing_key_name = configure_routing_key_name
|
344
365
|
@meta_config_map = create_meta_config_map
|
345
366
|
@current_config = nil
|
367
|
+
@compressable_connection = false
|
346
368
|
|
347
369
|
@ignore_exception_classes = @ignore_exceptions.map do |exception|
|
348
370
|
unless Object.const_defined?(exception)
|
@@ -511,13 +533,15 @@ EOC
|
|
511
533
|
return Time.at(event_time).to_datetime
|
512
534
|
end
|
513
535
|
|
514
|
-
def client(host = nil)
|
536
|
+
def client(host = nil, compress_connection = false)
|
515
537
|
# check here to see if we already have a client connection for the given host
|
516
538
|
connection_options = get_connection_options(host)
|
517
539
|
|
518
540
|
@_es = nil unless is_existing_connection(connection_options[:hosts])
|
541
|
+
@_es = nil unless @compressable_connection == compress_connection
|
519
542
|
|
520
543
|
@_es ||= begin
|
544
|
+
@compressable_connection = compress_connection
|
521
545
|
@current_config = connection_options[:hosts].clone
|
522
546
|
adapter_conf = lambda {|f| f.adapter @http_backend, @backend_options }
|
523
547
|
local_reload_connections = @reload_connections
|
@@ -525,7 +549,7 @@ EOC
|
|
525
549
|
local_reload_connections = @reload_after
|
526
550
|
end
|
527
551
|
|
528
|
-
gzip_headers = if
|
552
|
+
gzip_headers = if compress_connection
|
529
553
|
{'Content-Encoding' => 'gzip'}
|
530
554
|
else
|
531
555
|
{}
|
@@ -551,7 +575,8 @@ EOC
|
|
551
575
|
},
|
552
576
|
sniffer_class: @sniffer_class,
|
553
577
|
serializer_class: @serializer_class,
|
554
|
-
|
578
|
+
selector_class: @selector_class,
|
579
|
+
compression: compress_connection,
|
555
580
|
}), &adapter_conf)
|
556
581
|
Elasticsearch::Client.new transport: transport
|
557
582
|
end
|
@@ -715,7 +740,12 @@ EOC
|
|
715
740
|
else
|
716
741
|
pipeline = nil
|
717
742
|
end
|
718
|
-
|
743
|
+
if @ilm_policy_id
|
744
|
+
ilm_policy_id = extract_placeholders(@ilm_policy_id, chunk)
|
745
|
+
else
|
746
|
+
ilm_policy_id = nil
|
747
|
+
end
|
748
|
+
return logstash_prefix, logstash_dateformat, index_name, type_name, template_name, customize_template, deflector_alias, application_name, pipeline, ilm_policy_id
|
719
749
|
end
|
720
750
|
|
721
751
|
def multi_workers_ready?
|
@@ -741,9 +771,9 @@ EOC
|
|
741
771
|
begin
|
742
772
|
meta, header, record = process_message(tag, meta, header, time, record, extracted_values)
|
743
773
|
info = if @include_index_in_url
|
744
|
-
RequestInfo.new(host, meta.delete("_index".freeze), meta
|
774
|
+
RequestInfo.new(host, meta.delete("_index".freeze), meta.delete("_alias".freeze))
|
745
775
|
else
|
746
|
-
RequestInfo.new(host, nil, meta
|
776
|
+
RequestInfo.new(host, nil, meta.delete("_alias".freeze))
|
747
777
|
end
|
748
778
|
|
749
779
|
if split_request?(bulk_message, info)
|
@@ -789,7 +819,7 @@ EOC
|
|
789
819
|
end
|
790
820
|
|
791
821
|
def process_message(tag, meta, header, time, record, extracted_values)
|
792
|
-
logstash_prefix, logstash_dateformat, index_name, type_name, _template_name, _customize_template, _deflector_alias,
|
822
|
+
logstash_prefix, logstash_dateformat, index_name, type_name, _template_name, _customize_template, _deflector_alias, application_name, pipeline, _ilm_policy_id = extracted_values
|
793
823
|
|
794
824
|
if @flatten_hashes
|
795
825
|
record = flatten_record(record)
|
@@ -812,17 +842,19 @@ EOC
|
|
812
842
|
|
813
843
|
target_index_parent, target_index_child_key = @target_index_key ? get_parent_of(record, @target_index_key) : nil
|
814
844
|
if target_index_parent && target_index_parent[target_index_child_key]
|
815
|
-
target_index = target_index_parent.delete(target_index_child_key)
|
845
|
+
target_index_alias = target_index = target_index_parent.delete(target_index_child_key)
|
816
846
|
elsif @logstash_format
|
817
847
|
dt = dt.new_offset(0) if @utc_index
|
818
848
|
target_index = "#{logstash_prefix}#{@logstash_prefix_separator}#{dt.strftime(logstash_dateformat)}"
|
849
|
+
target_index_alias = "#{logstash_prefix}#{@logstash_prefix_separator}#{application_name}#{@logstash_prefix_separator}#{dt.strftime(logstash_dateformat)}"
|
819
850
|
else
|
820
|
-
target_index = index_name
|
851
|
+
target_index_alias = target_index = index_name
|
821
852
|
end
|
822
853
|
|
823
854
|
# Change target_index to lower-case since Elasticsearch doesn't
|
824
855
|
# allow upper-case characters in index names.
|
825
856
|
target_index = target_index.downcase
|
857
|
+
target_index_alias = target_index_alias.downcase
|
826
858
|
if @include_tag_key
|
827
859
|
record[@tag_key] = tag
|
828
860
|
end
|
@@ -841,7 +873,9 @@ EOC
|
|
841
873
|
target_type = nil
|
842
874
|
end
|
843
875
|
else
|
844
|
-
if @
|
876
|
+
if @suppress_type_name && @last_seen_major_version >= 7
|
877
|
+
target_type = nil
|
878
|
+
elsif @last_seen_major_version == 7 && @type_name != DEFAULT_TYPE_NAME_ES_7x
|
845
879
|
log.warn "Detected ES 7.x: `_doc` will be used as the document `_type`."
|
846
880
|
target_type = '_doc'.freeze
|
847
881
|
elsif @last_seen_major_version >= 8
|
@@ -855,6 +889,7 @@ EOC
|
|
855
889
|
meta.clear
|
856
890
|
meta["_index".freeze] = target_index
|
857
891
|
meta["_type".freeze] = target_type unless @last_seen_major_version >= 8
|
892
|
+
meta["_alias".freeze] = target_index_alias
|
858
893
|
|
859
894
|
if @pipeline
|
860
895
|
meta["pipeline".freeze] = pipeline
|
@@ -897,16 +932,17 @@ EOC
|
|
897
932
|
placeholder?(:logstash_prefix, @logstash_prefix.to_s) ||
|
898
933
|
placeholder?(:logstash_dateformat, @logstash_dateformat.to_s) ||
|
899
934
|
placeholder?(:deflector_alias, @deflector_alias.to_s) ||
|
900
|
-
placeholder?(:application_name, @application_name.to_s)
|
935
|
+
placeholder?(:application_name, @application_name.to_s) ||
|
936
|
+
placeholder?(:ilm_policy_id, @ilm_policy_id.to_s)
|
901
937
|
log.debug("Need substitution: #{need_substitution}")
|
902
938
|
need_substitution
|
903
939
|
end
|
904
940
|
|
905
|
-
def template_installation(deflector_alias, template_name, customize_template, application_name, target_index, host)
|
941
|
+
def template_installation(deflector_alias, template_name, customize_template, application_name, ilm_policy_id, target_index, host)
|
906
942
|
# for safety.
|
907
943
|
end
|
908
944
|
|
909
|
-
def template_installation_actual(deflector_alias, template_name, customize_template, application_name, target_index, host=nil)
|
945
|
+
def template_installation_actual(deflector_alias, template_name, customize_template, application_name, target_index, ilm_policy_id, host=nil)
|
910
946
|
if template_name && @template_file
|
911
947
|
if @alias_indexes.include? deflector_alias
|
912
948
|
log.debug("Index alias #{deflector_alias} already exists (cached)")
|
@@ -915,11 +951,12 @@ EOC
|
|
915
951
|
else
|
916
952
|
retry_operate(@max_retry_putting_template, @fail_on_putting_template_retry_exceed) do
|
917
953
|
if customize_template
|
918
|
-
template_custom_install(template_name, @template_file, @template_overwrite, customize_template, @enable_ilm, deflector_alias,
|
954
|
+
template_custom_install(template_name, @template_file, @template_overwrite, customize_template, @enable_ilm, deflector_alias, ilm_policy_id, host)
|
919
955
|
else
|
920
|
-
template_install(template_name, @template_file, @template_overwrite, @enable_ilm, deflector_alias,
|
956
|
+
template_install(template_name, @template_file, @template_overwrite, @enable_ilm, deflector_alias, ilm_policy_id, host)
|
921
957
|
end
|
922
|
-
|
958
|
+
ilm_policy = @ilm_policies[ilm_policy_id] || {}
|
959
|
+
create_rollover_alias(target_index, @rollover_index, deflector_alias, application_name, @index_date_pattern, @index_separator, @enable_ilm, ilm_policy_id, ilm_policy, @ilm_policy_overwrite, host)
|
923
960
|
end
|
924
961
|
@alias_indexes << deflector_alias unless deflector_alias.nil?
|
925
962
|
@template_names << template_name unless template_name.nil?
|
@@ -930,11 +967,11 @@ EOC
|
|
930
967
|
# send_bulk given a specific bulk request, the original tag,
|
931
968
|
# chunk, and bulk_message_count
|
932
969
|
def send_bulk(data, tag, chunk, bulk_message_count, extracted_values, info)
|
933
|
-
logstash_prefix, _logstash_dateformat, index_name, _type_name, template_name, customize_template, deflector_alias, application_name, _pipeline = extracted_values
|
970
|
+
logstash_prefix, _logstash_dateformat, index_name, _type_name, template_name, customize_template, deflector_alias, application_name, _pipeline, ilm_policy_id = extracted_values
|
934
971
|
if deflector_alias
|
935
|
-
template_installation(deflector_alias, template_name, customize_template, application_name, index_name, info.host)
|
972
|
+
template_installation(deflector_alias, template_name, customize_template, application_name, index_name, ilm_policy_id, info.host)
|
936
973
|
else
|
937
|
-
template_installation(info.ilm_index, template_name, customize_template, application_name, @logstash_format ? logstash_prefix : index_name, info.host)
|
974
|
+
template_installation(info.ilm_index, template_name, customize_template, application_name, @logstash_format ? logstash_prefix : index_name, ilm_policy_id, info.host)
|
938
975
|
end
|
939
976
|
|
940
977
|
begin
|
@@ -947,7 +984,7 @@ EOC
|
|
947
984
|
data
|
948
985
|
end
|
949
986
|
|
950
|
-
response = client(info.host).bulk body: prepared_data, index: info.index
|
987
|
+
response = client(info.host, compression).bulk body: prepared_data, index: info.index
|
951
988
|
log.on_trace { log.trace "bulk response: #{response}" }
|
952
989
|
|
953
990
|
if response['errors']
|
@@ -35,16 +35,18 @@ module Fluent::Plugin
|
|
35
35
|
end
|
36
36
|
|
37
37
|
|
38
|
-
def client(host = nil)
|
38
|
+
def client(host = nil, compress_connection = false)
|
39
39
|
# check here to see if we already have a client connection for the given host
|
40
40
|
connection_options = get_connection_options(host)
|
41
41
|
|
42
42
|
@_es = nil unless is_existing_connection(connection_options[:hosts])
|
43
|
+
@_es = nil unless @compressable_connection == compress_connection
|
43
44
|
|
44
45
|
@_es ||= begin
|
46
|
+
@compressable_connection = compress_connection
|
45
47
|
@current_config = connection_options[:hosts].clone
|
46
48
|
adapter_conf = lambda {|f| f.adapter @http_backend, @backend_options }
|
47
|
-
gzip_headers = if
|
49
|
+
gzip_headers = if compress_connection
|
48
50
|
{'Content-Encoding' => 'gzip'}
|
49
51
|
else
|
50
52
|
{}
|
@@ -67,7 +69,7 @@ module Fluent::Plugin
|
|
67
69
|
password: @password,
|
68
70
|
scheme: @scheme
|
69
71
|
},
|
70
|
-
compression:
|
72
|
+
compression: compress_connection,
|
71
73
|
}), &adapter_conf)
|
72
74
|
Elasticsearch::Client.new transport: transport
|
73
75
|
end
|
@@ -228,7 +230,7 @@ module Fluent::Plugin
|
|
228
230
|
else
|
229
231
|
data
|
230
232
|
end
|
231
|
-
response = client(host).bulk body: prepared_data, index: index
|
233
|
+
response = client(host, compression).bulk body: prepared_data, index: index
|
232
234
|
if response['errors']
|
233
235
|
log.error "Could not push log to Elasticsearch: #{response}"
|
234
236
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative '../helper'
|
2
|
+
require 'fluent/test/driver/output'
|
3
|
+
require 'fluent/plugin/out_elasticsearch'
|
4
|
+
|
5
|
+
class ElasticsearchFallbackSelectorTest < Test::Unit::TestCase
|
6
|
+
attr_accessor :index_cmds
|
7
|
+
|
8
|
+
def setup
|
9
|
+
Fluent::Test.setup
|
10
|
+
@driver = nil
|
11
|
+
log = Fluent::Engine.log
|
12
|
+
log.out.logs.slice!(0, log.out.logs.length)
|
13
|
+
end
|
14
|
+
|
15
|
+
def stub_elastic(url="http://localhost:9200/_bulk")
|
16
|
+
stub_request(:post, url).with do |req|
|
17
|
+
@index_cmds = req.body.split("\n").map {|r| JSON.parse(r) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def stub_elastic_info(url="http://localhost:9200/", version="6.4.2")
|
22
|
+
body ="{\"version\":{\"number\":\"#{version}\"}}"
|
23
|
+
stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' } })
|
24
|
+
end
|
25
|
+
|
26
|
+
def stub_elastic_info_not_found(url="http://localhost:9200/", version="6.4.2")
|
27
|
+
stub_request(:get, url).to_return(:status => [404, "Not Found"])
|
28
|
+
end
|
29
|
+
|
30
|
+
def stub_elastic_info_unavailable(url="http://localhost:9200/", version="6.4.2")
|
31
|
+
stub_request(:get, url).to_return(:status => [503, "Service Unavailable"])
|
32
|
+
end
|
33
|
+
|
34
|
+
def sample_record(content={})
|
35
|
+
{'age' => 26, 'request_id' => '42', 'parent_id' => 'parent', 'routing_id' => 'routing'}.merge(content)
|
36
|
+
end
|
37
|
+
|
38
|
+
def driver(conf='')
|
39
|
+
@driver ||= Fluent::Test::Driver::Output.new(Fluent::Plugin::ElasticsearchOutput) {
|
40
|
+
# v0.12's test driver assume format definition. This simulates ObjectBufferedOutput format
|
41
|
+
if !defined?(Fluent::Plugin::Output)
|
42
|
+
def format(tag, time, record)
|
43
|
+
[time, record].to_msgpack
|
44
|
+
end
|
45
|
+
end
|
46
|
+
}.configure(conf)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_fallback_on_info
|
50
|
+
stub_elastic_info_not_found("http://localhost:9202/")
|
51
|
+
stub_elastic_info_unavailable("http://localhost:9201/")
|
52
|
+
stub_elastic_info
|
53
|
+
stub_elastic
|
54
|
+
config = %[
|
55
|
+
hosts localhost:9202,localhost:9201,localhost:9200
|
56
|
+
selector_class_name Fluent::Plugin::ElasticseatchFallbackSelector
|
57
|
+
@log_level debug
|
58
|
+
with_transporter_log true
|
59
|
+
reload_connections true
|
60
|
+
reload_after 10
|
61
|
+
]
|
62
|
+
assert_raise(Elasticsearch::Transport::Transport::Errors::NotFound) do
|
63
|
+
driver(config)
|
64
|
+
end
|
65
|
+
driver.run(default_tag: 'test') do
|
66
|
+
driver.feed(sample_record)
|
67
|
+
end
|
68
|
+
assert_equal(2, index_cmds.length)
|
69
|
+
assert_equal("fluentd", index_cmds.first['index']['_index'])
|
70
|
+
end
|
71
|
+
|
72
|
+
# TODO: on feed phase test case
|
73
|
+
end
|