fluent-plugin-opensearch 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +7 -15
- data/History.md +5 -0
- data/README.md +1 -1
- data/fluent-plugin-opensearch.gemspec +1 -1
- data/lib/fluent/plugin/out_opensearch_data_stream.rb +26 -12
- data/test/plugin/test_out_opensearch_data_stream.rb +73 -21
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9dc42f6d13cb540c456050657cd2079a7b755a77e4148122f486be2b15486db7
|
4
|
+
data.tar.gz: 76bc650e96fc7b35a84641f6b0916024985bdccb779e54ef4e49d2172eb6227f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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/
|
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
|
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
|
23
|
+
* Fluentd v1.0 or later
|
32
24
|
* paste result of ``fluentd --version`` or ``td-agent --version``
|
33
|
-
*
|
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
|
-
*
|
37
|
-
*
|
28
|
+
* OpenSearch version (optional)
|
29
|
+
* OpenSearch template(s) (optional)
|
data/History.md
CHANGED
data/README.md
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|

|
7
7
|
[](https://coveralls.io/github/fluent/fluent-plugin-opensearch?branch=main)
|
8
8
|
|
9
|
-
Send your logs to OpenSearch (and search them with OpenSearch
|
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.
|
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
|
-
|
32
|
+
host = data_stream_connection
|
33
|
+
|
33
34
|
unless @use_placeholder
|
34
35
|
begin
|
35
36
|
@data_stream_names = [@data_stream_name]
|
36
|
-
|
37
|
-
|
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
|
-
|
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 =
|
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
|
-
|
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 =
|
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, "
|
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, "
|
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, "
|
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, "
|
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, "
|
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, "
|
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
|
89
|
-
stub_request(:
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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-
|
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.
|
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:
|