fluent-plugin-elasticsearch 4.0.10 → 4.1.3
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/History.md +17 -0
- data/README.md +51 -8
- data/fluent-plugin-elasticsearch.gemspec +1 -1
- data/lib/fluent/plugin/elasticsearch_fallback_selector.rb +9 -0
- data/lib/fluent/plugin/elasticsearch_index_template.rb +19 -11
- data/lib/fluent/plugin/out_elasticsearch.rb +32 -15
- data/test/plugin/test_elasticsearch_fallback_selector.rb +73 -0
- data/test/plugin/test_in_elasticsearch.rb +14 -9
- data/test/plugin/test_out_elasticsearch.rb +158 -83
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b4183d1e2afbcf9e0e5f78b6cb6ed2fff3206f495a8676d38eb1dbc1ff7267f
|
4
|
+
data.tar.gz: 2f1644d04286ae42c51e869c6aadd928ec00b678a405dce838cb1d1802ebf5b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bc88d00e8800e7062dff4fdb9b6bc67c509ee851f5e726321783bec8902df6b548a2533d7c278151882b6f534e5adc680ba83964885d7bb9fd520340484c8478
|
7
|
+
data.tar.gz: 07f4379b3bfee4b22bb50f60c441fa60c87ee65967fa70523c3a6fdc7d0cc80c0fced8fd92958227eb64e353c8e623293f5c1e3d17fba848cdab707969d4f3d4
|
data/History.md
CHANGED
@@ -2,6 +2,23 @@
|
|
2
2
|
|
3
3
|
### [Unreleased]
|
4
4
|
|
5
|
+
### 4.1.3
|
6
|
+
- Load multiple templates even if template_name and template_file given (#799)
|
7
|
+
- Handle elasticsearch-ruby 7.9.0 using HTTP method changes (#795)
|
8
|
+
|
9
|
+
### 4.1.2
|
10
|
+
- Use Hash#dig instead of Hash#[] on retrieving version information from Elasticsearch info API (#793)
|
11
|
+
|
12
|
+
### 4.1.1
|
13
|
+
- Correct ILM explain on logstash_format case (#786)
|
14
|
+
|
15
|
+
### 4.1.0
|
16
|
+
- Implement Fallback selector and configurable selector class (#782)
|
17
|
+
|
18
|
+
### 4.0.11
|
19
|
+
- Add custom and time placeholders combination testcase for ILM (#781)
|
20
|
+
- Really support ILM on `logstash_format` enabled environment (#779)
|
21
|
+
|
5
22
|
### 4.0.10
|
6
23
|
- filter_elasticsearch_genid: Use entire record as hash seed (#777)
|
7
24
|
- Suppress type in meta with suppress_type_name parameter (#774)
|
data/README.md
CHANGED
@@ -78,6 +78,7 @@ Current maintainers: @cosmo0920
|
|
78
78
|
+ [Hash flattening](#hash-flattening)
|
79
79
|
+ [Generate Hash ID](#generate-hash-id)
|
80
80
|
+ [sniffer_class_name](#sniffer-class-name)
|
81
|
+
+ [selector_class_name](#selector-class-name)
|
81
82
|
+ [reload_after](#reload-after)
|
82
83
|
+ [validate_client_version](#validate-client-version)
|
83
84
|
+ [unrecoverable_error_types](#unrecoverable-error-types)
|
@@ -120,10 +121,12 @@ Current maintainers: @cosmo0920
|
|
120
121
|
|
121
122
|
## Requirements
|
122
123
|
|
123
|
-
| fluent-plugin-elasticsearch | fluentd
|
124
|
-
|
125
|
-
| >=
|
126
|
-
|
|
124
|
+
| fluent-plugin-elasticsearch | fluentd | ruby |
|
125
|
+
|:----------------------------:|:-----------:|:------:|
|
126
|
+
| >= 4.0.1 | >= v0.14.22 | >= 2.3 |
|
127
|
+
| >= 3.2.4 && < 4.0.1 | >= v0.14.22 | >= 2.1 |
|
128
|
+
| >= 2.0.0 && < 3.2.3 | >= v0.14.20 | >= 2.1 |
|
129
|
+
| < 2.0.0 | >= v0.12.0 | >= 1.9 |
|
127
130
|
|
128
131
|
NOTE: For v0.12 version, you should use 1.x.y version. Please send patch into v0.12 branch if you encountered 1.x version's bug.
|
129
132
|
|
@@ -428,7 +431,7 @@ Specify index templates in form of hash. Can contain multiple templates.
|
|
428
431
|
templates { "template_name_1": "path_to_template_1_file", "template_name_2": "path_to_template_2_file"}
|
429
432
|
```
|
430
433
|
|
431
|
-
|
434
|
+
**Note:** Before ES plugin v4.1.2, if `template_file` and `template_name` are set, then this parameter will be ignored. In 4.1.3 or later, `template_file` and `template_name` can work with `templates`.
|
432
435
|
|
433
436
|
### customize_template
|
434
437
|
|
@@ -478,6 +481,8 @@ deflector_alias test-current
|
|
478
481
|
|
479
482
|
If [rollover_index](#rollover_index) is set, then this parameter will be in effect otherwise ignored.
|
480
483
|
|
484
|
+
**NOTE:** Since 4.1.1, `deflector_alias` is prohibited to use with `enable_ilm`.
|
485
|
+
|
481
486
|
### index_prefix
|
482
487
|
|
483
488
|
This parameter is marked as obsoleted.
|
@@ -989,7 +994,7 @@ reload_after 100
|
|
989
994
|
|
990
995
|
#### Tips
|
991
996
|
|
992
|
-
The included sniffer class
|
997
|
+
The included sniffer class is not required `out_elasticsearch`.
|
993
998
|
You should tell Fluentd where the sniffer class exists.
|
994
999
|
|
995
1000
|
If you use td-agent, you must put the following lines into `TD_AGENT_DEFAULT` file:
|
@@ -1006,6 +1011,38 @@ sniffer=$(td-agent-gem contents fluent-plugin-elasticsearch|grep elasticsearch_s
|
|
1006
1011
|
$ fluentd -r $sniffer [AND YOUR OTHER OPTIONS]
|
1007
1012
|
```
|
1008
1013
|
|
1014
|
+
### Selector Class Name
|
1015
|
+
|
1016
|
+
The default selector used by the `Elasticsearch::Transport` class works well when Fluentd should behave round robin and random selector cases. This doesn't work well when Fluentd should behave fallbacking from exhausted ES cluster to normal ES cluster.
|
1017
|
+
The parameter `selector_class_name` gives you the ability to provide your own Selector class to implement whatever selection nodes logic you require.
|
1018
|
+
|
1019
|
+
The below configuration is using plugin built-in `ElasticseatchFallbackSelector`:
|
1020
|
+
|
1021
|
+
```
|
1022
|
+
hosts exhausted-host:9201,normal-host:9200
|
1023
|
+
selector_class_name "Fluent::Plugin::ElasticseatchFallbackSelector"
|
1024
|
+
```
|
1025
|
+
|
1026
|
+
#### Tips
|
1027
|
+
|
1028
|
+
The included selector class is required in `out_elasticsearch` by default.
|
1029
|
+
But, your custom selector class is not required in `out_elasticsearch`.
|
1030
|
+
You should tell Fluentd where the selector class exists.
|
1031
|
+
|
1032
|
+
If you use td-agent, you must put the following lines into `TD_AGENT_DEFAULT` file:
|
1033
|
+
|
1034
|
+
```
|
1035
|
+
selector=/path/to/your_awesome_selector.rb
|
1036
|
+
TD_AGENT_OPTIONS="--use-v1-config -r $selector"
|
1037
|
+
```
|
1038
|
+
|
1039
|
+
If you use Fluentd directly, you must pass the following lines as Fluentd command line option:
|
1040
|
+
|
1041
|
+
```
|
1042
|
+
selector=/path/to/your_awesome_selector.rb
|
1043
|
+
$ fluentd -r $selector [AND YOUR OTHER OPTIONS]
|
1044
|
+
```
|
1045
|
+
|
1009
1046
|
### Reload After
|
1010
1047
|
|
1011
1048
|
When `reload_connections true`, this is the integer number of operations after which the plugin will
|
@@ -1720,7 +1757,7 @@ ILM target index alias is created with `index_name` or an index which is calcula
|
|
1720
1757
|
|
1721
1758
|
From Elasticsearch plugin v4.0.0, ILM target index will be calculated from `index_name` (normal mode) or `logstash_prefix` (using with `logstash_format`as true).
|
1722
1759
|
|
1723
|
-
|
1760
|
+
**NOTE:** Before Elasticsearch plugin v4.1.0, using `deflector_alias` parameter when ILM is enabled is permitted and handled, but, in the later releases such that 4.1.1 or later, it cannot use with when ILM is enabled.
|
1724
1761
|
|
1725
1762
|
And also, ILM feature users should specify their Elasticsearch template for ILM enabled indices.
|
1726
1763
|
Because ILM settings are injected into their Elasticsearch templates.
|
@@ -1733,7 +1770,13 @@ It usually should be used with default value which is `default`.
|
|
1733
1770
|
|
1734
1771
|
Then, ILM parameters are used in alias index like as:
|
1735
1772
|
|
1736
|
-
|
1773
|
+
##### Simple `index_name` case:
|
1774
|
+
|
1775
|
+
`<index_name><index_separator><application_name>-000001`.
|
1776
|
+
|
1777
|
+
##### `logstash_format` as `true` case:
|
1778
|
+
|
1779
|
+
`<logstash_prefix><logstash_prefix_separator><application_name><logstash_prefix_separator><logstash_dateformat>-000001`.
|
1737
1780
|
|
1738
1781
|
#### Example ILM settings
|
1739
1782
|
|
@@ -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 = '4.
|
6
|
+
s.version = '4.1.3'
|
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}
|
@@ -65,11 +65,12 @@ module Fluent::ElasticsearchIndexTemplate
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
def template_install(name, template_file, overwrite, enable_ilm = false, deflector_alias_name = nil, ilm_policy_id = nil, host = nil)
|
68
|
+
def template_install(name, template_file, overwrite, enable_ilm = false, deflector_alias_name = nil, ilm_policy_id = nil, host = nil, target_index = nil)
|
69
69
|
inject_template_name = get_template_name(enable_ilm, name, deflector_alias_name)
|
70
70
|
if overwrite
|
71
71
|
template_put(inject_template_name,
|
72
72
|
enable_ilm ? inject_ilm_settings_to_template(deflector_alias_name,
|
73
|
+
target_index,
|
73
74
|
ilm_policy_id,
|
74
75
|
get_template(template_file)) :
|
75
76
|
get_template(template_file), host)
|
@@ -80,6 +81,7 @@ module Fluent::ElasticsearchIndexTemplate
|
|
80
81
|
if !template_exists?(inject_template_name, host)
|
81
82
|
template_put(inject_template_name,
|
82
83
|
enable_ilm ? inject_ilm_settings_to_template(deflector_alias_name,
|
84
|
+
target_index,
|
83
85
|
ilm_policy_id,
|
84
86
|
get_template(template_file)) :
|
85
87
|
get_template(template_file), host)
|
@@ -89,10 +91,12 @@ module Fluent::ElasticsearchIndexTemplate
|
|
89
91
|
end
|
90
92
|
end
|
91
93
|
|
92
|
-
def template_custom_install(template_name, template_file, overwrite, customize_template, enable_ilm, deflector_alias_name, ilm_policy_id, host)
|
94
|
+
def template_custom_install(template_name, template_file, overwrite, customize_template, enable_ilm, deflector_alias_name, ilm_policy_id, host, target_index)
|
93
95
|
template_custom_name = get_template_name(enable_ilm, template_name, deflector_alias_name)
|
94
96
|
custom_template = if enable_ilm
|
95
|
-
inject_ilm_settings_to_template(deflector_alias_name,
|
97
|
+
inject_ilm_settings_to_template(deflector_alias_name,
|
98
|
+
target_index,
|
99
|
+
ilm_policy_id,
|
96
100
|
get_custom_template(template_file,
|
97
101
|
customize_template))
|
98
102
|
else
|
@@ -115,26 +119,30 @@ module Fluent::ElasticsearchIndexTemplate
|
|
115
119
|
enable_ilm ? deflector_alias_name : template_name
|
116
120
|
end
|
117
121
|
|
118
|
-
def inject_ilm_settings_to_template(
|
122
|
+
def inject_ilm_settings_to_template(deflector_alias, target_index, ilm_policy_id, template)
|
119
123
|
log.debug("Overwriting index patterns when Index Lifecycle Management is enabled.")
|
120
124
|
template.delete('template') if template.include?('template')
|
121
|
-
template['index_patterns'] = "#{
|
122
|
-
template['order'] = template['order'] ? template['order'] +
|
125
|
+
template['index_patterns'] = "#{target_index}-*"
|
126
|
+
template['order'] = template['order'] ? template['order'] + target_index.split('-').length : 50 + target_index.split('-').length
|
123
127
|
if template['settings'] && (template['settings']['index.lifecycle.name'] || template['settings']['index.lifecycle.rollover_alias'])
|
124
128
|
log.debug("Overwriting index lifecycle name and rollover alias when Index Lifecycle Management is enabled.")
|
125
129
|
end
|
126
|
-
template['settings'].update({ 'index.lifecycle.name' => ilm_policy_id, 'index.lifecycle.rollover_alias' =>
|
130
|
+
template['settings'].update({ 'index.lifecycle.name' => ilm_policy_id, 'index.lifecycle.rollover_alias' => deflector_alias})
|
127
131
|
template
|
128
132
|
end
|
129
133
|
|
130
|
-
def create_rollover_alias(
|
134
|
+
def create_rollover_alias(target_index, rollover_index, deflector_alias_name, app_name, index_date_pattern, index_separator, enable_ilm, ilm_policy_id, ilm_policy, ilm_policy_overwrite, host)
|
131
135
|
# ILM request to create alias.
|
132
136
|
if rollover_index || enable_ilm
|
133
137
|
if !client.indices.exists_alias(:name => deflector_alias_name)
|
134
|
-
if
|
135
|
-
index_name_temp='<'+
|
138
|
+
if @logstash_format
|
139
|
+
index_name_temp = '<'+target_index+'-000001>'
|
136
140
|
else
|
137
|
-
|
141
|
+
if index_date_pattern.empty?
|
142
|
+
index_name_temp = '<'+target_index.downcase+index_separator+app_name.downcase+'-000001>'
|
143
|
+
else
|
144
|
+
index_name_temp = '<'+target_index.downcase+index_separator+app_name.downcase+'-{'+index_date_pattern+'}-000001>'
|
145
|
+
end
|
138
146
|
end
|
139
147
|
indexcreation(index_name_temp, host)
|
140
148
|
body = rollover_alias_payload(deflector_alias_name)
|
@@ -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
|
@@ -50,7 +51,7 @@ module Fluent::Plugin
|
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
53
|
-
RequestInfo = Struct.new(:host, :index, :ilm_index)
|
54
|
+
RequestInfo = Struct.new(:host, :index, :ilm_index, :ilm_alias)
|
54
55
|
|
55
56
|
attr_reader :alias_indexes
|
56
57
|
attr_reader :template_names
|
@@ -137,6 +138,7 @@ EOC
|
|
137
138
|
config_param :with_transporter_log, :bool, :default => false
|
138
139
|
config_param :emit_error_for_missing_id, :bool, :default => false
|
139
140
|
config_param :sniffer_class_name, :string, :default => nil
|
141
|
+
config_param :selector_class_name, :string, :default => nil
|
140
142
|
config_param :reload_after, :integer, :default => DEFAULT_RELOAD_AFTER
|
141
143
|
config_param :content_type, :enum, list: [:"application/json", :"application/x-ndjson"], :default => :"application/json",
|
142
144
|
:deprecated => <<EOC
|
@@ -232,7 +234,7 @@ EOC
|
|
232
234
|
if !dry_run?
|
233
235
|
if @template_name && @template_file
|
234
236
|
if @enable_ilm
|
235
|
-
raise Fluent::ConfigError, "deflector_alias is prohibited to use with
|
237
|
+
raise Fluent::ConfigError, "deflector_alias is prohibited to use with enable_ilm at same time." if @deflector_alias
|
236
238
|
end
|
237
239
|
if @ilm_policy.empty? && @ilm_policy_overwrite
|
238
240
|
raise Fluent::ConfigError, "ilm_policy_overwrite requires a non empty ilm_policy."
|
@@ -245,7 +247,8 @@ EOC
|
|
245
247
|
template_installation_actual(@deflector_alias ? @deflector_alias : @index_name, @template_name, @customize_template, @application_name, @index_name, @ilm_policy_id)
|
246
248
|
end
|
247
249
|
verify_ilm_working if @enable_ilm
|
248
|
-
|
250
|
+
end
|
251
|
+
if @templates
|
249
252
|
retry_operate(@max_retry_putting_template, @fail_on_putting_template_retry_exceed) do
|
250
253
|
templates_hash_install(@templates, @template_overwrite)
|
251
254
|
end
|
@@ -300,6 +303,13 @@ EOC
|
|
300
303
|
raise Fluent::ConfigError, "Could not load sniffer class #{@sniffer_class_name}: #{ex}"
|
301
304
|
end
|
302
305
|
|
306
|
+
@selector_class = nil
|
307
|
+
begin
|
308
|
+
@selector_class = Object.const_get(@selector_class_name) if @selector_class_name
|
309
|
+
rescue Exception => ex
|
310
|
+
raise Fluent::ConfigError, "Could not load selector class #{@selector_class_name}: #{ex}"
|
311
|
+
end
|
312
|
+
|
303
313
|
@last_seen_major_version = if major_version = handle_last_seen_es_major_version
|
304
314
|
major_version
|
305
315
|
else
|
@@ -452,7 +462,10 @@ EOC
|
|
452
462
|
|
453
463
|
def detect_es_major_version
|
454
464
|
@_es_info ||= client.info
|
455
|
-
@_es_info
|
465
|
+
unless version = @_es_info.dig("version", "number")
|
466
|
+
version = @default_elasticsearch_version
|
467
|
+
end
|
468
|
+
version.to_i
|
456
469
|
end
|
457
470
|
|
458
471
|
def client_library_version
|
@@ -566,6 +579,7 @@ EOC
|
|
566
579
|
},
|
567
580
|
sniffer_class: @sniffer_class,
|
568
581
|
serializer_class: @serializer_class,
|
582
|
+
selector_class: @selector_class,
|
569
583
|
compression: compress_connection,
|
570
584
|
}), &adapter_conf)
|
571
585
|
Elasticsearch::Client.new transport: transport
|
@@ -761,9 +775,9 @@ EOC
|
|
761
775
|
begin
|
762
776
|
meta, header, record = process_message(tag, meta, header, time, record, extracted_values)
|
763
777
|
info = if @include_index_in_url
|
764
|
-
RequestInfo.new(host, meta.delete("_index".freeze), meta["_index".freeze])
|
778
|
+
RequestInfo.new(host, meta.delete("_index".freeze), meta["_index".freeze], meta.delete("_alias".freeze))
|
765
779
|
else
|
766
|
-
RequestInfo.new(host, nil, meta["_index".freeze])
|
780
|
+
RequestInfo.new(host, nil, meta["_index".freeze], meta.delete("_alias".freeze))
|
767
781
|
end
|
768
782
|
|
769
783
|
if split_request?(bulk_message, info)
|
@@ -809,7 +823,7 @@ EOC
|
|
809
823
|
end
|
810
824
|
|
811
825
|
def process_message(tag, meta, header, time, record, extracted_values)
|
812
|
-
logstash_prefix, logstash_dateformat, index_name, type_name, _template_name, _customize_template, _deflector_alias,
|
826
|
+
logstash_prefix, logstash_dateformat, index_name, type_name, _template_name, _customize_template, _deflector_alias, application_name, pipeline, _ilm_policy_id = extracted_values
|
813
827
|
|
814
828
|
if @flatten_hashes
|
815
829
|
record = flatten_record(record)
|
@@ -832,17 +846,19 @@ EOC
|
|
832
846
|
|
833
847
|
target_index_parent, target_index_child_key = @target_index_key ? get_parent_of(record, @target_index_key) : nil
|
834
848
|
if target_index_parent && target_index_parent[target_index_child_key]
|
835
|
-
target_index = target_index_parent.delete(target_index_child_key)
|
849
|
+
target_index_alias = target_index = target_index_parent.delete(target_index_child_key)
|
836
850
|
elsif @logstash_format
|
837
851
|
dt = dt.new_offset(0) if @utc_index
|
838
852
|
target_index = "#{logstash_prefix}#{@logstash_prefix_separator}#{dt.strftime(logstash_dateformat)}"
|
853
|
+
target_index_alias = "#{logstash_prefix}#{@logstash_prefix_separator}#{application_name}#{@logstash_prefix_separator}#{dt.strftime(logstash_dateformat)}"
|
839
854
|
else
|
840
|
-
target_index = index_name
|
855
|
+
target_index_alias = target_index = index_name
|
841
856
|
end
|
842
857
|
|
843
858
|
# Change target_index to lower-case since Elasticsearch doesn't
|
844
859
|
# allow upper-case characters in index names.
|
845
860
|
target_index = target_index.downcase
|
861
|
+
target_index_alias = target_index_alias.downcase
|
846
862
|
if @include_tag_key
|
847
863
|
record[@tag_key] = tag
|
848
864
|
end
|
@@ -877,6 +893,7 @@ EOC
|
|
877
893
|
meta.clear
|
878
894
|
meta["_index".freeze] = target_index
|
879
895
|
meta["_type".freeze] = target_type unless @last_seen_major_version >= 8
|
896
|
+
meta["_alias".freeze] = target_index_alias
|
880
897
|
|
881
898
|
if @pipeline
|
882
899
|
meta["pipeline".freeze] = pipeline
|
@@ -931,16 +948,16 @@ EOC
|
|
931
948
|
|
932
949
|
def template_installation_actual(deflector_alias, template_name, customize_template, application_name, target_index, ilm_policy_id, host=nil)
|
933
950
|
if template_name && @template_file
|
934
|
-
if @alias_indexes.include?
|
951
|
+
if !@logstash_format && @alias_indexes.include?(deflector_alias)
|
935
952
|
log.debug("Index alias #{deflector_alias} already exists (cached)")
|
936
|
-
elsif @template_names.include?
|
953
|
+
elsif !@logstash_format && @template_names.include?(template_name)
|
937
954
|
log.debug("Template name #{template_name} already exists (cached)")
|
938
955
|
else
|
939
956
|
retry_operate(@max_retry_putting_template, @fail_on_putting_template_retry_exceed) do
|
940
957
|
if customize_template
|
941
|
-
template_custom_install(template_name, @template_file, @template_overwrite, customize_template, @enable_ilm, deflector_alias, ilm_policy_id, host)
|
958
|
+
template_custom_install(template_name, @template_file, @template_overwrite, customize_template, @enable_ilm, deflector_alias, ilm_policy_id, host, target_index)
|
942
959
|
else
|
943
|
-
template_install(template_name, @template_file, @template_overwrite, @enable_ilm, deflector_alias, ilm_policy_id, host)
|
960
|
+
template_install(template_name, @template_file, @template_overwrite, @enable_ilm, deflector_alias, ilm_policy_id, host, target_index)
|
944
961
|
end
|
945
962
|
ilm_policy = @ilm_policies[ilm_policy_id] || {}
|
946
963
|
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)
|
@@ -954,11 +971,11 @@ EOC
|
|
954
971
|
# send_bulk given a specific bulk request, the original tag,
|
955
972
|
# chunk, and bulk_message_count
|
956
973
|
def send_bulk(data, tag, chunk, bulk_message_count, extracted_values, info)
|
957
|
-
|
974
|
+
_logstash_prefix, _logstash_dateformat, index_name, _type_name, template_name, customize_template, deflector_alias, application_name, _pipeline, ilm_policy_id = extracted_values
|
958
975
|
if deflector_alias
|
959
976
|
template_installation(deflector_alias, template_name, customize_template, application_name, index_name, ilm_policy_id, info.host)
|
960
977
|
else
|
961
|
-
template_installation(info.ilm_index, template_name, customize_template, application_name, @logstash_format ?
|
978
|
+
template_installation(info.ilm_index, template_name, customize_template, application_name, @logstash_format ? info.ilm_alias : index_name, ilm_policy_id, info.host)
|
962
979
|
end
|
963
980
|
|
964
981
|
begin
|
@@ -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
|
@@ -20,6 +20,11 @@ class ElasticsearchInputTest < Test::Unit::TestCase
|
|
20
20
|
@driver = nil
|
21
21
|
log = Fluent::Engine.log
|
22
22
|
log.out.logs.slice!(0, log.out.logs.length)
|
23
|
+
@http_method = if Gem::Version.new(Elasticsearch::VERSION) >= Gem::Version.new("7.9.0")
|
24
|
+
:post
|
25
|
+
else
|
26
|
+
:get
|
27
|
+
end
|
23
28
|
end
|
24
29
|
|
25
30
|
def driver(conf='')
|
@@ -313,7 +318,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
|
|
313
318
|
end
|
314
319
|
|
315
320
|
def test_emit
|
316
|
-
stub_request(
|
321
|
+
stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
|
317
322
|
with(body: "{\"sort\":[\"_doc\"]}").
|
318
323
|
to_return(status: 200, body: sample_response.to_s,
|
319
324
|
headers: {'Content-Type' => 'application/json'})
|
@@ -328,7 +333,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
|
|
328
333
|
|
329
334
|
def test_emit_with_custom_index_name
|
330
335
|
index_name = "logstash"
|
331
|
-
stub_request(
|
336
|
+
stub_request(@http_method, "http://localhost:9200/#{index_name}/_search?scroll=1m&size=1000").
|
332
337
|
with(body: "{\"sort\":[\"_doc\"]}").
|
333
338
|
to_return(status: 200, body: sample_response(index_name).to_s,
|
334
339
|
headers: {'Content-Type' => 'application/json'})
|
@@ -343,7 +348,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
|
|
343
348
|
|
344
349
|
def test_emit_with_parse_timestamp
|
345
350
|
index_name = "fluentd"
|
346
|
-
stub_request(
|
351
|
+
stub_request(@http_method, "http://localhost:9200/#{index_name}/_search?scroll=1m&size=1000").
|
347
352
|
with(body: "{\"sort\":[\"_doc\"]}").
|
348
353
|
to_return(status: 200, body: sample_response(index_name).to_s,
|
349
354
|
headers: {'Content-Type' => 'application/json'})
|
@@ -361,7 +366,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
|
|
361
366
|
|
362
367
|
def test_emit_with_parse_timestamp_and_timstamp_format
|
363
368
|
index_name = "fluentd"
|
364
|
-
stub_request(
|
369
|
+
stub_request(@http_method, "http://localhost:9200/#{index_name}/_search?scroll=1m&size=1000").
|
365
370
|
with(body: "{\"sort\":[\"_doc\"]}").
|
366
371
|
to_return(status: 200, body: sample_response(index_name).to_s,
|
367
372
|
headers: {'Content-Type' => 'application/json'})
|
@@ -380,7 +385,7 @@ class ElasticsearchInputTest < Test::Unit::TestCase
|
|
380
385
|
end
|
381
386
|
|
382
387
|
def test_emit_with_docinfo
|
383
|
-
stub_request(
|
388
|
+
stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
|
384
389
|
with(body: "{\"sort\":[\"_doc\"]}").
|
385
390
|
to_return(status: 200, body: sample_response.to_s,
|
386
391
|
headers: {'Content-Type' => 'application/json'})
|
@@ -399,11 +404,11 @@ class ElasticsearchInputTest < Test::Unit::TestCase
|
|
399
404
|
end
|
400
405
|
|
401
406
|
def test_emit_with_slices
|
402
|
-
stub_request(
|
407
|
+
stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
|
403
408
|
with(body: "{\"sort\":[\"_doc\"],\"slice\":{\"id\":0,\"max\":2}}").
|
404
409
|
to_return(status: 200, body: sample_response.to_s,
|
405
410
|
headers: {'Content-Type' => 'application/json'})
|
406
|
-
stub_request(
|
411
|
+
stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1000").
|
407
412
|
with(body: "{\"sort\":[\"_doc\"],\"slice\":{\"id\":1,\"max\":2}}").
|
408
413
|
to_return(status: 200, body: sample_response.to_s,
|
409
414
|
headers: {'Content-Type' => 'application/json'})
|
@@ -419,12 +424,12 @@ class ElasticsearchInputTest < Test::Unit::TestCase
|
|
419
424
|
end
|
420
425
|
|
421
426
|
def test_emit_with_size
|
422
|
-
stub_request(
|
427
|
+
stub_request(@http_method, "http://localhost:9200/fluentd/_search?scroll=1m&size=1").
|
423
428
|
with(body: "{\"sort\":[\"_doc\"]}").
|
424
429
|
to_return(status: 200, body: sample_scroll_response.to_s,
|
425
430
|
headers: {'Content-Type' => 'application/json'})
|
426
431
|
connection = 0
|
427
|
-
scroll_request = stub_request(
|
432
|
+
scroll_request = stub_request(@http_method, "http://localhost:9200/_search/scroll?scroll=1m").
|
428
433
|
with(
|
429
434
|
body: "{\"scroll_id\":\"WomkoUKG0QPB679Ulo6TqQgh3pIGRUmrl9qXXGK3EeiQh9rbYNasTkspZQcJ01uz\"}") do
|
430
435
|
connection += 1
|
@@ -707,7 +707,10 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
707
707
|
Fluent::Plugin::ElasticsearchOutput.module_eval(<<-CODE)
|
708
708
|
def detect_es_major_version
|
709
709
|
@_es_info ||= client.info
|
710
|
-
@_es_info
|
710
|
+
unless version = @_es_info.dig("version", "number")
|
711
|
+
version = @default_elasticsearch_version
|
712
|
+
end
|
713
|
+
version.to_i
|
711
714
|
end
|
712
715
|
CODE
|
713
716
|
Fluent::Plugin::ElasticsearchOutput.module_eval(<<-CODE)
|
@@ -753,7 +756,10 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
753
756
|
Fluent::Plugin::ElasticsearchOutput.module_eval(<<-CODE)
|
754
757
|
def detect_es_major_version
|
755
758
|
@_es_info ||= client.info
|
756
|
-
@_es_info
|
759
|
+
unless version = @_es_info.dig("version", "number")
|
760
|
+
version = @default_elasticsearch_version
|
761
|
+
end
|
762
|
+
version.to_i
|
757
763
|
end
|
758
764
|
CODE
|
759
765
|
Fluent::Plugin::ElasticsearchOutput.module_eval(<<-CODE)
|
@@ -1053,7 +1059,7 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
1053
1059
|
assert_requested(:put, "https://logs.google.com:777/es//_template/logstash", times: 1)
|
1054
1060
|
end
|
1055
1061
|
|
1056
|
-
def
|
1062
|
+
def test_template_create_with_rollover_index_and_default_ilm_on_logstash_format
|
1057
1063
|
cwd = File.dirname(__FILE__)
|
1058
1064
|
template_file = File.join(cwd, 'test_template.json')
|
1059
1065
|
|
@@ -1067,60 +1073,67 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
1067
1073
|
template_name logstash
|
1068
1074
|
template_file #{template_file}
|
1069
1075
|
index_date_pattern now/w{xxxx.ww}
|
1070
|
-
index_name logstash
|
1071
1076
|
enable_ilm true
|
1072
|
-
|
1073
|
-
|
1077
|
+
logstash_format true
|
1078
|
+
application_name log
|
1074
1079
|
}
|
1075
1080
|
|
1081
|
+
date_str = Time.now.strftime("%Y.%m.%d")
|
1076
1082
|
# connection start
|
1077
1083
|
stub_request(:head, "https://logs.google.com:777/es//").
|
1078
1084
|
with(basic_auth: ['john', 'doe']).
|
1079
1085
|
to_return(:status => 200, :body => "", :headers => {})
|
1080
1086
|
# check if template exists
|
1081
|
-
stub_request(:get, "https://logs.google.com:777/es//_template/logstash").
|
1087
|
+
stub_request(:get, "https://logs.google.com:777/es//_template/logstash-#{date_str}").
|
1082
1088
|
with(basic_auth: ['john', 'doe']).
|
1083
1089
|
to_return(:status => 404, :body => "", :headers => {})
|
1084
1090
|
# creation
|
1085
|
-
stub_request(:put, "https://logs.google.com:777/es//_template/logstash").
|
1091
|
+
stub_request(:put, "https://logs.google.com:777/es//_template/logstash-#{date_str}").
|
1086
1092
|
with(basic_auth: ['john', 'doe']).
|
1087
1093
|
to_return(:status => 200, :body => "", :headers => {})
|
1088
1094
|
# check if alias exists
|
1089
|
-
stub_request(:head, "https://logs.google.com:777/es//_alias/logstash").
|
1095
|
+
stub_request(:head, "https://logs.google.com:777/es//_alias/logstash-#{date_str}").
|
1090
1096
|
with(basic_auth: ['john', 'doe']).
|
1091
1097
|
to_return(:status => 404, :body => "", :headers => {})
|
1092
|
-
stub_request(:get, "https://logs.google.com:777/es//_template/logstash").
|
1098
|
+
stub_request(:get, "https://logs.google.com:777/es//_template/logstash-#{date_str}").
|
1093
1099
|
with(basic_auth: ['john', 'doe']).
|
1094
1100
|
to_return(status: 404, body: "", headers: {})
|
1095
|
-
stub_request(:put, "https://logs.google.com:777/es//_template/logstash").
|
1101
|
+
stub_request(:put, "https://logs.google.com:777/es//_template/logstash-#{date_str}").
|
1096
1102
|
with(basic_auth: ['john', 'doe'],
|
1097
|
-
body: "{\"settings\":{\"number_of_shards\":1,\"index.lifecycle.name\":\"logstash-policy\",\"index.lifecycle.rollover_alias\":\"logstash\"},\"mappings\":{\"type1\":{\"_source\":{\"enabled\":false},\"properties\":{\"host_name\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"created_at\":{\"type\":\"date\",\"format\":\"EEE MMM dd HH:mm:ss Z YYYY\"}}}},\"index_patterns\":\"logstash-*\",\"order\":
|
1103
|
+
body: "{\"settings\":{\"number_of_shards\":1,\"index.lifecycle.name\":\"logstash-policy\",\"index.lifecycle.rollover_alias\":\"logstash-log-#{date_str}\"},\"mappings\":{\"type1\":{\"_source\":{\"enabled\":false},\"properties\":{\"host_name\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"created_at\":{\"type\":\"date\",\"format\":\"EEE MMM dd HH:mm:ss Z YYYY\"}}}},\"index_patterns\":\"logstash-log-#{date_str}-*\",\"order\":53}").
|
1098
1104
|
to_return(status: 200, body: "", headers: {})
|
1099
1105
|
# put the alias for the index
|
1100
|
-
stub_request(:put, "https://logs.google.com:777/es//%3Clogstash-
|
1106
|
+
stub_request(:put, "https://logs.google.com:777/es//%3Clogstash-log-#{date_str}-000001%3E").
|
1101
1107
|
with(basic_auth: ['john', 'doe']).
|
1102
1108
|
to_return(:status => 200, :body => "", :headers => {})
|
1103
|
-
|
1109
|
+
|
1110
|
+
stub_request(:put, "https://logs.google.com:777/es//%3Clogstash-log-#{date_str}-000001%3E/#{alias_endpoint}/logstash-#{date_str}").
|
1104
1111
|
with(basic_auth: ['john', 'doe'],
|
1105
|
-
:
|
1106
|
-
to_return(:
|
1112
|
+
body: "{\"aliases\":{\"logstash-#{date_str}\":{\"is_write_index\":true}}}").
|
1113
|
+
to_return(status: 200, body: "", headers: {})
|
1107
1114
|
stub_request(:get, "https://logs.google.com:777/es//_xpack").
|
1108
1115
|
with(basic_auth: ['john', 'doe']).
|
1109
1116
|
to_return(:status => 200, :body => '{"features":{"ilm":{"available":true,"enabled":true}}}', :headers => {"Content-Type"=> "application/json"})
|
1110
1117
|
stub_request(:get, "https://logs.google.com:777/es//_ilm/policy/logstash-policy").
|
1111
1118
|
with(basic_auth: ['john', 'doe']).
|
1112
|
-
to_return(:status =>
|
1119
|
+
to_return(:status => 404, :body => "", :headers => {})
|
1113
1120
|
stub_request(:put, "https://logs.google.com:777/es//_ilm/policy/logstash-policy").
|
1114
1121
|
with(basic_auth: ['john', 'doe'],
|
1115
|
-
:body => "{\"policy\":{\"phases\":{\"hot\":{\"actions\":{\"rollover\":{\"max_size\":\"
|
1122
|
+
:body => "{\"policy\":{\"phases\":{\"hot\":{\"actions\":{\"rollover\":{\"max_size\":\"50gb\",\"max_age\":\"30d\"}}}}}}").
|
1116
1123
|
to_return(:status => 200, :body => "", :headers => {})
|
1117
1124
|
|
1118
1125
|
driver(config)
|
1119
1126
|
|
1120
|
-
|
1127
|
+
elastic_request = stub_elastic("https://logs.google.com:777/es//_bulk")
|
1128
|
+
driver.run(default_tag: 'test') do
|
1129
|
+
driver.feed(sample_record)
|
1130
|
+
end
|
1131
|
+
assert_requested(:put, "https://logs.google.com:777/es//_template/logstash-#{date_str}", times: 1)
|
1132
|
+
|
1133
|
+
assert_requested(elastic_request)
|
1121
1134
|
end
|
1122
1135
|
|
1123
|
-
def
|
1136
|
+
def test_template_create_with_rollover_index_and_default_ilm_and_ilm_policy_overwrite
|
1124
1137
|
cwd = File.dirname(__FILE__)
|
1125
1138
|
template_file = File.join(cwd, 'test_template.json')
|
1126
1139
|
|
@@ -1134,9 +1147,10 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
1134
1147
|
template_name logstash
|
1135
1148
|
template_file #{template_file}
|
1136
1149
|
index_date_pattern now/w{xxxx.ww}
|
1137
|
-
deflector_alias myapp_deflector
|
1138
1150
|
index_name logstash
|
1139
1151
|
enable_ilm true
|
1152
|
+
ilm_policy_overwrite true
|
1153
|
+
ilm_policy {"policy":{"phases":{"hot":{"actions":{"rollover":{"max_size":"60gb","max_age": "45d"}}}}}}
|
1140
1154
|
}
|
1141
1155
|
|
1142
1156
|
# connection start
|
@@ -1152,38 +1166,63 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
1152
1166
|
with(basic_auth: ['john', 'doe']).
|
1153
1167
|
to_return(:status => 200, :body => "", :headers => {})
|
1154
1168
|
# check if alias exists
|
1155
|
-
stub_request(:head, "https://logs.google.com:777/es//_alias/
|
1169
|
+
stub_request(:head, "https://logs.google.com:777/es//_alias/logstash").
|
1156
1170
|
with(basic_auth: ['john', 'doe']).
|
1157
1171
|
to_return(:status => 404, :body => "", :headers => {})
|
1158
|
-
stub_request(:get, "https://logs.google.com:777/es//_template/
|
1172
|
+
stub_request(:get, "https://logs.google.com:777/es//_template/logstash").
|
1159
1173
|
with(basic_auth: ['john', 'doe']).
|
1160
1174
|
to_return(status: 404, body: "", headers: {})
|
1161
|
-
stub_request(:put, "https://logs.google.com:777/es//_template/
|
1175
|
+
stub_request(:put, "https://logs.google.com:777/es//_template/logstash").
|
1162
1176
|
with(basic_auth: ['john', 'doe'],
|
1163
|
-
body: "{\"settings\":{\"number_of_shards\":1,\"index.lifecycle.name\":\"logstash-policy\",\"index.lifecycle.rollover_alias\":\"
|
1177
|
+
body: "{\"settings\":{\"number_of_shards\":1,\"index.lifecycle.name\":\"logstash-policy\",\"index.lifecycle.rollover_alias\":\"logstash\"},\"mappings\":{\"type1\":{\"_source\":{\"enabled\":false},\"properties\":{\"host_name\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"created_at\":{\"type\":\"date\",\"format\":\"EEE MMM dd HH:mm:ss Z YYYY\"}}}},\"index_patterns\":\"logstash-*\",\"order\":51}").
|
1164
1178
|
to_return(status: 200, body: "", headers: {})
|
1165
1179
|
# put the alias for the index
|
1166
1180
|
stub_request(:put, "https://logs.google.com:777/es//%3Clogstash-default-%7Bnow%2Fw%7Bxxxx.ww%7D%7D-000001%3E").
|
1167
1181
|
with(basic_auth: ['john', 'doe']).
|
1168
1182
|
to_return(:status => 200, :body => "", :headers => {})
|
1169
|
-
stub_request(:put, "https://logs.google.com:777/es//%3Clogstash-default-%7Bnow%2Fw%7Bxxxx.ww%7D%7D-000001%3E/#{alias_endpoint}/
|
1183
|
+
stub_request(:put, "https://logs.google.com:777/es//%3Clogstash-default-%7Bnow%2Fw%7Bxxxx.ww%7D%7D-000001%3E/#{alias_endpoint}/logstash").
|
1170
1184
|
with(basic_auth: ['john', 'doe'],
|
1171
|
-
:body => "{\"aliases\":{\"
|
1185
|
+
:body => "{\"aliases\":{\"logstash\":{\"is_write_index\":true}}}").
|
1172
1186
|
to_return(:status => 200, :body => "", :headers => {})
|
1173
1187
|
stub_request(:get, "https://logs.google.com:777/es//_xpack").
|
1174
1188
|
with(basic_auth: ['john', 'doe']).
|
1175
1189
|
to_return(:status => 200, :body => '{"features":{"ilm":{"available":true,"enabled":true}}}', :headers => {"Content-Type"=> "application/json"})
|
1176
1190
|
stub_request(:get, "https://logs.google.com:777/es//_ilm/policy/logstash-policy").
|
1177
1191
|
with(basic_auth: ['john', 'doe']).
|
1178
|
-
to_return(:status =>
|
1192
|
+
to_return(:status => 200, :body => "", :headers => {})
|
1179
1193
|
stub_request(:put, "https://logs.google.com:777/es//_ilm/policy/logstash-policy").
|
1180
1194
|
with(basic_auth: ['john', 'doe'],
|
1181
|
-
:body => "{\"policy\":{\"phases\":{\"hot\":{\"actions\":{\"rollover\":{\"max_size\":\"
|
1195
|
+
:body => "{\"policy\":{\"phases\":{\"hot\":{\"actions\":{\"rollover\":{\"max_size\":\"60gb\",\"max_age\":\"45d\"}}}}}}").
|
1182
1196
|
to_return(:status => 200, :body => "", :headers => {})
|
1183
1197
|
|
1184
1198
|
driver(config)
|
1185
1199
|
|
1186
|
-
assert_requested(:put, "https://logs.google.com:777/es//_template/
|
1200
|
+
assert_requested(:put, "https://logs.google.com:777/es//_template/logstash", times: 1)
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
def test_template_create_with_rollover_index_and_default_ilm_with_deflector_alias
|
1204
|
+
cwd = File.dirname(__FILE__)
|
1205
|
+
template_file = File.join(cwd, 'test_template.json')
|
1206
|
+
|
1207
|
+
config = %{
|
1208
|
+
host logs.google.com
|
1209
|
+
port 777
|
1210
|
+
scheme https
|
1211
|
+
path /es/
|
1212
|
+
user john
|
1213
|
+
password doe
|
1214
|
+
template_name logstash
|
1215
|
+
template_file #{template_file}
|
1216
|
+
index_date_pattern now/w{xxxx.ww}
|
1217
|
+
deflector_alias myapp_deflector
|
1218
|
+
index_name logstash
|
1219
|
+
enable_ilm true
|
1220
|
+
}
|
1221
|
+
|
1222
|
+
# Should raise error because multiple alias indices IllegalArgument Error on executing ILM feature
|
1223
|
+
assert_raise(Fluent::ConfigError) do
|
1224
|
+
driver(config)
|
1225
|
+
end
|
1187
1226
|
end
|
1188
1227
|
|
1189
1228
|
def test_template_create_with_rollover_index_and_default_ilm_with_empty_index_date_pattern
|
@@ -1607,6 +1646,83 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
1607
1646
|
|
1608
1647
|
assert_requested(elastic_request)
|
1609
1648
|
end
|
1649
|
+
|
1650
|
+
def test_template_create_with_rollover_index_and_default_ilm_and_custom_and_time_placeholders
|
1651
|
+
cwd = File.dirname(__FILE__)
|
1652
|
+
template_file = File.join(cwd, 'test_template.json')
|
1653
|
+
|
1654
|
+
config = Fluent::Config::Element.new(
|
1655
|
+
'ROOT', '', {
|
1656
|
+
'@type' => 'elasticsearch',
|
1657
|
+
'host' => 'logs.google.com',
|
1658
|
+
'port' => 777,
|
1659
|
+
'scheme' => "https",
|
1660
|
+
'path' => "/es/",
|
1661
|
+
'user' => 'john',
|
1662
|
+
'password' => 'doe',
|
1663
|
+
'template_name' => 'logstash',
|
1664
|
+
'template_file' => "#{template_file}",
|
1665
|
+
'index_date_pattern' => 'now/w{xxxx.ww}',
|
1666
|
+
'index_name' => "${taskDef}-%Y.%m",
|
1667
|
+
'enable_ilm' => true,
|
1668
|
+
}, [
|
1669
|
+
Fluent::Config::Element.new('buffer', 'tag, time, taskDef', {
|
1670
|
+
'chunk_keys' => ['tag', 'time', 'taskDef'],
|
1671
|
+
'timekey' => 3600,
|
1672
|
+
}, [])
|
1673
|
+
]
|
1674
|
+
)
|
1675
|
+
|
1676
|
+
task_def_value = "task_definition"
|
1677
|
+
date_str = Time.now.strftime("%Y.%m")
|
1678
|
+
# connection start
|
1679
|
+
stub_request(:head, "https://logs.google.com:777/es//").
|
1680
|
+
with(basic_auth: ['john', 'doe']).
|
1681
|
+
to_return(:status => 200, :body => "", :headers => {})
|
1682
|
+
# check if template exists
|
1683
|
+
stub_request(:get, "https://logs.google.com:777/es//_template/#{task_def_value}-#{date_str}").
|
1684
|
+
with(basic_auth: ['john', 'doe']).
|
1685
|
+
to_return(:status => 404, :body => "", :headers => {})
|
1686
|
+
# creation
|
1687
|
+
stub_request(:put, "https://logs.google.com:777/es//_template/#{task_def_value}-#{date_str}").
|
1688
|
+
with(basic_auth: ['john', 'doe'],
|
1689
|
+
body: "{\"settings\":{\"number_of_shards\":1,\"index.lifecycle.name\":\"logstash-policy\",\"index.lifecycle.rollover_alias\":\"#{task_def_value}-#{date_str}\"},\"mappings\":{\"type1\":{\"_source\":{\"enabled\":false},\"properties\":{\"host_name\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"created_at\":{\"type\":\"date\",\"format\":\"EEE MMM dd HH:mm:ss Z YYYY\"}}}},\"index_patterns\":\"#{task_def_value}-#{date_str}-*\",\"order\":52}").
|
1690
|
+
to_return(:status => 200, :body => "", :headers => {})
|
1691
|
+
# check if alias exists
|
1692
|
+
stub_request(:head, "https://logs.google.com:777/es//_alias/#{task_def_value}-#{date_str}").
|
1693
|
+
with(basic_auth: ['john', 'doe']).
|
1694
|
+
to_return(:status => 404, :body => "", :headers => {})
|
1695
|
+
# put the alias for the index
|
1696
|
+
stub_request(:put, "https://logs.google.com:777/es//%3C#{task_def_value}-#{date_str}-default-%7Bnow%2Fw%7Bxxxx.ww%7D%7D-000001%3E").
|
1697
|
+
with(basic_auth: ['john', 'doe']).
|
1698
|
+
to_return(:status => 200, :body => "", :headers => {})
|
1699
|
+
stub_request(:put, "https://logs.google.com:777/es//%3C#{task_def_value}-#{date_str}-default-%7Bnow%2Fw%7Bxxxx.ww%7D%7D-000001%3E/#{alias_endpoint}/#{task_def_value}-#{date_str}").
|
1700
|
+
with(basic_auth: ['john', 'doe'],
|
1701
|
+
:body => "{\"aliases\":{\"#{task_def_value}-#{date_str}\":{\"is_write_index\":true}}}").
|
1702
|
+
to_return(:status => 200, :body => "", :headers => {})
|
1703
|
+
stub_request(:get, "https://logs.google.com:777/es//_xpack").
|
1704
|
+
with(basic_auth: ['john', 'doe']).
|
1705
|
+
to_return(:status => 200, :body => '{"features":{"ilm":{"available":true,"enabled":true}}}', :headers => {"Content-Type"=> "application/json"})
|
1706
|
+
stub_request(:get, "https://logs.google.com:777/es//_ilm/policy/logstash-policy").
|
1707
|
+
with(basic_auth: ['john', 'doe']).
|
1708
|
+
to_return(:status => 404, :body => "", :headers => {})
|
1709
|
+
stub_request(:put, "https://logs.google.com:777/es//_ilm/policy/logstash-policy").
|
1710
|
+
with(basic_auth: ['john', 'doe'],
|
1711
|
+
:body => "{\"policy\":{\"phases\":{\"hot\":{\"actions\":{\"rollover\":{\"max_size\":\"50gb\",\"max_age\":\"30d\"}}}}}}").
|
1712
|
+
to_return(:status => 200, :body => "", :headers => {})
|
1713
|
+
|
1714
|
+
driver(config)
|
1715
|
+
|
1716
|
+
elastic_request = stub_elastic("https://logs.google.com:777/es//_bulk")
|
1717
|
+
driver.run(default_tag: 'test') do
|
1718
|
+
driver.feed(sample_record.merge("taskDef" => task_def_value))
|
1719
|
+
end
|
1720
|
+
assert_equal("#{task_def_value}-#{date_str}", index_cmds.first['index']['_index'])
|
1721
|
+
|
1722
|
+
assert_equal ["#{task_def_value}-#{date_str}"], driver.instance.alias_indexes
|
1723
|
+
|
1724
|
+
assert_requested(elastic_request)
|
1725
|
+
end
|
1610
1726
|
end
|
1611
1727
|
|
1612
1728
|
def test_custom_template_create
|
@@ -1845,6 +1961,7 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
1845
1961
|
application_name myapp
|
1846
1962
|
}
|
1847
1963
|
|
1964
|
+
timestr = Time.now.strftime("%Y.%m.%d")
|
1848
1965
|
# connection start
|
1849
1966
|
stub_request(:head, "https://logs.google.com:777/es//").
|
1850
1967
|
with(basic_auth: ['john', 'doe']).
|
@@ -1858,17 +1975,17 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
1858
1975
|
with(basic_auth: ['john', 'doe']).
|
1859
1976
|
to_return(:status => 200, :body => "", :headers => {})
|
1860
1977
|
# creation of index which can rollover
|
1861
|
-
stub_request(:put, "https://logs.google.com:777/es//%3Cmylogs-myapp
|
1978
|
+
stub_request(:put, "https://logs.google.com:777/es//%3Cmylogs-myapp-#{timestr}-000001%3E").
|
1862
1979
|
with(basic_auth: ['john', 'doe']).
|
1863
1980
|
to_return(:status => 200, :body => "", :headers => {})
|
1864
1981
|
# check if alias exists
|
1865
|
-
timestr = Time.now.strftime("%Y.%m.%d")
|
1866
1982
|
stub_request(:head, "https://logs.google.com:777/es//_alias/mylogs-#{timestr}").
|
1867
1983
|
with(basic_auth: ['john', 'doe']).
|
1868
1984
|
to_return(:status => 404, :body => "", :headers => {})
|
1869
1985
|
# put the alias for the index
|
1870
|
-
stub_request(:put, "https://logs.google.com:777/es//%3Cmylogs-myapp
|
1871
|
-
with(basic_auth: ['john', 'doe']
|
1986
|
+
stub_request(:put, "https://logs.google.com:777/es//%3Cmylogs-myapp-#{timestr}-000001%3E/#{alias_endpoint}/mylogs-#{timestr}").
|
1987
|
+
with(basic_auth: ['john', 'doe'],
|
1988
|
+
body: "{\"aliases\":{\"mylogs-#{timestr}\":{\"is_write_index\":true}}}").
|
1872
1989
|
to_return(:status => 200, :body => "", :headers => {})
|
1873
1990
|
|
1874
1991
|
driver(config)
|
@@ -2051,52 +2168,10 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
2051
2168
|
enable_ilm true
|
2052
2169
|
}
|
2053
2170
|
|
2054
|
-
#
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
# check if template exists
|
2059
|
-
stub_request(:get, "https://logs.google.com:777/es//_template/myapp_alias_template").
|
2060
|
-
with(basic_auth: ['john', 'doe']).
|
2061
|
-
to_return(:status => 404, :body => "", :headers => {})
|
2062
|
-
# creation
|
2063
|
-
stub_request(:put, "https://logs.google.com:777/es//_template/myapp_alias_template").
|
2064
|
-
with(basic_auth: ['john', 'doe']).
|
2065
|
-
to_return(:status => 200, :body => "", :headers => {})
|
2066
|
-
# creation of index which can rollover
|
2067
|
-
stub_request(:put, "https://logs.google.com:777/es//%3Cmylogs-myapp-%7Bnow%2Fw%7Bxxxx.ww%7D%7D-000001%3E").
|
2068
|
-
with(basic_auth: ['john', 'doe']).
|
2069
|
-
to_return(:status => 200, :body => "", :headers => {})
|
2070
|
-
# check if alias exists
|
2071
|
-
stub_request(:head, "https://logs.google.com:777/es//_alias/myapp_deflector").
|
2072
|
-
with(basic_auth: ['john', 'doe']).
|
2073
|
-
to_return(:status => 404, :body => "", :headers => {})
|
2074
|
-
stub_request(:get, "https://logs.google.com:777/es//_template/myapp_deflector").
|
2075
|
-
with(basic_auth: ['john', 'doe']).
|
2076
|
-
to_return(status: 404, body: "", headers: {})
|
2077
|
-
stub_request(:put, "https://logs.google.com:777/es//_template/myapp_deflector").
|
2078
|
-
with(basic_auth: ['john', 'doe'],
|
2079
|
-
body: "{\"order\":6,\"settings\":{\"index.lifecycle.name\":\"fluentd-policy\",\"index.lifecycle.rollover_alias\":\"myapp_deflector\"},\"mappings\":{},\"aliases\":{\"myapp-logs-alias\":{}},\"index_patterns\":\"myapp_deflector-*\"}").
|
2080
|
-
to_return(status: 200, body: "", headers: {})
|
2081
|
-
# put the alias for the index
|
2082
|
-
stub_request(:put, "https://logs.google.com:777/es//%3Cmylogs-myapp-%7Bnow%2Fw%7Bxxxx.ww%7D%7D-000001%3E/#{alias_endpoint}/myapp_deflector").
|
2083
|
-
with(basic_auth: ['john', 'doe'],
|
2084
|
-
:body => "{\"aliases\":{\"myapp_deflector\":{\"is_write_index\":true}}}").
|
2085
|
-
to_return(:status => 200, :body => "", :headers => {})
|
2086
|
-
stub_request(:get, "https://logs.google.com:777/es//_xpack").
|
2087
|
-
with(basic_auth: ['john', 'doe']).
|
2088
|
-
to_return(:status => 200, :body => '{"features":{"ilm":{"available":true,"enabled":true}}}', :headers => {"Content-Type"=> "application/json"})
|
2089
|
-
stub_request(:get, "https://logs.google.com:777/es//_ilm/policy/fluentd-policy").
|
2090
|
-
with(basic_auth: ['john', 'doe']).
|
2091
|
-
to_return(:status => 404, :body => "", :headers => {})
|
2092
|
-
stub_request(:put, "https://logs.google.com:777/es//_ilm/policy/fluentd-policy").
|
2093
|
-
with(basic_auth: ['john', 'doe'],
|
2094
|
-
:body => "{\"policy\":{\"phases\":{\"hot\":{\"actions\":{\"rollover\":{\"max_size\":\"50gb\",\"max_age\":\"30d\"}}}}}}").
|
2095
|
-
to_return(:status => 200, :body => "", :headers => {})
|
2096
|
-
|
2097
|
-
driver(config)
|
2098
|
-
|
2099
|
-
assert_requested(:put, "https://logs.google.com:777/es//_template/myapp_deflector", times: 1)
|
2171
|
+
# Should raise error because multiple alias indices IllegalArgument Error on executing ILM feature
|
2172
|
+
assert_raise(Fluent::ConfigError) do
|
2173
|
+
driver(config)
|
2174
|
+
end
|
2100
2175
|
end
|
2101
2176
|
|
2102
2177
|
def test_custom_template_with_rollover_index_create_and_default_ilm_and_placeholders
|
@@ -2584,7 +2659,7 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
2584
2659
|
assert_requested(:put, "https://logs.google.com:777/es//_template/logstash3", times: 1)
|
2585
2660
|
end
|
2586
2661
|
|
2587
|
-
def
|
2662
|
+
def test_templates_are_also_used
|
2588
2663
|
cwd = File.dirname(__FILE__)
|
2589
2664
|
template_file = File.join(cwd, 'test_template.json')
|
2590
2665
|
|
@@ -2628,8 +2703,8 @@ class ElasticsearchOutputTest < Test::Unit::TestCase
|
|
2628
2703
|
|
2629
2704
|
assert_requested(:put, "https://logs.google.com:777/es//_template/logstash", times: 1)
|
2630
2705
|
|
2631
|
-
|
2632
|
-
|
2706
|
+
assert_requested(:put, "https://logs.google.com:777/es//_template/logstash1")
|
2707
|
+
assert_requested(:put, "https://logs.google.com:777/es//_template/logstash2")
|
2633
2708
|
end
|
2634
2709
|
|
2635
2710
|
def test_templates_can_be_partially_created_if_error_occurs
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-elasticsearch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- diogo
|
8
8
|
- pitr
|
9
9
|
- Hiroshi Hatake
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2020-
|
13
|
+
date: 2020-09-08 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: fluentd
|
@@ -160,6 +160,7 @@ files:
|
|
160
160
|
- lib/fluent/plugin/elasticsearch_constants.rb
|
161
161
|
- lib/fluent/plugin/elasticsearch_error.rb
|
162
162
|
- lib/fluent/plugin/elasticsearch_error_handler.rb
|
163
|
+
- lib/fluent/plugin/elasticsearch_fallback_selector.rb
|
163
164
|
- lib/fluent/plugin/elasticsearch_index_lifecycle_management.rb
|
164
165
|
- lib/fluent/plugin/elasticsearch_index_template.rb
|
165
166
|
- lib/fluent/plugin/elasticsearch_simple_sniffer.rb
|
@@ -172,6 +173,7 @@ files:
|
|
172
173
|
- test/helper.rb
|
173
174
|
- test/plugin/test_alias_template.json
|
174
175
|
- test/plugin/test_elasticsearch_error_handler.rb
|
176
|
+
- test/plugin/test_elasticsearch_fallback_selector.rb
|
175
177
|
- test/plugin/test_elasticsearch_index_lifecycle_management.rb
|
176
178
|
- test/plugin/test_elasticsearch_tls.rb
|
177
179
|
- test/plugin/test_filter_elasticsearch_genid.rb
|
@@ -186,7 +188,7 @@ licenses:
|
|
186
188
|
- Apache-2.0
|
187
189
|
metadata:
|
188
190
|
changelog_uri: https://github.com/uken/fluent-plugin-elasticsearch/blob/master/History.md
|
189
|
-
post_install_message:
|
191
|
+
post_install_message:
|
190
192
|
rdoc_options: []
|
191
193
|
require_paths:
|
192
194
|
- lib
|
@@ -202,13 +204,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
202
204
|
version: '0'
|
203
205
|
requirements: []
|
204
206
|
rubygems_version: 3.1.2
|
205
|
-
signing_key:
|
207
|
+
signing_key:
|
206
208
|
specification_version: 4
|
207
209
|
summary: Elasticsearch output plugin for Fluent event collector
|
208
210
|
test_files:
|
209
211
|
- test/helper.rb
|
210
212
|
- test/plugin/test_alias_template.json
|
211
213
|
- test/plugin/test_elasticsearch_error_handler.rb
|
214
|
+
- test/plugin/test_elasticsearch_fallback_selector.rb
|
212
215
|
- test/plugin/test_elasticsearch_index_lifecycle_management.rb
|
213
216
|
- test/plugin/test_elasticsearch_tls.rb
|
214
217
|
- test/plugin/test_filter_elasticsearch_genid.rb
|