fluent-plugin-opensearch 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56dc0da995d5f55c59e13afd75452b46e824f8337de6b074655dc8c92926eba8
4
- data.tar.gz: dffab1c953b558fe1001df5c59844f1d71f8a2847199afade1b74ff9a05f739a
3
+ metadata.gz: 9dc42f6d13cb540c456050657cd2079a7b755a77e4148122f486be2b15486db7
4
+ data.tar.gz: 76bc650e96fc7b35a84641f6b0916024985bdccb779e54ef4e49d2172eb6227f
5
5
  SHA512:
6
- metadata.gz: da67be6908b8000b6904655b0492cfedbedddae45dd7b408a41698e7c02ea1778b1fb8c64be4097b5cbfed1e58601c30a57892d07706de4782526cb0a6edd0c4
7
- data.tar.gz: f002f9ccec9f8dd7c292ef3d88d8425e0f05e3651cf831eb86204059726643db43502c3285b4ad8410840e7bb29d814f2e243c1b6671c24909abb1f1b7b14824
6
+ metadata.gz: dfa28860c87c55fcffba26a9d4990e64d909b8daf5e0ed68dfe309d6fcd3d78b61f41738bff3a88e6ffd780f1c870e0a95a151c5637c228f488253e2ac889a79
7
+ data.tar.gz: 77045d8ba592eaf9daf904b5d10ac36935c8d0ac13decff011e281cc0732e72f5b02ba69e196a8822a303dcb399752fe081d2bb846e0a19a93123513eac763e3
@@ -1,37 +1,29 @@
1
1
  ---
2
2
  name: Bug Report
3
- about: Create a report to help us improve. If you have questions about ES plugin on kubernetes, please direct these to https://discuss.kubernetes.io/ before sumbit kubernetes related issue.
3
+ about: Create a report to help us improve. If you have questions about OpenSearch plugin on kubernetes, please direct these to https://discuss.kubernetes.io/ before sumbit kubernetes related issue.
4
4
 
5
5
  ---
6
6
 
7
7
  (check apply)
