fluent-plugin-elasticsearch 4.0.7 → 4.1.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 +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
|