fluent-plugin-elasticsearch 5.1.0 → 5.1.4

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