fluent-plugin-elasticsearch 5.1.0 → 5.1.4

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: 9cbe785cfd5534abf0b55d8207eae176d1dd02d5ef7a3092e9f0ef3c6d588e7f
4
+ data.tar.gz: c12b413d1415ac38a6d119ff1f0ca106b1d4f1017f206ce72d97a74abe819551
5
5
  SHA512:
6
- metadata.gz: a69fbfa9c0fab591f55656d87cc99aa003aa4e3b7a7d1b2819bd385e70d0c67d7b91dfff0fa42cfeafe94b6fe8f467b069ed075a2776809d0615f6e243f8c355
7
- data.tar.gz: 572585eeb9e939d2b08e5fe0590bd25f02b8390a730d9f3012c44604b33123d9372cf59ac50a108119b413f3d718e2a606a0b21dc62f676199329e3b12c6073c
6
+ metadata.gz: d30472143db2451da2eca168b22086d157abb7e62c26f1df5afa2ab4ed23a250a2b81fd04424f260dbfe996cc0a4794504e0c4262efc7969db363be02c79bcf9
7
+ data.tar.gz: 9fd7a57fe732f18b6f568a96052ba7a5bf51423e93072ba230c7a57866b828dfe07e16b11f937c5d84d0cb01619fe027ccd80c0a0a4fb939d94a41f127ff5e3c
data/History.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  ### [Unreleased]
4
4
 
