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 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