fluent-plugin-elasticsearch 5.1.0 → 5.1.1
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 +5 -0
- data/README.md +13 -1
- data/fluent-plugin-elasticsearch.gemspec +1 -1
- data/lib/fluent/plugin/out_elasticsearch_data_stream.rb +81 -49
- data/test/plugin/test_out_elasticsearch_data_stream.rb +340 -98
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 27d74e7048671def02b98e337c052c395152021a4a3f4c2138d1780c725d09bd
|
4
|
+
data.tar.gz: eb5282b8e688b091700a549c711af2f1959bc9b1b2c4f6fd1b49e3119c62ddb7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a3ad9fa5259fcd1e80a85bdf7d1acd11cd26675d4f47f326100db242f0f9320232530099eb5346e5ea11aba76c4cc66cfc2e97f6393ca95d1227281217283ea
|
7
|
+
data.tar.gz: f97182a9487be71d34ddcd8ec2dd046eca9c6de1cae55d3842feeeaef627f23a05862be4783aee37fe38c84cba3bf984a51fb7fb3e8bad50f1bf0f57c956803e
|
data/History.md
CHANGED
@@ -2,6 +2,11 @@
|
|
2
2
|
|
3
3
|
### [Unreleased]
|
4
4
|
|
5
|
+
### 5.1.1
|
6
|
+
- Report appropriate error for data_stream parameters (#922)
|
7
|
+
- Add ILM and template parameters for data streams (#920)
|
8
|
+
- Support Buffer in Data Stream Output (#917)
|
9
|
+
|
5
10
|
### 5.1.0
|
6
11
|
- Correct default target bytes value (#914)
|
7
12
|
- Handle elasticsearch-ruby 7.14 properly (#913)
|
data/README.md
CHANGED
@@ -1521,7 +1521,7 @@ You can enable this feature by specifying `@type elasticsearch_data_stream`.
|
|
1521
1521
|
data_stream_name test
|
1522
1522
|
```
|
1523
1523
|
|
1524
|
-
When `@type elasticsearch_data_stream` is used, ILM default policy is set to the specified data stream.
|
1524
|
+
When `@type elasticsearch_data_stream` is used, unless specified with `data_stream_ilm_name` and `data_stream_template_name`, ILM default policy is set to the specified data stream.
|
1525
1525
|
Then, the matching index template is also created automatically.
|
1526
1526
|
|
1527
1527
|
### data_stream_name
|
@@ -1529,6 +1529,18 @@ Then, the matching index template is also created automatically.
|
|
1529
1529
|
You can specify Elasticsearch data stream name by this parameter.
|
1530
1530
|
This parameter is mandatory for `elasticsearch_data_stream`.
|
1531
1531
|
|
1532
|
+
### data_stream_template_name
|
1533
|
+
|
1534
|
+
You can specify an existing matching index template for the data stream. If not present, it creates a new matching index template.
|
1535
|
+
|
1536
|
+
Default value is `data_stream_name`.
|
1537
|
+
|
1538
|
+
### data_stream_ilm_name
|
1539
|
+
|
1540
|
+
You can specify the name of an existing ILM policy, which will be applied to the data stream. If not present, it creates a new ILM default policy (unless `data_stream_template_name` is defined, in that case the ILM will be set to the one specified in the matching index template).
|
1541
|
+
|
1542
|
+
Default value is `data_stream_name`.
|
1543
|
+
|
1532
1544
|
There are some limitations about naming rule.
|
1533
1545
|
|
1534
1546
|
In more detail, please refer to the [Path parameters](https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-create-data-stream.html#indices-create-data-stream-api-path-params).
|
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = 'fluent-plugin-elasticsearch'
|
6
|
-
s.version = '5.1.
|
6
|
+
s.version = '5.1.1'
|
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}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
require_relative 'out_elasticsearch'
|
2
3
|
|
3
4
|
module Fluent::Plugin
|
@@ -8,6 +9,8 @@ module Fluent::Plugin
|
|
8
9
|
helpers :event_emitter
|
9
10
|
|
10
11
|
config_param :data_stream_name, :string
|
12
|
+
config_param :data_stream_ilm_name, :string, :default => :data_stream_name
|
13
|
+
config_param :data_stream_template_name, :string, :default => :data_stream_name
|
11
14
|
# Elasticsearch 7.9 or later always support new style of index template.
|
12
15
|
config_set_default :use_legacy_template, false
|
13
16
|
|
@@ -26,7 +29,7 @@ module Fluent::Plugin
|
|
26
29
|
|
27
30
|
# ref. https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-create-data-stream.html
|
28
31
|
unless placeholder?(:data_stream_name_placeholder, @data_stream_name)
|
29
|
-
|
32
|
+
validate_data_stream_parameters
|
30
33
|
else
|
31
34
|
@use_placeholder = true
|
32
35
|
@data_stream_names = []
|
@@ -36,8 +39,8 @@ module Fluent::Plugin
|
|
36
39
|
unless @use_placeholder
|
37
40
|
begin
|
38
41
|
@data_stream_names = [@data_stream_name]
|
39
|
-
create_ilm_policy(@data_stream_name)
|
40
|
-
create_index_template(@data_stream_name)
|
42
|
+
create_ilm_policy(@data_stream_name, @data_stream_template_name, @data_stream_ilm_name, @host)
|
43
|
+
create_index_template(@data_stream_name, @data_stream_template_name, @data_stream_ilm_name, @host)
|
41
44
|
create_data_stream(@data_stream_name)
|
42
45
|
rescue => e
|
43
46
|
raise Fluent::ConfigError, "Failed to create data stream: <#{@data_stream_name}> #{e.message}"
|
@@ -45,31 +48,35 @@ module Fluent::Plugin
|
|
45
48
|
end
|
46
49
|
end
|
47
50
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
def validate_data_stream_parameters
|
52
|
+
{"data_stream_name" => @data_stream_name,
|
53
|
+
"data_stream_template_name"=> @data_stream_template_name,
|
54
|
+
"data_stream_ilm_name" => @data_stream_ilm_name}.each do |parameter, value|
|
55
|
+
unless valid_data_stream_parameters?(value)
|
56
|
+
unless start_with_valid_characters?(value)
|
57
|
+
if not_dots?(value)
|
58
|
+
raise Fluent::ConfigError, "'#{parameter}' must not start with #{INVALID_START_CHRACTERS.join(",")}: <#{value}>"
|
59
|
+
else
|
60
|
+
raise Fluent::ConfigError, "'#{parameter}' must not be . or ..: <#{value}>"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
unless valid_characters?(value)
|
64
|
+
raise Fluent::ConfigError, "'#{parameter}' must not contain invalid characters #{INVALID_CHARACTERS.join(",")}: <#{value}>"
|
65
|
+
end
|
66
|
+
unless lowercase_only?(value)
|
67
|
+
raise Fluent::ConfigError, "'#{parameter}' must be lowercase only: <#{value}>"
|
68
|
+
end
|
69
|
+
if value.bytes.size > 255
|
70
|
+
raise Fluent::ConfigError, "'#{parameter}' must not be longer than 255 bytes: <#{value}>"
|
55
71
|
end
|
56
|
-
end
|
57
|
-
unless valid_characters?
|
58
|
-
raise Fluent::ConfigError, "'data_stream_name' must not contain invalid characters #{INVALID_CHARACTERS.join(",")}: <#{@data_stream_name}>"
|
59
|
-
end
|
60
|
-
unless lowercase_only?
|
61
|
-
raise Fluent::ConfigError, "'data_stream_name' must be lowercase only: <#{@data_stream_name}>"
|
62
|
-
end
|
63
|
-
if @data_stream_name.bytes.size > 255
|
64
|
-
raise Fluent::ConfigError, "'data_stream_name' must not be longer than 255 bytes: <#{@data_stream_name}>"
|
65
72
|
end
|
66
73
|
end
|
67
74
|
end
|
68
75
|
|
69
|
-
def create_ilm_policy(
|
70
|
-
return if data_stream_exist?(
|
76
|
+
def create_ilm_policy(datastream_name, template_name, ilm_name, host)
|
77
|
+
return if data_stream_exist?(datastream_name) or template_exists?(template_name, host) or ilm_policy_exists?(ilm_name)
|
71
78
|
params = {
|
72
|
-
policy_id: "#{
|
79
|
+
policy_id: "#{ilm_name}_policy",
|
73
80
|
body: File.read(File.join(File.dirname(__FILE__), "default-ilm-policy.json"))
|
74
81
|
}
|
75
82
|
retry_operate(@max_retry_putting_template,
|
@@ -79,19 +86,19 @@ module Fluent::Plugin
|
|
79
86
|
end
|
80
87
|
end
|
81
88
|
|
82
|
-
def create_index_template(
|
83
|
-
return if data_stream_exist?(
|
89
|
+
def create_index_template(datastream_name, template_name, ilm_name, host)
|
90
|
+
return if data_stream_exist?(datastream_name) or template_exists?(template_name, host)
|
84
91
|
body = {
|
85
|
-
"index_patterns" => ["#{
|
92
|
+
"index_patterns" => ["#{datastream_name}*"],
|
86
93
|
"data_stream" => {},
|
87
94
|
"template" => {
|
88
95
|
"settings" => {
|
89
|
-
"index.lifecycle.name" => "#{
|
96
|
+
"index.lifecycle.name" => "#{ilm_name}_policy"
|
90
97
|
}
|
91
98
|
}
|
92
99
|
}
|
93
100
|
params = {
|
94
|
-
name:
|
101
|
+
name: template_name,
|
95
102
|
body: body
|
96
103
|
}
|
97
104
|
retry_operate(@max_retry_putting_template,
|
@@ -101,9 +108,9 @@ module Fluent::Plugin
|
|
101
108
|
end
|
102
109
|
end
|
103
110
|
|
104
|
-
def data_stream_exist?(
|
111
|
+
def data_stream_exist?(datastream_name)
|
105
112
|
params = {
|
106
|
-
|
113
|
+
name: datastream_name
|
107
114
|
}
|
108
115
|
begin
|
109
116
|
response = @client.indices.get_data_stream(params)
|
@@ -114,10 +121,10 @@ module Fluent::Plugin
|
|
114
121
|
end
|
115
122
|
end
|
116
123
|
|
117
|
-
def create_data_stream(
|
118
|
-
return if data_stream_exist?(
|
124
|
+
def create_data_stream(datastream_name)
|
125
|
+
return if data_stream_exist?(datastream_name)
|
119
126
|
params = {
|
120
|
-
|
127
|
+
name: datastream_name
|
121
128
|
}
|
122
129
|
retry_operate(@max_retry_putting_template,
|
123
130
|
@fail_on_putting_template_retry_exceed,
|
@@ -126,28 +133,48 @@ module Fluent::Plugin
|
|
126
133
|
end
|
127
134
|
end
|
128
135
|
|
129
|
-
def
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
136
|
+
def ilm_policy_exists?(policy_id)
|
137
|
+
begin
|
138
|
+
@client.ilm.get_policy(policy_id: policy_id)
|
139
|
+
true
|
140
|
+
rescue
|
141
|
+
false
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def template_exists?(name, host = nil)
|
146
|
+
if @use_legacy_template
|
147
|
+
client(host).indices.get_template(:name => name)
|
148
|
+
else
|
149
|
+
client(host).indices.get_index_template(:name => name)
|
150
|
+
end
|
151
|
+
return true
|
152
|
+
rescue Elasticsearch::Transport::Transport::Errors::NotFound
|
153
|
+
return false
|
154
|
+
end
|
155
|
+
|
156
|
+
def valid_data_stream_parameters?(data_stream_parameter)
|
157
|
+
lowercase_only?(data_stream_parameter) and
|
158
|
+
valid_characters?(data_stream_parameter) and
|
159
|
+
start_with_valid_characters?(data_stream_parameter) and
|
160
|
+
not_dots?(data_stream_parameter) and
|
161
|
+
data_stream_parameter.bytes.size <= 255
|
135
162
|
end
|
136
163
|
|
137
|
-
def lowercase_only?
|
138
|
-
|
164
|
+
def lowercase_only?(data_stream_parameter)
|
165
|
+
data_stream_parameter.downcase == data_stream_parameter
|
139
166
|
end
|
140
167
|
|
141
|
-
def valid_characters?
|
142
|
-
not (INVALID_CHARACTERS.each.any? do |v|
|
168
|
+
def valid_characters?(data_stream_parameter)
|
169
|
+
not (INVALID_CHARACTERS.each.any? do |v| data_stream_parameter.include?(v) end)
|
143
170
|
end
|
144
171
|
|
145
|
-
def start_with_valid_characters?
|
146
|
-
not (INVALID_START_CHRACTERS.each.any? do |v|
|
172
|
+
def start_with_valid_characters?(data_stream_parameter)
|
173
|
+
not (INVALID_START_CHRACTERS.each.any? do |v| data_stream_parameter.start_with?(v) end)
|
147
174
|
end
|
148
175
|
|
149
|
-
def not_dots?
|
150
|
-
not (
|
176
|
+
def not_dots?(data_stream_parameter)
|
177
|
+
not (data_stream_parameter == "." or data_stream_parameter == "..")
|
151
178
|
end
|
152
179
|
|
153
180
|
def client_library_version
|
@@ -160,13 +187,18 @@ module Fluent::Plugin
|
|
160
187
|
|
161
188
|
def write(chunk)
|
162
189
|
data_stream_name = @data_stream_name
|
190
|
+
data_stream_template_name = @data_stream_template_name
|
191
|
+
data_stream_ilm_name = @data_stream_ilm_name
|
192
|
+
host = @host
|
163
193
|
if @use_placeholder
|
164
194
|
data_stream_name = extract_placeholders(@data_stream_name, chunk)
|
195
|
+
data_stream_template_name = extract_placeholders(@data_stream_template_name, chunk)
|
196
|
+
data_stream_ilm_name = extract_placeholders(@data_stream_ilm_name, chunk)
|
165
197
|
unless @data_stream_names.include?(data_stream_name)
|
166
198
|
begin
|
167
|
-
create_ilm_policy(data_stream_name)
|
168
|
-
create_index_template(data_stream_name)
|
169
199
|
create_data_stream(data_stream_name)
|
200
|
+
create_ilm_policy(data_stream_name, data_stream_template_name, data_stream_ilm_name, host)
|
201
|
+
create_index_template(data_stream_name, data_stream_template_name, data_stream_ilm_name, host)
|
170
202
|
@data_stream_names << data_stream_name
|
171
203
|
rescue => e
|
172
204
|
raise Fluent::ConfigError, "Failed to create data stream: <#{data_stream_name}> #{e.message}"
|
@@ -200,7 +232,7 @@ module Fluent::Plugin
|
|
200
232
|
log.error "Could not bulk insert to Data Stream: #{data_stream_name} #{response}"
|
201
233
|
end
|
202
234
|
rescue => e
|
203
|
-
|
235
|
+
raise RecoverableRequestFailure, "could not push logs to Elasticsearch cluster (#{data_stream_name}): #{e.message}"
|
204
236
|
end
|
205
237
|
end
|
206
238
|
|
@@ -45,7 +45,7 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
45
45
|
{
|
46
46
|
'data_streams': [
|
47
47
|
{
|
48
|
-
'name' => '
|
48
|
+
'name' => 'foo',
|
49
49
|
'timestamp_field' => {
|
50
50
|
'name' => '@timestamp'
|
51
51
|
}
|
@@ -62,11 +62,11 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
62
62
|
DUPLICATED_DATA_STREAM_EXCEPTION = {"error": {}, "status": 400}
|
63
63
|
NONEXISTENT_DATA_STREAM_EXCEPTION = {"error": {}, "status": 404}
|
64
64
|
|
65
|
-
def stub_ilm_policy(name="
|
65
|
+
def stub_ilm_policy(name="foo_ilm")
|
66
66
|
stub_request(:put, "http://localhost:9200/_ilm/policy/#{name}_policy").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
67
67
|
end
|
68
68
|
|
69
|
-
def stub_index_template(name="
|
69
|
+
def stub_index_template(name="foo_tpl")
|
70
70
|
stub_request(:put, "http://localhost:9200/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
71
71
|
end
|
72
72
|
|
@@ -78,14 +78,42 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
78
78
|
stub_request(:get, "http://localhost:9200/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
79
79
|
end
|
80
80
|
|
81
|
+
def stub_existent_ilm?(name="foo_ilm")
|
82
|
+
stub_request(:get, "http://localhost:9200/_ilm/policy/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
83
|
+
end
|
84
|
+
|
85
|
+
def stub_existent_template?(name="foo_tpl")
|
86
|
+
stub_request(:get, "http://localhost:9200/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
|
87
|
+
end
|
88
|
+
|
81
89
|
def stub_nonexistent_data_stream?(name="foo")
|
82
90
|
stub_request(:get, "http://localhost:9200/_data_stream/#{name}").to_return(:status => [404, Elasticsearch::Transport::Transport::Errors::NotFound])
|
83
91
|
end
|
84
92
|
|
85
|
-
def
|
86
|
-
stub_request(:
|
93
|
+
def stub_nonexistent_ilm?(name="foo_ilm")
|
94
|
+
stub_request(:get, "http://localhost:9200/_ilm/policy/#{name}").to_return(:status => [404, Elasticsearch::Transport::Transport::Errors::NotFound])
|
95
|
+
end
|
96
|
+
|
97
|
+
def stub_nonexistent_template?(name="foo_tpl")
|
98
|
+
stub_request(:get, "http://localhost:9200/_index_template/#{name}").to_return(:status => [404, Elasticsearch::Transport::Transport::Errors::NotFound])
|
99
|
+
end
|
100
|
+
|
101
|
+
def stub_bulk_feed(datastream_name="foo", ilm_name="foo_ilm", template_name="foo_tpl")
|
102
|
+
stub_request(:post, "http://localhost:9200/#{datastream_name}/_bulk").with do |req|
|
103
|
+
# bulk data must be pair of OP and records
|
104
|
+
# {"create": {}}\nhttp://localhost:9200/_ilm/policy/foo_ilm_bar
|
105
|
+
# {"@timestamp": ...}
|
106
|
+
@bulk_records += req.body.split("\n").size / 2
|
107
|
+
end
|
108
|
+
stub_request(:post, "http://localhost:9200/#{ilm_name}/_bulk").with do |req|
|
109
|
+
# bulk data must be pair of OP and records
|
110
|
+
# {"create": {}}\nhttp://localhost:9200/_ilm/policy/foo_ilm_bar
|
111
|
+
# {"@timestamp": ...}
|
112
|
+
@bulk_records += req.body.split("\n").size / 2
|
113
|
+
end
|
114
|
+
stub_request(:post, "http://localhost:9200/#{template_name}/_bulk").with do |req|
|
87
115
|
# bulk data must be pair of OP and records
|
88
|
-
# {"create": {}}\
|
116
|
+
# {"create": {}}\nhttp://localhost:9200/_ilm/policy/foo_ilm_bar
|
89
117
|
# {"@timestamp": ...}
|
90
118
|
@bulk_records += req.body.split("\n").size / 2
|
91
119
|
end
|
@@ -96,12 +124,14 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
96
124
|
stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' } })
|
97
125
|
end
|
98
126
|
|
99
|
-
def stub_default(
|
127
|
+
def stub_default(datastream_name="foo", ilm_name="foo_ilm", template_name="foo_tpl", host="http://localhost:9200")
|
100
128
|
stub_elastic_info(host)
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
129
|
+
stub_nonexistent_ilm?(ilm_name)
|
130
|
+
stub_ilm_policy(ilm_name)
|
131
|
+
stub_nonexistent_template?(template_name)
|
132
|
+
stub_index_template(template_name)
|
133
|
+
stub_nonexistent_data_stream?(datastream_name)
|
134
|
+
stub_data_stream(datastream_name)
|
105
135
|
end
|
106
136
|
|
107
137
|
def data_stream_supported?
|
@@ -121,82 +151,274 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
121
151
|
end
|
122
152
|
end
|
123
153
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
'
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
154
|
+
sub_test_case "invalid uppercase" do
|
155
|
+
def test_stream_name
|
156
|
+
conf = config_element(
|
157
|
+
'ROOT', '', {
|
158
|
+
'@type' => 'elasticsearch_datastream',
|
159
|
+
'data_stream_name' => 'TEST',
|
160
|
+
'data_stream_ilm_name' => 'default-policy',
|
161
|
+
'data_stream_template_name' => 'template'
|
162
|
+
})
|
163
|
+
assert_raise Fluent::ConfigError.new("'data_stream_name' must be lowercase only: <TEST>") do
|
164
|
+
driver(conf)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
def test_stream_ilm_name
|
168
|
+
conf = config_element(
|
169
|
+
'ROOT', '', {
|
170
|
+
'@type' => 'elasticsearch_datastream',
|
171
|
+
'data_stream_name' => 'data_stream',
|
172
|
+
'data_stream_ilm_name' => 'TEST-ILM',
|
173
|
+
'data_stream_template_name' => 'template'
|
174
|
+
})
|
175
|
+
assert_raise Fluent::ConfigError.new("'data_stream_ilm_name' must be lowercase only: <TEST-ILM>") do
|
176
|
+
driver(conf)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
def test_stream_template_name
|
180
|
+
conf = config_element(
|
181
|
+
'ROOT', '', {
|
182
|
+
'@type' => 'elasticsearch_datastream',
|
183
|
+
'data_stream_name' => 'default',
|
184
|
+
'data_stream_ilm_name' => 'default-policy',
|
185
|
+
'data_stream_template_name' => 'TEST-TPL'
|
186
|
+
})
|
187
|
+
assert_raise Fluent::ConfigError.new("'data_stream_template_name' must be lowercase only: <TEST-TPL>") do
|
188
|
+
driver(conf)
|
189
|
+
end
|
132
190
|
end
|
133
191
|
end
|
134
192
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
'
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
193
|
+
sub_test_case "invalid parameters" do
|
194
|
+
data("backslash" => "\\",
|
195
|
+
"slash" => "/",
|
196
|
+
"asterisk" => "*",
|
197
|
+
"question" => "?",
|
198
|
+
"doublequote" => "\"",
|
199
|
+
"lt" => "<",
|
200
|
+
"gt" => ">",
|
201
|
+
"bar" => "|",
|
202
|
+
"space" => " ",
|
203
|
+
"comma" => ",",
|
204
|
+
"sharp" => "#",
|
205
|
+
"colon" => ":")
|
206
|
+
def test_stream_name(data)
|
207
|
+
c, _ = data
|
208
|
+
conf = config_element(
|
209
|
+
'ROOT', '', {
|
210
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
211
|
+
'data_stream_name' => "TEST#{c}",
|
212
|
+
'data_stream_ilm_name' => "default_policy",
|
213
|
+
'data_stream_template_name' => "data_stream"
|
214
|
+
})
|
215
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_CHARACTERS.join(',')
|
216
|
+
assert_raise Fluent::ConfigError.new("'data_stream_name' must not contain invalid characters #{label}: <TEST#{c}>") do
|
217
|
+
driver(conf)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
data("backslash" => "\\",
|
222
|
+
"slash" => "/",
|
223
|
+
"asterisk" => "*",
|
224
|
+
"question" => "?",
|
225
|
+
"doublequote" => "\"",
|
226
|
+
"lt" => "<",
|
227
|
+
"gt" => ">",
|
228
|
+
"bar" => "|",
|
229
|
+
"space" => " ",
|
230
|
+
"comma" => ",",
|
231
|
+
"sharp" => "#",
|
232
|
+
"colon" => ":")
|
233
|
+
def test_stream_ilm_name(data)
|
234
|
+
c, _ = data
|
235
|
+
conf = config_element(
|
236
|
+
'ROOT', '', {
|
237
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
238
|
+
'data_stream_name' => "default",
|
239
|
+
'data_stream_ilm_name' => "TEST#{c}",
|
240
|
+
'data_stream_template_name' => "data_stream"
|
241
|
+
})
|
242
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_CHARACTERS.join(',')
|
243
|
+
assert_raise Fluent::ConfigError.new("'data_stream_ilm_name' must not contain invalid characters #{label}: <TEST#{c}>") do
|
244
|
+
driver(conf)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
data("backslash" => "\\",
|
249
|
+
"slash" => "/",
|
250
|
+
"asterisk" => "*",
|
251
|
+
"question" => "?",
|
252
|
+
"doublequote" => "\"",
|
253
|
+
"lt" => "<",
|
254
|
+
"gt" => ">",
|
255
|
+
"bar" => "|",
|
256
|
+
"space" => " ",
|
257
|
+
"comma" => ",",
|
258
|
+
"sharp" => "#",
|
259
|
+
"colon" => ":")
|
260
|
+
def test_stream_template_name(data)
|
261
|
+
c, _ = data
|
262
|
+
conf = config_element(
|
263
|
+
'ROOT', '', {
|
264
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
265
|
+
'data_stream_name' => "default",
|
266
|
+
'data_stream_ilm_name' => "default_policy",
|
267
|
+
'data_stream_template_name' => "TEST#{c}"
|
268
|
+
})
|
269
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_CHARACTERS.join(',')
|
270
|
+
assert_raise Fluent::ConfigError.new("'data_stream_template_name' must not contain invalid characters #{label}: <TEST#{c}>") do
|
271
|
+
driver(conf)
|
272
|
+
end
|
157
273
|
end
|
158
274
|
end
|
159
275
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
'
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
276
|
+
sub_test_case "invalid start characters" do
|
277
|
+
data("hyphen" => "-",
|
278
|
+
"underscore" => "_",
|
279
|
+
"plus" => "+",
|
280
|
+
"period" => ".")
|
281
|
+
def test_stream_name(data)
|
282
|
+
c, _ = data
|
283
|
+
conf = config_element(
|
284
|
+
'ROOT', '', {
|
285
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
286
|
+
'data_stream_name' => "#{c}TEST",
|
287
|
+
'data_stream_ilm_name' => "default-policy",
|
288
|
+
'data_stream_template_name' => "template"
|
289
|
+
})
|
290
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_START_CHRACTERS.join(',')
|
291
|
+
assert_raise Fluent::ConfigError.new("'data_stream_name' must not start with #{label}: <#{c}TEST>") do
|
292
|
+
driver(conf)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
data("hyphen" => "-",
|
296
|
+
"underscore" => "_",
|
297
|
+
"plus" => "+",
|
298
|
+
"period" => ".")
|
299
|
+
def test_stream_ilm_name(data)
|
300
|
+
c, _ = data
|
301
|
+
conf = config_element(
|
302
|
+
'ROOT', '', {
|
303
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
304
|
+
'data_stream_name' => "default",
|
305
|
+
'data_stream_ilm_name' => "#{c}TEST",
|
306
|
+
'data_stream_template_name' => "template"
|
307
|
+
})
|
308
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_START_CHRACTERS.join(',')
|
309
|
+
assert_raise Fluent::ConfigError.new("'data_stream_ilm_name' must not start with #{label}: <#{c}TEST>") do
|
310
|
+
driver(conf)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
data("hyphen" => "-",
|
314
|
+
"underscore" => "_",
|
315
|
+
"plus" => "+",
|
316
|
+
"period" => ".")
|
317
|
+
def test_stream_template_name(data)
|
318
|
+
c, _ = data
|
319
|
+
conf = config_element(
|
320
|
+
'ROOT', '', {
|
321
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
322
|
+
'data_stream_name' => "default",
|
323
|
+
'data_stream_ilm_name' => "default-policy",
|
324
|
+
'data_stream_template_name' => "#{c}TEST"
|
325
|
+
})
|
326
|
+
label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_START_CHRACTERS.join(',')
|
327
|
+
assert_raise Fluent::ConfigError.new("'data_stream_template_name' must not start with #{label}: <#{c}TEST>") do
|
328
|
+
driver(conf)
|
329
|
+
end
|
174
330
|
end
|
175
331
|
end
|
176
332
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
'
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
333
|
+
sub_test_case "invalid dots" do
|
334
|
+
data("current" => ".",
|
335
|
+
"parents" => "..")
|
336
|
+
def test_stream_name
|
337
|
+
c, _ = data
|
338
|
+
conf = config_element(
|
339
|
+
'ROOT', '', {
|
340
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
341
|
+
'data_stream_name' => "#{c}",
|
342
|
+
'data_stream_ilm_name' => "default-policy",
|
343
|
+
'data_stream_template_name' => "template"
|
344
|
+
})
|
345
|
+
assert_raise Fluent::ConfigError.new("'data_stream_name' must not be . or ..: <#{c}>") do
|
346
|
+
driver(conf)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
data("current" => ".",
|
351
|
+
"parents" => "..")
|
352
|
+
def test_stream_ilm_name
|
353
|
+
c, _ = data
|
354
|
+
conf = config_element(
|
355
|
+
'ROOT', '', {
|
356
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
357
|
+
'data_stream_name' => "default",
|
358
|
+
'data_stream_ilm_name' => "#{c}",
|
359
|
+
'data_stream_template_name' => "template"
|
360
|
+
})
|
361
|
+
assert_raise Fluent::ConfigError.new("'data_stream_ilm_name' must not be . or ..: <#{c}>") do
|
362
|
+
driver(conf)
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
data("current" => ".",
|
367
|
+
"parents" => "..")
|
368
|
+
def test_stream_template_name
|
369
|
+
c, _ = data
|
370
|
+
conf = config_element(
|
371
|
+
'ROOT', '', {
|
372
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
373
|
+
'data_stream_name' => "default",
|
374
|
+
'data_stream_ilm_name' => "default-policy",
|
375
|
+
'data_stream_template_name' => "#{c}"
|
376
|
+
})
|
377
|
+
assert_raise Fluent::ConfigError.new("'data_stream_template_name' must not be . or ..: <#{c}>") do
|
378
|
+
driver(conf)
|
379
|
+
end
|
188
380
|
end
|
189
381
|
end
|
190
382
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
'
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
383
|
+
sub_test_case "invalid length" do
|
384
|
+
def test_stream_name
|
385
|
+
c = "a" * 256
|
386
|
+
conf = config_element(
|
387
|
+
'ROOT', '', {
|
388
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
389
|
+
'data_stream_name' => "#{c}",
|
390
|
+
'data_stream_ilm_name' => "default-policy",
|
391
|
+
'data_stream_template_name' => "template"
|
392
|
+
})
|
393
|
+
assert_raise Fluent::ConfigError.new("'data_stream_name' must not be longer than 255 bytes: <#{c}>") do
|
394
|
+
driver(conf)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
def test_stream_ilm_name
|
398
|
+
c = "a" * 256
|
399
|
+
conf = config_element(
|
400
|
+
'ROOT', '', {
|
401
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
402
|
+
'data_stream_name' => "default",
|
403
|
+
'data_stream_ilm_name' => "#{c}",
|
404
|
+
'data_stream_template_name' => "template"
|
405
|
+
})
|
406
|
+
assert_raise Fluent::ConfigError.new("'data_stream_ilm_name' must not be longer than 255 bytes: <#{c}>") do
|
407
|
+
driver(conf)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
def test_stream_template_name
|
411
|
+
c = "a" * 256
|
412
|
+
conf = config_element(
|
413
|
+
'ROOT', '', {
|
414
|
+
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
415
|
+
'data_stream_name' => "default",
|
416
|
+
'data_stream_ilm_name' => "default-policy",
|
417
|
+
'data_stream_template_name' => "#{c}"
|
418
|
+
})
|
419
|
+
assert_raise Fluent::ConfigError.new("'data_stream_template_name' must not be longer than 255 bytes: <#{c}>") do
|
420
|
+
driver(conf)
|
421
|
+
end
|
200
422
|
end
|
201
423
|
end
|
202
424
|
end
|
@@ -208,7 +430,9 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
208
430
|
conf = config_element(
|
209
431
|
'ROOT', '', {
|
210
432
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
211
|
-
'data_stream_name' => 'foo'
|
433
|
+
'data_stream_name' => 'foo',
|
434
|
+
'data_stream_ilm_name' => "foo_ilm",
|
435
|
+
'data_stream_template_name' => "foo_tpl"
|
212
436
|
})
|
213
437
|
assert_equal "foo", driver(conf).instance.data_stream_name
|
214
438
|
end
|
@@ -224,7 +448,9 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
224
448
|
conf = config_element(
|
225
449
|
'ROOT', '', {
|
226
450
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
227
|
-
'data_stream_name' => 'foo'
|
451
|
+
'data_stream_name' => 'foo',
|
452
|
+
'data_stream_ilm_name' => "foo_ilm",
|
453
|
+
'data_stream_template_name' => "foo_tpl"
|
228
454
|
})
|
229
455
|
assert_equal "foo", driver(conf).instance.data_stream_name
|
230
456
|
end
|
@@ -232,13 +458,17 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
232
458
|
def test_placeholder
|
233
459
|
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
234
460
|
|
235
|
-
|
236
|
-
|
237
|
-
|
461
|
+
dsname = "foo_test"
|
462
|
+
ilmname = "foo_ilm_test"
|
463
|
+
tplname = "foo_tpl_test"
|
464
|
+
stub_default(dsname, ilmname, tplname)
|
465
|
+
stub_bulk_feed(dsname, ilmname, tplname)
|
238
466
|
conf = config_element(
|
239
467
|
'ROOT', '', {
|
240
468
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
241
|
-
'data_stream_name' => 'foo_${tag}'
|
469
|
+
'data_stream_name' => 'foo_${tag}',
|
470
|
+
'data_stream_ilm_name' => "foo_ilm_${tag}",
|
471
|
+
'data_stream_template_name' => "foo_tpl_${tag}"
|
242
472
|
})
|
243
473
|
driver(conf).run(default_tag: 'test') do
|
244
474
|
driver.feed(sample_record)
|
@@ -250,13 +480,17 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
250
480
|
omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
|
251
481
|
|
252
482
|
time = Time.now
|
253
|
-
|
254
|
-
|
255
|
-
|
483
|
+
dsname = "foo_#{time.strftime("%Y%m%d")}"
|
484
|
+
ilmname = "foo_ilm_#{time.strftime("%Y%m%d")}"
|
485
|
+
tplname = "foo_tpl_#{time.strftime("%Y%m%d")}"
|
486
|
+
stub_default(dsname, ilmname, tplname)
|
487
|
+
stub_bulk_feed(dsname, ilmname, tplname)
|
256
488
|
conf = config_element(
|
257
489
|
'ROOT', '', {
|
258
490
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
259
|
-
'data_stream_name' => 'foo_%Y%m%d'
|
491
|
+
'data_stream_name' => 'foo_%Y%m%d',
|
492
|
+
'data_stream_ilm_name' => 'foo_ilm_%Y%m%d',
|
493
|
+
'data_stream_template_name' => 'foo_tpl_%Y%m%d'
|
260
494
|
}, [config_element('buffer', 'time', {
|
261
495
|
'timekey' => '1d'
|
262
496
|
}, [])]
|
@@ -272,14 +506,18 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
272
506
|
|
273
507
|
keys = ["bar", "baz"]
|
274
508
|
keys.each do |key|
|
275
|
-
|
276
|
-
|
277
|
-
|
509
|
+
dsname = "foo_#{key}"
|
510
|
+
ilmname = "foo_ilm_#{key}"
|
511
|
+
tplname = "foo_tpl_#{key}"
|
512
|
+
stub_default(dsname, ilmname, tplname)
|
513
|
+
stub_bulk_feed(dsname, ilmname, tplname)
|
278
514
|
end
|
279
515
|
conf = config_element(
|
280
516
|
'ROOT', '', {
|
281
517
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
282
|
-
'data_stream_name' => 'foo_${key1}'
|
518
|
+
'data_stream_name' => 'foo_${key1}',
|
519
|
+
'data_stream_ilm_name' => 'foo_ilm_${key1}',
|
520
|
+
'data_stream_template_name' => 'foo_tpl_${key1}'
|
283
521
|
}, [config_element('buffer', 'tag,key1', {
|
284
522
|
'timekey' => '1d'
|
285
523
|
}, [])]
|
@@ -301,7 +539,9 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
301
539
|
conf = config_element(
|
302
540
|
'ROOT', '', {
|
303
541
|
'@type' => ELASTIC_DATA_STREAM_TYPE,
|
304
|
-
'data_stream_name' => 'foo'
|
542
|
+
'data_stream_name' => 'foo',
|
543
|
+
'data_stream_ilm_name' => 'foo_ilm',
|
544
|
+
'data_stream_template_name' => 'foo_tpl'
|
305
545
|
})
|
306
546
|
driver(conf).run(default_tag: 'test') do
|
307
547
|
driver.feed(sample_record)
|
@@ -316,14 +556,16 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
|
|
316
556
|
template_file = File.join(cwd, 'test_index_template.json')
|
317
557
|
|
318
558
|
config = %{
|
319
|
-
host
|
320
|
-
port
|
321
|
-
scheme
|
322
|
-
data_stream_name
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
559
|
+
host logs.google.com
|
560
|
+
port 778
|
561
|
+
scheme https
|
562
|
+
data_stream_name foo
|
563
|
+
data_stream_ilm_name foo_ilm
|
564
|
+
data_stream_template_name foo_tpl
|
565
|
+
user john
|
566
|
+
password doe
|
567
|
+
template_name logstash
|
568
|
+
template_file #{template_file}
|
327
569
|
max_retry_putting_template 3
|
328
570
|
}
|
329
571
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-elasticsearch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.1.
|
4
|
+
version: 5.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- diogo
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-10-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: fluentd
|
@@ -223,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
223
223
|
- !ruby/object:Gem::Version
|
224
224
|
version: '0'
|
225
225
|
requirements: []
|
226
|
-
rubygems_version: 3.2.
|
226
|
+
rubygems_version: 3.2.22
|
227
227
|
signing_key:
|
228
228
|
specification_version: 4
|
229
229
|
summary: Elasticsearch output plugin for Fluent event collector
|