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 +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
|
![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
|
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:
|