5
+ ### 5.1.4
6
+ - Handle ES8 or above more strictly (#931)
7
+ - fixing double "\_policy" in index lifecycle management policy for elasticsearch\_data\_stream output (#930)
8
+
9
+ ### 5.1.3
10
+ - fixing execution order for dynamic data stream creation (#928)
11
+
12
+ ### 5.1.2
13
+ - Fix default values of datastream parameters (#926)
14
+
15
+ ### 5.1.1
16
+ - Report appropriate error for data_stream parameters (#922)
17
+ - Add ILM and template parameters for data streams (#920)
18
+ - Support Buffer in Data Stream Output (#917)
19
+
5
20
  ### 5.1.0
6
21
  - Correct default target bytes value (#914)
7
22
  - 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.4'
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}
@@ -987,12 +987,12 @@ EOC
987
987
  elsif @last_seen_major_version == 7
988
988
  log.warn "Detected ES 7.x: `_doc` will be used as the document `_type`."
989
989
  target_type = '_doc'.freeze
990
- elsif @last_seen_major_version >=8
990
+ elsif @last_seen_major_version >= 8
991
991
  log.debug "Detected ES 8.x or above: document type will not be used."
992
992
  target_type = nil
993
993
  end
994
994
  else
995
- if @suppress_type_name && @last_seen_major_version >= 7
995
+ if @suppress_type_name && @last_seen_major_version == 7
996
996
  target_type = nil
997
997
  elsif @last_seen_major_version == 7 && @type_name != DEFAULT_TYPE_NAME_ES_7x
998
998
  log.warn "Detected ES 7.x: `_doc` will be used as the document `_type`."
@@ -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 => nil
13
+ config_param :data_stream_template_name, :string, :default => nil
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
 
@@ -24,9 +27,12 @@ module Fluent::Plugin
24
27
  raise Fluent::ConfigError, "'elasticsearch/api', 'elasticsearch/xpack' are required for <@elasticsearch_data_stream>."
25
28
  end
26
29
 
30
+ @data_stream_ilm_name = "#{@data_stream_name}_policy" if @data_stream_ilm_name.nil?
31
+ @data_stream_template_name = "#{@data_stream_name}_template" if @data_stream_template_name.nil?
32
+
27
33
  # ref. https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-create-data-stream.html
28
34
  unless placeholder?(:data_stream_name_placeholder, @data_stream_name)
29
- validate_data_stream_name
35
+ validate_data_stream_parameters
30
36
  else
31
37
  @use_placeholder = true
32
38
  @data_stream_names = []
@@ -36,8 +42,8 @@ module Fluent::Plugin
36
42
  unless @use_placeholder
37
43
  begin
38
44
  @data_stream_names = [@data_stream_name]
39
- create_ilm_policy(@data_stream_name)
40
- create_index_template(@data_stream_name)
45
+ create_ilm_policy(@data_stream_name, @data_stream_template_name, @data_stream_ilm_name, @host)
46
+ create_index_template(@data_stream_name, @data_stream_template_name, @data_stream_ilm_name, @host)
41
47
  create_data_stream(@data_stream_name)
42
48
  rescue => e
43
49
  raise Fluent::ConfigError, "Failed to create data stream: <#{@data_stream_name}> #{e.message}"
@@ -45,31 +51,35 @@ module Fluent::Plugin
45
51
  end
46
52
  end
47
53
 
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}>"
54
+ def validate_data_stream_parameters
55
+ {"data_stream_name" => @data_stream_name,
56
+ "data_stream_template_name"=> @data_stream_template_name,
57
+ "data_stream_ilm_name" => @data_stream_ilm_name}.each do |parameter, value|
58
+ unless valid_data_stream_parameters?(value)
59
+ unless start_with_valid_characters?(value)
60
+ if not_dots?(value)
61
+ raise Fluent::ConfigError, "'#{parameter}' must not start with #{INVALID_START_CHRACTERS.join(",")}: <#{value}>"
62
+ else
63
+ raise Fluent::ConfigError, "'#{parameter}' must not be . or ..: <#{value}>"
64
+ end
65
+ end
66
+ unless valid_characters?(value)
67
+ raise Fluent::ConfigError, "'#{parameter}' must not contain invalid characters #{INVALID_CHARACTERS.join(",")}: <#{value}>"
68
+ end
69
+ unless lowercase_only?(value)
70
+ raise Fluent::ConfigError, "'#{parameter}' must be lowercase only: <#{value}>"
71
+ end
72
+ if value.bytes.size > 255
73
+ raise Fluent::ConfigError, "'#{parameter}' must not be longer than 255 bytes: <#{value}>"
55
74
  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
75
  end
66
76
  end
67
77
  end
68
78
 
69
- def create_ilm_policy(name)
70
- return if data_stream_exist?(name)
79
+ def create_ilm_policy(datastream_name, template_name, ilm_name, host)
80
+ return if data_stream_exist?(datastream_name) or template_exists?(template_name, host) or ilm_policy_exists?(ilm_name)
71
81
  params = {
72
- policy_id: "#{name}_policy",
82
+ policy_id: ilm_name,
73
83
  body: File.read(File.join(File.dirname(__FILE__), "default-ilm-policy.json"))
74
84
  }
75
85
  retry_operate(@max_retry_putting_template,
@@ -79,19 +89,19 @@ module Fluent::Plugin
79
89
  end
80
90
  end
81
91
 
82
- def create_index_template(name)
83
- return if data_stream_exist?(name)
92
+ def create_index_template(datastream_name, template_name, ilm_name, host)
93
+ return if data_stream_exist?(datastream_name) or template_exists?(template_name, host)
84
94
  body = {
85
- "index_patterns" => ["#{name}*"],
95
+ "index_patterns" => ["#{datastream_name}*"],
86
96
  "data_stream" => {},
87
97
  "template" => {
88
98
  "settings" => {
89
- "index.lifecycle.name" => "#{name}_policy"
99
+ "index.lifecycle.name" => "#{ilm_name}"
90
100
  }
91
101
  }
92
102
  }
93
103
  params = {
94
- name: name,
104
+ name: template_name,
95
105
  body: body
96
106
  }
97
107
  retry_operate(@max_retry_putting_template,
@@ -101,9 +111,9 @@ module Fluent::Plugin
101
111
  end
102
112
  end
103
113
 
104
- def data_stream_exist?(name)
114
+ def data_stream_exist?(datastream_name)
105
115
  params = {
106
- "name": name
116
+ name: datastream_name
107
117
  }
108
118
  begin
109
119
  response = @client.indices.get_data_stream(params)
@@ -114,10 +124,10 @@ module Fluent::Plugin
114
124
  end
115
125
  end
116
126
 
117
- def create_data_stream(name)
118
- return if data_stream_exist?(name)
127
+ def create_data_stream(datastream_name)
128
+ return if data_stream_exist?(datastream_name)
119
129
  params = {
120
- "name": name
130
+ name: datastream_name
121
131
  }
122
132
  retry_operate(@max_retry_putting_template,
123
133
  @fail_on_putting_template_retry_exceed,
@@ -126,28 +136,48 @@ module Fluent::Plugin
126
136
  end
127
137
  end
128
138
 
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
139
+ def ilm_policy_exists?(policy_id)
140
+ begin
141
+ @client.ilm.get_policy(policy_id: policy_id)
142
+ true
143
+ rescue
144
+ false
145
+ end
146
+ end
147
+
148
+ def template_exists?(name, host = nil)
149
+ if @use_legacy_template
150
+ client(host).indices.get_template(:name => name)
151
+ else
152
+ client(host).indices.get_index_template(:name => name)
153
+ end
154
+ return true
155
+ rescue Elasticsearch::Transport::Transport::Errors::NotFound
156
+ return false
157
+ end
158
+
159
+ def valid_data_stream_parameters?(data_stream_parameter)
160
+ lowercase_only?(data_stream_parameter) and
161
+ valid_characters?(data_stream_parameter) and
162
+ start_with_valid_characters?(data_stream_parameter) and
163
+ not_dots?(data_stream_parameter) and
164
+ data_stream_parameter.bytes.size <= 255
135
165
  end
136
166
 
137
- def lowercase_only?
138
- @data_stream_name.downcase == @data_stream_name
167
+ def lowercase_only?(data_stream_parameter)
168
+ data_stream_parameter.downcase == data_stream_parameter
139
169
  end
140
170
 
141
- def valid_characters?
142
- not (INVALID_CHARACTERS.each.any? do |v| @data_stream_name.include?(v) end)
171
+ def valid_characters?(data_stream_parameter)
172
+ not (INVALID_CHARACTERS.each.any? do |v| data_stream_parameter.include?(v) end)
143
173
  end
144
174
 
145
- def start_with_valid_characters?
146
- not (INVALID_START_CHRACTERS.each.any? do |v| @data_stream_name.start_with?(v) end)
175
+ def start_with_valid_characters?(data_stream_parameter)
176
+ not (INVALID_START_CHRACTERS.each.any? do |v| data_stream_parameter.start_with?(v) end)
147
177
  end
148
178
 
149
- def not_dots?
150
- not (@data_stream_name == "." or @data_stream_name == "..")
179
+ def not_dots?(data_stream_parameter)
180
+ not (data_stream_parameter == "." or data_stream_parameter == "..")
151
181
  end
152
182
 
153
183
  def client_library_version
@@ -160,12 +190,17 @@ module Fluent::Plugin
160
190
 
161
191
  def write(chunk)
162
192
  data_stream_name = @data_stream_name
193
+ data_stream_template_name = @data_stream_template_name
194
+ data_stream_ilm_name = @data_stream_ilm_name
195
+ host = @host
163
196
  if @use_placeholder
164
197
  data_stream_name = extract_placeholders(@data_stream_name, chunk)
198
+ data_stream_template_name = extract_placeholders(@data_stream_template_name, chunk)
199
+ data_stream_ilm_name = extract_placeholders(@data_stream_ilm_name, chunk)
165
200
  unless @data_stream_names.include?(data_stream_name)
166
201
  begin
167
- create_ilm_policy(data_stream_name)
168
- create_index_template(data_stream_name)
202
+ create_ilm_policy(data_stream_name, data_stream_template_name, data_stream_ilm_name, host)
203
+ create_index_template(data_stream_name, data_stream_template_name, data_stream_ilm_name, host)
169
204
  create_data_stream(data_stream_name)
170
205
  @data_stream_names << data_stream_name
171
206
  rescue => e
@@ -200,7 +235,7 @@ module Fluent::Plugin
200
235
  log.error "Could not bulk insert to Data Stream: #{data_stream_name} #{response}"
201
236
  end
202
237
  rescue => e
203
- log.error "Could not bulk insert to Data Stream: #{data_stream_name} #{e.message}"
238
+ raise RecoverableRequestFailure, "could not push logs to Elasticsearch cluster (#{data_stream_name}): #{e.message}"
204
239
  end
205
240
  end
206
241
 
@@ -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")
66
- stub_request(:put, "http://localhost:9200/_ilm/policy/#{name}_policy").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
65
+ def stub_ilm_policy(name="foo_ilm_policy")
66
+ stub_request(:put, "http://localhost:9200/_ilm/policy/#{name}").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_policy")
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_policy")
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_policy", template_name="foo_tpl")
102
+ stub_request(:post, "http://localhost:9200/#{datastream_name}/_bulk").with do |req|
87
103
  # bulk data must be pair of OP and records
88
- # {"create": {}}\n
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|
115
+ # bulk data must be pair of OP and records
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_policy", 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_policy",
435
+ 'data_stream_template_name' => "foo_tpl"
212
436
  })
213
437
  assert_equal "foo", driver(conf).instance.data_stream_name
214
438
  end
@@ -224,21 +448,101 @@ 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_policy",
453
+ 'data_stream_template_name' => "foo_tpl"
228
454
  })
229
455
  assert_equal "foo", driver(conf).instance.data_stream_name
230
456
  end
231
457
 
458
+ def test_template_unset
459
+ omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
460
+
461
+ stub_ilm_policy
462
+ stub_index_template
463
+ stub_existent_data_stream?
464
+ stub_data_stream
465
+ stub_elastic_info
466
+ conf = config_element(
467
+ 'ROOT', '', {
468
+ '@type' => ELASTIC_DATA_STREAM_TYPE,
469
+ 'data_stream_name' => 'foo',
470
+ 'data_stream_ilm_name' => "foo_ilm_policy",
471
+ })
472
+ assert_equal "foo", driver(conf).instance.data_stream_name
473
+ assert_equal "foo_ilm_policy", driver(conf).instance.data_stream_ilm_name
474
+ assert_equal "foo_template", driver(conf).instance.data_stream_template_name
475
+ end
476
+
477
+ def test_ilm_unset
478
+ omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
479
+
480
+ stub_ilm_policy
481
+ stub_index_template
482
+ stub_existent_data_stream?
483
+ stub_data_stream
484
+ stub_elastic_info
485
+ conf = config_element(
486
+ 'ROOT', '', {
487
+ '@type' => ELASTIC_DATA_STREAM_TYPE,
488
+ 'data_stream_name' => 'foo',
489
+ 'data_stream_template_name' => "foo_tpl"
490
+ })
491
+ assert_equal "foo", driver(conf).instance.data_stream_name
492
+ assert_equal "foo_tpl", driver(conf).instance.data_stream_template_name
493
+ end
494
+
495
+ def test_template_and_ilm_unset
496
+ omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
497
+
498
+ stub_ilm_policy
499
+ stub_index_template
500
+ stub_existent_data_stream?
501
+ stub_data_stream
502
+ stub_elastic_info
503
+ conf = config_element(
504
+ 'ROOT', '', {
505
+ '@type' => ELASTIC_DATA_STREAM_TYPE,
506
+ 'data_stream_name' => 'foo',
507
+ })
508
+ assert_equal "foo", driver(conf).instance.data_stream_name
509
+ assert_equal "foo_template", driver(conf).instance.data_stream_template_name
510
+ assert_equal "foo_policy", driver(conf).instance.data_stream_ilm_name
511
+ end
512
+
232
513
  def test_placeholder
233
514
  omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
234
515
 
235
- name = "foo_test"
236
- stub_default(name)
237
- stub_bulk_feed(name)
516
+ dsname = "foo_test"
517
+ ilmname = "foo_ilm_test"
518
+ tplname = "foo_tpl_test"
519
+ stub_default(dsname, ilmname, tplname)
520
+ stub_bulk_feed(dsname, ilmname, tplname)
521
+ conf = config_element(
522
+ 'ROOT', '', {
523
+ '@type' => ELASTIC_DATA_STREAM_TYPE,
524
+ 'data_stream_name' => 'foo_${tag}',
525
+ 'data_stream_ilm_name' => "foo_ilm_${tag}",
526
+ 'data_stream_template_name' => "foo_tpl_${tag}"
527
+ })
528
+ driver(conf).run(default_tag: 'test') do
529
+ driver.feed(sample_record)
530
+ end
531
+ assert_equal 1, @bulk_records
532
+ end
533
+
534
+ def test_placeholder_params_unset
535
+ omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
536
+
537
+ dsname = "foo_test"
538
+ ilmname = "foo_test_policy"
539
+ tplname = "foo_test_template"
540
+ stub_default(dsname, ilmname, tplname)
541
+ stub_bulk_feed(dsname, ilmname, tplname)
238
542
  conf = config_element(
239
543
  'ROOT', '', {
240
544
  '@type' => ELASTIC_DATA_STREAM_TYPE,
241
- 'data_stream_name' => 'foo_${tag}'
545
+ 'data_stream_name' => 'foo_${tag}',
242
546
  })
243
547
  driver(conf).run(default_tag: 'test') do
244
548
  driver.feed(sample_record)
@@ -246,17 +550,22 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
246
550
  assert_equal 1, @bulk_records
247
551
  end
248
552
 
553
+
249
554
  def test_time_placeholder
250
555
  omit REQUIRED_ELASTIC_MESSAGE unless data_stream_supported?
251
556
 
252
557
  time = Time.now
253
- name = "foo_#{time.strftime("%Y%m%d")}"
254
- stub_default(name)
255
- stub_bulk_feed(name)
558
+ dsname = "foo_#{time.strftime("%Y%m%d")}"
559
+ ilmname = "foo_ilm_#{time.strftime("%Y%m%d")}"
560
+ tplname = "foo_tpl_#{time.strftime("%Y%m%d")}"
561
+ stub_default(dsname, ilmname, tplname)
562
+ stub_bulk_feed(dsname, ilmname, tplname)
256
563
  conf = config_element(
257
564
  'ROOT', '', {
258
565
  '@type' => ELASTIC_DATA_STREAM_TYPE,
259
- 'data_stream_name' => 'foo_%Y%m%d'
566
+ 'data_stream_name' => 'foo_%Y%m%d',
567
+ 'data_stream_ilm_name' => 'foo_ilm_%Y%m%d',
568
+ 'data_stream_template_name' => 'foo_tpl_%Y%m%d'
260
569
  }, [config_element('buffer', 'time', {
261
570
  'timekey' => '1d'
262
571
  }, [])]
@@ -272,14 +581,18 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
272
581
 
273
582
  keys = ["bar", "baz"]
274
583
  keys.each do |key|
275
- name = "foo_#{key}"
276
- stub_default(name)
277
- stub_bulk_feed(name)
584
+ dsname = "foo_#{key}"
585
+ ilmname = "foo_ilm_#{key}"
586
+ tplname = "foo_tpl_#{key}"
587
+ stub_default(dsname, ilmname, tplname)
588
+ stub_bulk_feed(dsname, ilmname, tplname)
278
589
  end
279
590
  conf = config_element(
280
591
  'ROOT', '', {
281
592
  '@type' => ELASTIC_DATA_STREAM_TYPE,
282
- 'data_stream_name' => 'foo_${key1}'
593
+ 'data_stream_name' => 'foo_${key1}',
594
+ 'data_stream_ilm_name' => 'foo_ilm_${key1}',
595
+ 'data_stream_template_name' => 'foo_tpl_${key1}'
283
596
  }, [config_element('buffer', 'tag,key1', {
284
597
  'timekey' => '1d'
285
598
  }, [])]
@@ -301,7 +614,9 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
301
614
  conf = config_element(
302
615
  'ROOT', '', {
303
616
  '@type' => ELASTIC_DATA_STREAM_TYPE,
304
- 'data_stream_name' => 'foo'
617
+ 'data_stream_name' => 'foo',
618
+ 'data_stream_ilm_name' => 'foo_ilm_policy',
619
+ 'data_stream_template_name' => 'foo_tpl'
305
620
  })
306
621
  driver(conf).run(default_tag: 'test') do
307
622
  driver.feed(sample_record)
@@ -316,14 +631,16 @@ class ElasticsearchOutputDataStreamTest < Test::Unit::TestCase
316
631
  template_file = File.join(cwd, 'test_index_template.json')
317
632
 
318
633
  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}
634
+ host logs.google.com
635
+ port 778
636
+ scheme https
637
+ data_stream_name foo
638
+ data_stream_ilm_name foo_ilm_policy
639
+ data_stream_template_name foo_tpl
640
+ user john
641
+ password doe
642
+ template_name logstash
643
+ template_file #{template_file}
327
644
  max_retry_putting_template 3
328
645
  }
329
646
 
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.4
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-11-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: fluentd
@@ -156,7 +156,6 @@ files:
156
156
  - ".github/workflows/macos.yml"
157
157
  - ".github/workflows/windows.yml"
158
158
  - ".gitignore"
159
- - ".travis.yml"
160
159
  - CONTRIBUTING.md
161
160
  - Gemfile
162
161
  - History.md
@@ -168,7 +167,6 @@ files:
168
167
  - README.Troubleshooting.md
169
168
  - README.md
170
169
  - Rakefile
171
- - appveyor.yml
172
170
  - fluent-plugin-elasticsearch.gemspec
173
171
  - gemfiles/Gemfile.elasticsearch.v6
174
172
  - lib/fluent/log-ext.rb
@@ -223,7 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
221
  - !ruby/object:Gem::Version
224
222
  version: '0'
225
223
  requirements: []
226
- rubygems_version: 3.2.3
224
+ rubygems_version: 3.2.30
227
225
  signing_key:
228
226
  specification_version: 4
229
227
  summary: Elasticsearch output plugin for Fluent event collector
data/.travis.yml DELETED
@@ -1,40 +0,0 @@
1
- language: ruby
2
-
3
- jobs:
4
- include:
5
- - rvm: 2.4.6
6
- gemfile: Gemfile
7
- os: linux
8
- arch: amd64
9
- - rvm: 2.5.5
10
- gemfile: Gemfile
11
- os: linux
12
- arch: amd64
13
- - rvm: 2.6.3
14
- gemfile: gemfiles/Gemfile.elasticsearch.v6
15
- os: linux
16
- arch: amd64
17
- - rvm: 2.6.3
18
- gemfile: Gemfile
19
- os: linux
20
- arch: amd64
21
- - rvm: 2.6.3
22
- gemfile: Gemfile
23
- os: linux
24
- arch: arm64
25
- - rvm: 2.6.3
26
- gemfile: Gemfile
27
- os: osx
28
- osx_image: xcode11.3
29
- - rvm: 2.7.0
30
- gemfile: Gemfile
31
- os: linux
32
- arch: amd64
33
-
34
- gemfile:
35
- - Gemfile
36
-
37
- before_install:
38
- - gem update --system=2.7.8
39
-
40
- script: bundle exec rake test
data/appveyor.yml DELETED
@@ -1,20 +0,0 @@
1
- version: '{build}'
2
- install:
3
- - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
4
- - ridk.cmd enable
5
- - ruby --version
6
- - gem --version
7
- - bundle install
8
- build: off
9
- test_script:
10
- - bundle exec rake test
11
-
12
- # https://www.appveyor.com/docs/installed-software/#ruby
13
- environment:
14
- matrix:
15
- - ruby_version: "26-x64"
16
- - ruby_version: "26"
17
- - ruby_version: "25-x64"
18
- - ruby_version: "25"
19
- - ruby_version: "24-x64"
20
- - ruby_version: "24"