fluent-plugin-elasticsearch 5.1.0 → 5.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 89dfb07388fcdb941bd3dc13a9e481fcb2ecf8f4a0b3c828b6a539f13c90e8ee
4
- data.tar.gz: ee8ac22c05d144076e62311e013fea483d72493d6066f87712b5c325f3c215e7
3
+ metadata.gz: 27d74e7048671def02b98e337c052c395152021a4a3f4c2138d1780c725d09bd
4
+ data.tar.gz: eb5282b8e688b091700a549c711af2f1959bc9b1b2c4f6fd1b49e3119c62ddb7
5
5
  SHA512:
6
- metadata.gz: a69fbfa9c0fab591f55656d87cc99aa003aa4e3b7a7d1b2819bd385e70d0c67d7b91dfff0fa42cfeafe94b6fe8f467b069ed075a2776809d0615f6e243f8c355
7
- data.tar.gz: 572585eeb9e939d2b08e5fe0590bd25f02b8390a730d9f3012c44604b33123d9372cf59ac50a108119b413f3d718e2a606a0b21dc62f676199329e3b12c6073c
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.0'
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
- validate_data_stream_name
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 validate_data_stream_name
49
- unless valid_data_stream_name?
50
- unless start_with_valid_characters?
51
- if not_dots?
52
- raise Fluent::ConfigError, "'data_stream_name' must not start with #{INVALID_START_CHRACTERS.join(",")}: <#{@data_stream_name}>"
53
- else
54
- raise Fluent::ConfigError, "'data_stream_name' must not be . or ..: <#{@data_stream_name}>"
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(name)
70
- return if data_stream_exist?(name)
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: "#{name}_policy",
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(name)
83
- return if data_stream_exist?(name)
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" => ["#{name}*"],
92
+ "index_patterns" => ["#{datastream_name}*"],
86
93
  "data_stream" => {},
87
94
  "template" => {
88
95
  "settings" => {
89
- "index.lifecycle.name" => "#{name}_policy"
96
+ "index.lifecycle.name" => "#{ilm_name}_policy"
90
97
  }
91
98
  }
92
99
  }
93
100
  params = {
94
- name: 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?(name)
111
+ def data_stream_exist?(datastream_name)
105
112
  params = {
106
- "name": name
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(name)
118
- return if data_stream_exist?(name)
124
+ def create_data_stream(datastream_name)
125
+ return if data_stream_exist?(datastream_name)
119
126
  params = {
120
- "name": name
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 valid_data_stream_name?
130
- lowercase_only? and
131
- valid_characters? and
132
- start_with_valid_characters? and
133
- not_dots? and
134
- @data_stream_name.bytes.size <= 255
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
- @data_stream_name.downcase == @data_stream_name
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| @data_stream_name.include?(v) end)
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| @data_stream_name.start_with?(v) end)
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 (@data_stream_name == "." or @data_stream_name == "..")
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
- log.error "Could not bulk insert to Data Stream: #{data_stream_name} #{e.message}"
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' => 'my-data-stream',
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="foo")
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="foo")
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 stub_bulk_feed(name="foo")
86
- stub_request(:post, "http://localhost:9200/#{name}/_bulk").with do |req|
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": {}}\n
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(name="foo", host="http://localhost:9200")
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
- stub_ilm_policy(name)
102
- stub_index_template(name)
103
- stub_nonexistent_data_stream?(name)
104
- stub_data_stream(name)
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
- def test_invalid_uppercase
125
- conf = config_element(
126
- 'ROOT', '', {
127
- '@type' => 'elasticsearch_datastream',
128
- 'data_stream_name' => 'TEST'
129
- })
130
- assert_raise Fluent::ConfigError.new("'data_stream_name' must be lowercase only: <TEST>") do
131
- driver(conf)
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
- data("backslash" => "\\",
136
- "slash" => "/",
137
- "asterisk" => "*",
138
- "question" => "?",
139
- "doublequote" => "\"",
140
- "lt" => "<",
141
- "gt" => ">",
142
- "bar" => "|",
143
- "space" => " ",
144
- "comma" => ",",
145
- "sharp" => "#",
146
- "colon" => ":")
147
- def test_invalid_characters(data)
148
- c, _ = data
149
- conf = config_element(
150
- 'ROOT', '', {
151
- '@type' => ELASTIC_DATA_STREAM_TYPE,
152
- 'data_stream_name' => "TEST#{c}"
153
- })
154
- label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_CHARACTERS.join(',')
155
- assert_raise Fluent::ConfigError.new("'data_stream_name' must not contain invalid characters #{label}: <TEST#{c}>") do
156
- driver(conf)
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
- data("hyphen" => "-",
161
- "underscore" => "_",
162
- "plus" => "+",
163
- "period" => ".")
164
- def test_invalid_start_characters(data)
165
- c, _ = data
166
- conf = config_element(
167
- 'ROOT', '', {
168
- '@type' => ELASTIC_DATA_STREAM_TYPE,
169
- 'data_stream_name' => "#{c}TEST"
170
- })
171
- label = Fluent::Plugin::ElasticsearchOutputDataStream::INVALID_START_CHRACTERS.join(',')
172
- assert_raise Fluent::ConfigError.new("'data_stream_name' must not start with #{label}: <#{c}TEST>") do
173
- driver(conf)
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
- data("current" => ".",
178
- "parents" => "..")
179
- def test_invalid_dots
180
- c, _ = data
181
- conf = config_element(
182
- 'ROOT', '', {
183
- '@type' => ELASTIC_DATA_STREAM_TYPE,
184
- 'data_stream_name' => "#{c}"
185
- })
186
- assert_raise Fluent::ConfigError.new("'data_stream_name' must not be . or ..: <#{c}>") do
187
- driver(conf)
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
- def test_invalid_length
192
- c = "a" * 256
193
- conf = config_element(
194
- 'ROOT', '', {
195
- '@type' => ELASTIC_DATA_STREAM_TYPE,
196
- 'data_stream_name' => "#{c}"
197
- })
198
- assert_raise Fluent::ConfigError.new("'data_stream_name' must not be longer than 255 bytes: <#{c}>") do
199
- driver(conf)
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
- name = "foo_test"
236
- stub_default(name)
237
- stub_bulk_feed(name)
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
- name = "foo_#{time.strftime("%Y%m%d")}"
254
- stub_default(name)
255
- stub_bulk_feed(name)
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
- name = "foo_#{key}"
276
- stub_default(name)
277
- stub_bulk_feed(name)
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 logs.google.com
320
- port 778
321
- scheme https
322
- data_stream_name foo
323
- user john
324
- password doe
325
- template_name logstash
326
- template_file #{template_file}
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.0
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-08-19 00:00:00.000000000 Z
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.3
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