8
- - [ ] read [the contribution guideline](https://github.com/uken/fluent-plugin-elasticsearch/blob/master/CONTRIBUTING.md)
8
+ - [ ] read [the contribution guideline](https://github.com/fluent/fluent-plugin-opensearch/blob/master/CONTRIBUTING.md)
9
9
  - [ ] (optional) already reported 3rd party upstream repository or mailing list if you use k8s addon or helm charts.
10
10
 
11
- #### Problem
12
-
13
- ...
14
-
15
11
  #### Steps to replicate
16
12
 
17
- Either clone and modify https://gist.github.com/pitr/9a518e840db58f435911
18
-
19
- **OR**
20
-
21
13
  Provide example config and message
22
14
 
23
15
  #### Expected Behavior or What you need to ask
24
16
 
25
17
  ...
26
18
 
27
- #### Using Fluentd and ES plugin versions
19
+ #### Using Fluentd and OpenSearch plugin versions
28
20
 
29
21
  * OS version
30
22
  * Bare Metal or within Docker or Kubernetes or others?
31
- * Fluentd v0.12 or v0.14/v1.0
23
+ * Fluentd v1.0 or later
32
24
  * paste result of ``fluentd --version`` or ``td-agent --version``
33
- * ES plugin 3.x.y/2.x.y or 1.x.y
25
+ * OpenSearch plugin version
34
26
  * paste boot log of fluentd or td-agent
35
27
  * paste result of ``fluent-gem list``, ``td-agent-gem list`` or your Gemfile.lock
36
- * ES version (optional)
37
- * ES template(s) (optional)
28
+ * OpenSearch version (optional)
29
+ * OpenSearch template(s) (optional)
data/History.md CHANGED
@@ -2,5 +2,10 @@
2
2
 
3
3
  ### [Unreleased]
4
4
 
5
+ ### 1.0.1
6
+ - Add testcases for hosts parameter (#10)
7
+ - Permit to handle @hosts parameter (#9)
8
+ - Retry creating data stream/template when OpenSearch is unreachable (#8)
9
+
5
10
  ### 1.0.0
6
11
  - Initial public gem release.
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  ![Testing on Ubuntu](https://github.com/fluent/fluent-plugin-opensearch/workflows/Testing%20on%20Ubuntu/badge.svg?branch=main)
7
7
  [![Coverage Status](https://coveralls.io/repos/github/fluent/fluent-plugin-opensearch/badge.svg?branch=upload-coverage-into-coveralls)](https://coveralls.io/github/fluent/fluent-plugin-opensearch?branch=main)
8
8
 
9
- Send your logs to OpenSearch (and search them with OpenSearch Dashboard maybe?)
9
+ Send your logs to OpenSearch (and search them with OpenSearch Dashboards maybe?)
10
10
 
11
11
  * [Installation](#installation)
12
12
  * [Usage](#usage)
@@ -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-opensearch'
6
- s.version = '1.0.0'
6
+ s.version = '1.0.1'
7
7
  s.authors = ['Hiroshi Hatake']
8
8
  s.email = ['cosmo0920.wp@gmail.com']
9
9
  s.description = %q{Opensearch output plugin for Fluent event collector}
@@ -29,18 +29,32 @@ module Fluent::Plugin
29
29
  @data_stream_names = []
30
30
  end
31
31
 
32
- @client = client
32
+ host = data_stream_connection
33
+
33
34
  unless @use_placeholder
34
35
  begin
35
36
  @data_stream_names = [@data_stream_name]
36
- create_index_template(@data_stream_name, @data_stream_template_name, @host)
37
- create_data_stream(@data_stream_name)
37
+ retry_operate(@max_retry_putting_template,
38
+ @fail_on_putting_template_retry_exceed,
39
+ @catch_transport_exception_on_retry) do
40
+ create_index_template(@data_stream_name, @data_stream_template_name, host)
41
+ create_data_stream(@data_stream_name, host)
42
+ end
38
43
  rescue => e
39
44
  raise Fluent::ConfigError, "Failed to create data stream: <#{@data_stream_name}> #{e.message}"
40
45
  end
41
46
  end
42
47
  end
43
48
 
49
+ # FIXME: Currently, the first element from hosts is only used and extracted.
50
+ def data_stream_connection
51
+ if host = get_connection_options[:hosts].first
52
+ "#{host[:scheme]}://#{host[:host]}:#{host[:port]}#{host[:path]}"
53
+ else
54
+ @host
55
+ end
56
+ end
57
+
44
58
  def validate_data_stream_parameters
45
59
  {"data_stream_name" => @data_stream_name,
46
60
  "data_stream_template_name"=> @data_stream_template_name}.each do |parameter, value|
@@ -65,7 +79,7 @@ module Fluent::Plugin
65
79
  end
66
80
  end
67
81
 
68
- def create_index_template(datastream_name, template_name, host)
82
+ def create_index_template(datastream_name, template_name, host = nil)
69
83
  return if data_stream_exist?(datastream_name) or template_exists?(template_name, host)
70
84
  body = {
71
85
  "index_patterns" => ["#{datastream_name}*"],
@@ -78,17 +92,17 @@ module Fluent::Plugin
78
92
  retry_operate(@max_retry_putting_template,
79
93
  @fail_on_putting_template_retry_exceed,
80
94
  @catch_transport_exception_on_retry) do
81
- @client.indices.put_index_template(params)
95
+ client(host).indices.put_index_template(params)
82
96
  end
83
97
  end
84
98
 
85
- def data_stream_exist?(datastream_name)
99
+ def data_stream_exist?(datastream_name, host = nil)
86
100
  params = {
87
101
  name: datastream_name
88
102
  }
89
103
  begin
90
104
  # TODO: Use X-Pack equivalent performing DataStream operation method on the following line
91
- response = @client.perform_request('GET', "/_data_stream/#{datastream_name}", {}, params)
105
+ response = client(host).perform_request('GET', "/_data_stream/#{datastream_name}", {}, params)
92
106
  return (not response.is_a?(OpenSearch::Transport::Transport::Errors::NotFound))
93
107
  rescue OpenSearch::Transport::Transport::Errors::NotFound => e
94
108
  log.info "Specified data stream does not exist. Will be created: <#{e}>"
@@ -96,8 +110,8 @@ module Fluent::Plugin
96
110
  end
97
111
  end
98
112
 
99
- def create_data_stream(datastream_name)
100
- return if data_stream_exist?(datastream_name)
113
+ def create_data_stream(datastream_name, host = nil)
114
+ return if data_stream_exist?(datastream_name, host)
101
115
  params = {
102
116
  name: datastream_name
103
117
  }
@@ -105,7 +119,7 @@ module Fluent::Plugin
105
119
  @fail_on_putting_template_retry_exceed,
106
120
  @catch_transport_exception_on_retry) do
107
121
  # TODO: Use X-Pack equivalent performing DataStream operation method on the following line
108
- @client.perform_request('PUT', "/_data_stream/#{datastream_name}", {}, params)
122
+ client(host).perform_request('PUT', "/_data_stream/#{datastream_name}", {}, params)
109
123
  end
110
124
  end
111
125
 
@@ -162,7 +176,7 @@ module Fluent::Plugin
162
176
  unless @data_stream_names.include?(data_stream_name)
163
177
  begin
164
178
  create_index_template(data_stream_name, data_stream_template_name, host)
165
- create_data_stream(data_stream_name)
179
+ create_data_stream(data_stream_name, host)
166
180
  @data_stream_names << data_stream_name
167
181
  rescue => e
168
182
  raise Fluent::ConfigError, "Failed to create data stream: <#{data_stream_name}> #{e.message}"
@@ -191,7 +205,7 @@ module Fluent::Plugin
191
205
  body: bulk_message
192
206
  }
193
207
  begin
194
- response = @client.bulk(params)
208
+ response = client(host).bulk(params)
195
209
  if response['errors']
196
210
  log.error "Could not bulk insert to Data Stream: #{data_stream_name} #{response}"
197
211
  end
@@ -61,38 +61,43 @@ class OpenSearchOutputDataStreamTest < Test::Unit::TestCase
61
61
  DUPLICATED_DATA_STREAM_EXCEPTION = {"error": {}, "status": 400}
62
62
  NONEXISTENT_DATA_STREAM_EXCEPTION = {"error": {}, "status": 404}
63
63
 
64
- def stub_index_template(name="foo_tpl")
65
- stub_request(:put, "http://localhost:9200/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
64
+ def stub_index_template(name="foo_tpl", url="http://localhost:9200")
65
+ stub_request(:put, "#{url}/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
66
66
  end
67
67
 
68
- def stub_data_stream(name="foo")
69
- stub_request(:put, "http://localhost:9200/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
68
+ def stub_data_stream(name="foo", url="localhost:9200")
69
+ stub_request(:put, "#{url}/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
70
70
  end
71
71
 
72
- def stub_existent_data_stream?(name="foo")
73
- stub_request(:get, "http://localhost:9200/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
72
+ def stub_existent_data_stream?(name="foo", url="localhost:9200")
73
+ stub_request(:get, "#{url}/_data_stream/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
74
74
  end
75
75
 
76
- def stub_existent_template?(name="foo_tpl")
77
- stub_request(:get, "http://localhost:9200/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
76
+ def stub_existent_template?(name="foo_tpl", url="localhost:9200")
77
+ stub_request(:get, "#{url}/_index_template/#{name}").to_return(:status => [200, RESPONSE_ACKNOWLEDGED])
78
78
  end
79
79
 
80
- def stub_nonexistent_data_stream?(name="foo")
81
- stub_request(:get, "http://localhost:9200/_data_stream/#{name}").to_return(:status => [404, OpenSearch::Transport::Transport::Errors::NotFound])
80
+ def stub_nonexistent_data_stream?(name="foo", url="localhost:9200")
81
+ stub_request(:get, "#{url}/_data_stream/#{name}").to_return(:status => [404, OpenSearch::Transport::Transport::Errors::NotFound])
82
82
  end
83
83
 
84
- def stub_nonexistent_template?(name="foo_tpl")
85
- stub_request(:get, "http://localhost:9200/_index_template/#{name}").to_return(:status => [404, OpenSearch::Transport::Transport::Errors::NotFound])
84
+ def stub_nonexistent_template?(name="foo_tpl", url="http://localhost:9200")
85
+ stub_request(:get, "#{url}/_index_template/#{name}").to_return(:status => [404, OpenSearch::Transport::Transport::Errors::NotFound])
86
86
  end
87
87
 
88
- def stub_bulk_feed(datastream_name="foo", template_name="foo_tpl")
89
- stub_request(:post, "http://localhost:9200/#{datastream_name}/_bulk").with do |req|
88
+ def stub_nonexistent_template_retry?(name="foo_tpl", url="http://localhost:9200")
89
+ stub_request(:get, "#{url}/_index_template/#{name}").
90
+ to_return({ status: 500, body: 'Internal Server Error' }, { status: 404, body: '{}' })
91
+ end
92
+
93
+ def stub_bulk_feed(datastream_name="foo", template_name="foo_tpl", url="http://localhost:9200")
94
+ stub_request(:post, "#{url}/#{datastream_name}/_bulk").with do |req|
90
95
  # bulk data must be pair of OP and records
91
96
  # {"create": {}}\nhttp://localhost:9200/_data_stream/foo_bar
92
97
  # {"@timestamp": ...}
93
98
  @bulk_records += req.body.split("\n").size / 2
94
99
  end
95
- stub_request(:post, "http://localhost:9200/#{template_name}/_bulk").with do |req|
100
+ stub_request(:post, "http://#{url}#{template_name}/_bulk").with do |req|
96
101
  # bulk data must be pair of OP and records
97
102
  # {"create": {}}\nhttp://localhost:9200/_data_stream/foo_bar
98
103
  # {"@timestamp": ...}
@@ -100,13 +105,13 @@ class OpenSearchOutputDataStreamTest < Test::Unit::TestCase
100
105
  end
101
106
  end
102
107
 
103
- def stub_elastic_info(url="http://localhost:9200/", version="1.2.2")
108
+ def stub_opensearch_info(url="http://localhost:9200/", version="1.2.2", headers={})
104
109
  body ="{\"version\":{\"number\":\"#{version}\", \"distribution\":\"opensearch\"},\"tagline\":\"The OpenSearch Project: https://opensearch.org/\"}"
105
- stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' } })
110
+ stub_request(:get, url).to_return({:status => 200, :body => body, :headers => { 'Content-Type' => 'json' }.merge(headers) })
106
111
  end
107
112
 
108
113
  def stub_default(datastream_name="foo", template_name="foo_tpl", host="http://localhost:9200")
109
- stub_elastic_info(host)
114
+ stub_opensearch_info(host)
110
115
  stub_nonexistent_template?(template_name)
111
116
  stub_index_template(template_name)
112
117
  stub_nonexistent_data_stream?(datastream_name)
@@ -315,11 +320,58 @@ class OpenSearchOutputDataStreamTest < Test::Unit::TestCase
315
320
  assert_equal "foo", driver(conf).instance.data_stream_name
316
321
  end
317
322
 
323
+ def test_hosts_list_configure
324
+ config = %{
325
+ hosts https://john:password@host1:443/elastic/,http://host2
326
+ path /default_path
327
+ user default_user
328
+ password default_password
329
+ data_stream_name default
330
+ }
331
+ stub_opensearch_info("https://host1:443/elastic//", "1.2.2",
332
+ {'Authorization'=>'Basic am9objpwYXNzd29yZA=='})
333
+ stub_opensearch_info("http://host2/default_path/_data_stream/default", "1.2.2",
334
+ {'Authorization'=>'Basic am9objpwYXNzd29yZA=='})
335
+ stub_existent_data_stream?("default", "https://host1/elastic/")
336
+ instance = driver(config).instance
337
+
338
+ assert_equal 2, instance.get_connection_options[:hosts].length
339
+ host1, host2 = instance.get_connection_options[:hosts]
340
+
341
+ assert_equal 'host1', host1[:host]
342
+ assert_equal 443, host1[:port]
343
+ assert_equal 'https', host1[:scheme]
344
+ assert_equal 'john', host1[:user]
345
+ assert_equal 'password', host1[:password]
346
+ assert_equal '/elastic/', host1[:path]
347
+
348
+ assert_equal 'host2', host2[:host]
349
+ assert_equal 'http', host2[:scheme]
350
+ assert_equal 'default_user', host2[:user]
351
+ assert_equal 'default_password', host2[:password]
352
+ assert_equal '/default_path', host2[:path]
353
+ end
354
+
355
+ def test_datastream_configure_retry
356
+ stub_opensearch_info
357
+ stub_nonexistent_template_retry?
358
+ stub_index_template
359
+ stub_nonexistent_data_stream?
360
+ stub_data_stream
361
+ conf = config_element(
362
+ 'ROOT', '', {
363
+ '@type' => OPENSEARCH_DATA_STREAM_TYPE,
364
+ 'data_stream_name' => 'foo',
365
+ 'data_stream_template_name' => "foo_tpl"
366
+ })
367
+ assert_equal "foo", driver(conf).instance.data_stream_name
368
+ end
369
+
318
370
  def test_existent_data_stream
319
371
  stub_index_template
320
372
  stub_existent_data_stream?
321
373
  stub_data_stream
322
- stub_elastic_info
374
+ stub_opensearch_info
323
375
  conf = config_element(
324
376
  'ROOT', '', {
325
377
  '@type' => OPENSEARCH_DATA_STREAM_TYPE,
@@ -333,7 +385,7 @@ class OpenSearchOutputDataStreamTest < Test::Unit::TestCase
333
385
  stub_index_template
334
386
  stub_existent_data_stream?
335
387
  stub_data_stream
336
- stub_elastic_info
388
+ stub_opensearch_info
337
389
  conf = config_element(
338
390
  'ROOT', '', {
339
391
  '@type' => OPENSEARCH_DATA_STREAM_TYPE,
@@ -463,7 +515,7 @@ class OpenSearchOutputDataStreamTest < Test::Unit::TestCase
463
515
  connection_resets += 1
464
516
  raise Faraday::ConnectionFailed, "Test message"
465
517
  end
466
- stub_elastic_info("https://logs.google.com:778/")
518
+ stub_opensearch_info("https://logs.google.com:778/")
467
519
 
468
520
  assert_raise(Fluent::Plugin::OpenSearchError::RetryableOperationExhaustedFailure) do
469
521
  driver(config)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-opensearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hiroshi Hatake
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-01-13 00:00:00.000000000 Z
11
+ date: 2022-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -226,7 +226,7 @@ licenses:
226
226
  - Apache-2.0
227
227
  metadata:
228
228
  changelog_uri: https://github.com/fluent/fluent-plugin-opensearch/blob/master/History.md
229
- post_install_message:
229
+ post_install_message:
230
230
  rdoc_options: []
231
231
  require_paths:
232
232
  - lib
@@ -241,8 +241,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
241
241
  - !ruby/object:Gem::Version
242
242
  version: '0'
243
243
  requirements: []
244
- rubygems_version: 3.2.22
245
- signing_key:
244
+ rubygems_version: 3.2.30
245
+ signing_key:
246
246
  specification_version: 4
247
247
  summary: Opensearch output plugin for Fluent event collector
248
248
  test_files: