fluent-plugin-input-opensearch 1.1.9 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.OpenSearchInput.md +86 -4
- data/fluent-plugin-opensearch.gemspec +1 -1
- data/lib/fluent/plugin/in_opensearch.rb +70 -43
- data/test/plugin/test_in_opensearch.rb +7 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0bf5409e93f99297d1e0f3474d8534eecd62315fbbafa8c0e3085ee7108d8daa
|
4
|
+
data.tar.gz: bbf84fc1ce4485450b57a264c5f9517cc2465191e4755bc972f0b315fc3df809
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a17efc75fc7dd5979dbf85d26af0ba6a6b770865f1b2c2de9110265ebfa9c3538da8353f3c6d7d98ba7248e3c722c404a3d58ae93972ae268bb3db32c1b3f745
|
7
|
+
data.tar.gz: 75ac7e8e7385f19e2f57aa5b7cda3134cb073de9d421f3dfdfe9f2db118f94ec8b8fe9fac03a24a22936d8fb40513c844a1a85b3cb827a7b7bff6f925a9f84b5
|
data/README.OpenSearchInput.md
CHANGED
@@ -24,7 +24,16 @@
|
|
24
24
|
+ [docinfo_fields](#docinfo_fields)
|
25
25
|
+ [docinfo_target](#docinfo_target)
|
26
26
|
+ [docinfo](#docinfo)
|
27
|
-
+ [
|
27
|
+
+ [check_connection](#check_connection)
|
28
|
+
+ [retry_forever](#retry_forever)
|
29
|
+
+ [retry_timeout](#retry_timeout)
|
30
|
+
+ [retry_max_times](#retry_max_times)
|
31
|
+
+ [retry_type](#retry_type)
|
32
|
+
+ [retry_wait](#retry_wait)
|
33
|
+
+ [retry_exponential_backoff_base](#retry_exponential_backoff_base)
|
34
|
+
+ [retry_max_interval](#retry_max_interval)
|
35
|
+
+ [retry_randomize](#retry_randomize)
|
36
|
+
|
28
37
|
* [Advanced Usage](#advanced-usage)
|
29
38
|
|
30
39
|
## Usage
|
@@ -275,14 +284,87 @@ This parameter specifies whether docinfo information including or not. The defau
|
|
275
284
|
docinfo false
|
276
285
|
```
|
277
286
|
|
278
|
-
###
|
287
|
+
### check_connection
|
288
|
+
|
289
|
+
The parameter for checking on connection availability with Elasticsearch or Opensearch hosts. The default value is `true`.
|
290
|
+
|
291
|
+
```
|
292
|
+
check_connection true
|
293
|
+
```
|
294
|
+
### retry_forever
|
295
|
+
|
296
|
+
The parameter If true, plugin will ignore retry_timeout and retry_max_times options and retry forever. The default value is `true`.
|
297
|
+
|
298
|
+
```
|
299
|
+
retry_forever true
|
300
|
+
```
|
301
|
+
|
302
|
+
### retry_timeout
|
303
|
+
|
304
|
+
The parameter maximum time (seconds) to retry again the failed try, until the plugin discards the retry.
|
305
|
+
If the next retry is going to exceed this time limit, the last retry will be made at exactly this time limit..
|
306
|
+
The default value is `72h`.
|
307
|
+
72hours == 17 times with exponential backoff (not to change default behavior)
|
308
|
+
|
309
|
+
```
|
310
|
+
retry_timeout 72 * 60 * 60
|
311
|
+
```
|
312
|
+
|
313
|
+
### retry_max_times
|
314
|
+
|
315
|
+
The parameter maximum number of times to retry the failed try. The default value is `5`
|
316
|
+
|
317
|
+
```
|
318
|
+
retry_max_times 5
|
319
|
+
```
|
320
|
+
|
321
|
+
### retry_type
|
279
322
|
|
280
|
-
The parameter
|
323
|
+
The parameter needs for how long need to wait (time in seconds) to retry again:
|
324
|
+
`exponential_backoff`: wait in seconds will become large exponentially per failure,
|
325
|
+
`periodic`: plugin will retry periodically with fixed intervals (configured via retry_wait). The default value is `:exponential_backoff`
|
326
|
+
Periodic -> fixed :retry_wait
|
327
|
+
Exponential backoff: k is number of retry times
|
328
|
+
c: constant factor, @retry_wait
|
329
|
+
b: base factor, @retry_exponential_backoff_base
|
330
|
+
k: times
|
331
|
+
total retry time: c + c * b^1 + (...) + c*b^k = c*b^(k+1) - 1
|
281
332
|
|
282
333
|
```
|
283
|
-
|
334
|
+
retry_type exponential_backoff
|
284
335
|
```
|
285
336
|
|
337
|
+
### retry_wait
|
338
|
+
|
339
|
+
The parameter needs for wait in seconds before the next retry to again or constant factor of exponential backoff. The default value is `5`
|
340
|
+
|
341
|
+
```
|
342
|
+
retry_wait 5
|
343
|
+
```
|
344
|
+
|
345
|
+
### retry_exponential_backoff_base
|
346
|
+
|
347
|
+
The parameter The base number of exponential backoff for retries. The default value is `2`
|
348
|
+
|
349
|
+
```
|
350
|
+
retry_exponential_backoff_base 2
|
351
|
+
```
|
352
|
+
|
353
|
+
### retry_max_interval
|
354
|
+
|
355
|
+
The parameter maximum interval (seconds) for exponential backoff between retries while failing. The default value is `nil`
|
356
|
+
|
357
|
+
```
|
358
|
+
retry_max_interval nil
|
359
|
+
```
|
360
|
+
|
361
|
+
### retry_randomize
|
362
|
+
|
363
|
+
The parameter If true, the plugin will retry after randomized interval not to do burst retries. The default value is `false`
|
364
|
+
|
365
|
+
```
|
366
|
+
retry_randomize false
|
367
|
+
```
|
286
368
|
|
287
369
|
## Advanced Usage
|
288
370
|
|
@@ -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-input-opensearch'
|
6
|
-
s.version = '1.
|
6
|
+
s.version = '1.2.0'
|
7
7
|
s.authors = ['imcotop']
|
8
8
|
s.email = ['imcotop@icloud.com']
|
9
9
|
s.description = %q{Opensearch output plugin for Fluent event collector}
|
@@ -29,6 +29,7 @@ require 'opensearch'
|
|
29
29
|
require 'faraday/excon'
|
30
30
|
require 'fluent/log-ext'
|
31
31
|
require 'fluent/plugin/input'
|
32
|
+
require 'fluent/plugin_helper'
|
32
33
|
require_relative 'opensearch_constants'
|
33
34
|
|
34
35
|
module Fluent::Plugin
|
@@ -39,7 +40,7 @@ module Fluent::Plugin
|
|
39
40
|
DEFAULT_STORAGE_TYPE = 'local'
|
40
41
|
METADATA = "@metadata".freeze
|
41
42
|
|
42
|
-
helpers :timer, :thread
|
43
|
+
helpers :timer, :thread, :retry_state
|
43
44
|
|
44
45
|
Fluent::Plugin.register_input('opensearch', self)
|
45
46
|
|
@@ -80,7 +81,23 @@ module Fluent::Plugin
|
|
80
81
|
config_param :docinfo_fields, :array, :default => ['_index', '_type', '_id']
|
81
82
|
config_param :docinfo_target, :string, :default => METADATA
|
82
83
|
config_param :docinfo, :bool, :default => false
|
83
|
-
config_param :
|
84
|
+
config_param :check_connection, :bool, :default => true
|
85
|
+
config_param :retry_forever, :bool, default: true, desc: 'If true, plugin will ignore retry_timeout and retry_max_times options and retry forever.'
|
86
|
+
config_param :retry_timeout, :time, default: 72 * 60 * 60, desc: 'The maximum seconds to retry'
|
87
|
+
# 72hours == 17 times with exponential backoff (not to change default behavior)
|
88
|
+
config_param :retry_max_times, :integer, default: 5, desc: 'The maximum number of times to retry'
|
89
|
+
# exponential backoff sequence will be initialized at the time of this threshold
|
90
|
+
config_param :retry_type, :enum, list: [:exponential_backoff, :periodic], default: :exponential_backoff
|
91
|
+
### Periodic -> fixed :retry_wait
|
92
|
+
### Exponential backoff: k is number of retry times
|
93
|
+
# c: constant factor, @retry_wait
|
94
|
+
# b: base factor, @retry_exponential_backoff_base
|
95
|
+
# k: times
|
96
|
+
# total retry time: c + c * b^1 + (...) + c*b^k = c*b^(k+1) - 1
|
97
|
+
config_param :retry_wait, :time, default: 5, desc: 'Seconds to wait before next retry , or constant factor of exponential backoff.'
|
98
|
+
config_param :retry_exponential_backoff_base, :float, default: 2, desc: 'The base number of exponential backoff for retries.'
|
99
|
+
config_param :retry_max_interval, :time, default: nil, desc: 'The maximum interval seconds for exponential backoff between retries while failing.'
|
100
|
+
config_param :retry_randomize, :bool, default: false, desc: 'If true, output plugin will retry after randomized interval not to do burst retries.'
|
84
101
|
|
85
102
|
include Fluent::Plugin::OpenSearchConstants
|
86
103
|
|
@@ -93,6 +110,7 @@ module Fluent::Plugin
|
|
93
110
|
|
94
111
|
@timestamp_parser = create_time_parser
|
95
112
|
@backend_options = backend_options
|
113
|
+
@retry = nil
|
96
114
|
|
97
115
|
raise Fluent::ConfigError, "`password` must be present if `user` is present" if @user && @password.nil?
|
98
116
|
|
@@ -139,6 +157,15 @@ module Fluent::Plugin
|
|
139
157
|
raise Fluent::ConfigError, "You must install #{@http_backend} gem. Exception: #{ex}"
|
140
158
|
end
|
141
159
|
|
160
|
+
def retry_state(randomize)
|
161
|
+
retry_state_create(
|
162
|
+
:input_retries, @retry_type, @retry_wait, @retry_timeout,
|
163
|
+
forever: @retry_forever, max_steps: @retry_max_times,
|
164
|
+
max_interval: @retry_max_interval, backoff_base: @retry_exponential_backoff_base,
|
165
|
+
randomize: randomize
|
166
|
+
)
|
167
|
+
end
|
168
|
+
|
142
169
|
def get_escaped_userinfo(host_str)
|
143
170
|
if m = host_str.match(/(?<scheme>.*)%{(?<user>.*)}:%{(?<password>.*)}(?<path>@.*)/)
|
144
171
|
m["scheme"] +
|
@@ -177,12 +204,29 @@ module Fluent::Plugin
|
|
177
204
|
host.merge!(user: @user, password: @password) if !host[:user] && @user
|
178
205
|
host.merge!(path: @path) if !host[:path] && @path
|
179
206
|
end
|
180
|
-
|
207
|
+
live_hosts = @check_connection ? hosts.select { |host| reachable_host?(host) } : hosts
|
181
208
|
{
|
182
|
-
hosts:
|
209
|
+
hosts: live_hosts
|
183
210
|
}
|
184
211
|
end
|
185
212
|
|
213
|
+
def reachable_host?(host)
|
214
|
+
client = OpenSearch::Client.new(
|
215
|
+
host: ["#{host[:scheme]}://#{host[:host]}:#{host[:port]}"],
|
216
|
+
user: host[:user],
|
217
|
+
password: host[:password],
|
218
|
+
reload_connections: @reload_connections,
|
219
|
+
request_timeout: @request_timeout,
|
220
|
+
resurrect_after: @resurrect_after,
|
221
|
+
reload_on_failure: @reload_on_failure,
|
222
|
+
transport_options: { ssl: { verify: @ssl_verify, ca_file: @ca_file, version: @ssl_version } }
|
223
|
+
)
|
224
|
+
client.ping
|
225
|
+
rescue => e
|
226
|
+
log.warn "Failed to connect to #{host[:scheme]}://#{host[:host]}:#{host[:port]}: #{e.message}"
|
227
|
+
false
|
228
|
+
end
|
229
|
+
|
186
230
|
def emit_error_label_event(&block)
|
187
231
|
# If `emit_error_label_event` is specified as false, error event emittions are not occurred.
|
188
232
|
if emit_error_label_event
|
@@ -240,43 +284,6 @@ module Fluent::Plugin
|
|
240
284
|
return Time.at(event_time).to_time
|
241
285
|
end
|
242
286
|
|
243
|
-
def get_reachable_hosts(hosts=nil)
|
244
|
-
reachable_hosts = []
|
245
|
-
attempt = 0
|
246
|
-
loop do
|
247
|
-
hosts.each do |host|
|
248
|
-
begin
|
249
|
-
if @infinite_check_connection == true
|
250
|
-
check_host = OpenSearch::Client.new(
|
251
|
-
host: ["#{host[:scheme]}://#{host[:host]}:#{host[:port]}"],
|
252
|
-
user: host[:user],
|
253
|
-
password: host[:password],
|
254
|
-
reload_connections: true,
|
255
|
-
resurrect_after: @resurrect_after,
|
256
|
-
reload_on_failure: @reload_on_failure,
|
257
|
-
transport_options: { ssl: { verify: @ssl_verify, ca_file: @ca_file, version: @ssl_version } }
|
258
|
-
)
|
259
|
-
response = check_host.ping #https://github.com/opensearch-project/opensearch-ruby/blob/136e1c975fc91b8cb80d7d1134e32c6dbefdb3eb/lib/opensearch/api/actions/ping.rb#L33
|
260
|
-
if response == true
|
261
|
-
reachable_hosts << host
|
262
|
-
else
|
263
|
-
log.warn "Connection to #{host[:scheme]}://#{host[:host]}:#{host[:port]} failed with status code #{response.status}"
|
264
|
-
end
|
265
|
-
else
|
266
|
-
reachable_hosts << host
|
267
|
-
end
|
268
|
-
rescue => e
|
269
|
-
log.warn "Failed to connect to #{host[:scheme]}://#{host[:host]}:#{host[:port]}"
|
270
|
-
end
|
271
|
-
end
|
272
|
-
break unless reachable_hosts.empty?
|
273
|
-
log.info "Attempt ##{attempt += 1} to get reachable hosts"
|
274
|
-
log.info "No reachable hosts found. Retrying in #{@request_timeout} seconds..."
|
275
|
-
sleep(@request_timeout)
|
276
|
-
end
|
277
|
-
reachable_hosts
|
278
|
-
end
|
279
|
-
|
280
287
|
def client(host = nil)
|
281
288
|
# check here to see if we already have a client connection for the given host
|
282
289
|
connection_options = get_connection_options(host)
|
@@ -330,6 +337,25 @@ module Fluent::Plugin
|
|
330
337
|
return true
|
331
338
|
end
|
332
339
|
|
340
|
+
def update_retry_state(error=nil)
|
341
|
+
if error
|
342
|
+
unless @retry
|
343
|
+
@retry = retry_state(@retry_randomize)
|
344
|
+
end
|
345
|
+
@retry.step
|
346
|
+
#Raise error if the retry limit has been reached
|
347
|
+
raise "Hit limit for retries. retry_times: #{@retry.steps}, error: #{error.message}" if @retry.limit?
|
348
|
+
#Retry if the limit hasn't been reached
|
349
|
+
log.warn("failed to connect or search.", retry_times: @retry.steps, next_retry_time: @retry.next_time.round, error: error.message)
|
350
|
+
sleep(@retry.next_time - Time.now)
|
351
|
+
else
|
352
|
+
unless @retry.nil?
|
353
|
+
log.debug("retry succeeded.")
|
354
|
+
@retry = nil
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
333
359
|
def run
|
334
360
|
return run_slice if @num_slices <= 1
|
335
361
|
|
@@ -340,8 +366,8 @@ module Fluent::Plugin
|
|
340
366
|
run_slice(slice_id)
|
341
367
|
end
|
342
368
|
end
|
343
|
-
rescue Faraday::ConnectionFailed =>
|
344
|
-
|
369
|
+
rescue Faraday::ConnectionFailed, OpenSearch::Transport::Transport::Error => error
|
370
|
+
update_retry_state(error)
|
345
371
|
retry
|
346
372
|
end
|
347
373
|
|
@@ -363,6 +389,7 @@ module Fluent::Plugin
|
|
363
389
|
|
364
390
|
router.emit_stream(@tag, es)
|
365
391
|
clear_scroll(scroll_id)
|
392
|
+
update_retry_state
|
366
393
|
end
|
367
394
|
|
368
395
|
def clear_scroll(scroll_id)
|
@@ -39,7 +39,7 @@ class OpenSearchInputTest < Test::Unit::TestCase
|
|
39
39
|
CONFIG = %[
|
40
40
|
tag raw.opensearch
|
41
41
|
interval 2
|
42
|
-
|
42
|
+
check_connection false
|
43
43
|
]
|
44
44
|
|
45
45
|
def setup
|
@@ -191,7 +191,7 @@ class OpenSearchInputTest < Test::Unit::TestCase
|
|
191
191
|
user john
|
192
192
|
password doe
|
193
193
|
tag raw.opensearch
|
194
|
-
|
194
|
+
check_connection false
|
195
195
|
}
|
196
196
|
instance = driver(config).instance
|
197
197
|
|
@@ -230,7 +230,7 @@ class OpenSearchInputTest < Test::Unit::TestCase
|
|
230
230
|
user john
|
231
231
|
password doe
|
232
232
|
tag raw.opensearch
|
233
|
-
|
233
|
+
check_connection false
|
234
234
|
}
|
235
235
|
instance = driver(config).instance
|
236
236
|
|
@@ -252,7 +252,7 @@ class OpenSearchInputTest < Test::Unit::TestCase
|
|
252
252
|
user %{j+hn}
|
253
253
|
password %{d@e}
|
254
254
|
tag raw.opensearch
|
255
|
-
|
255
|
+
check_connection false
|
256
256
|
}
|
257
257
|
instance = driver(config).instance
|
258
258
|
|
@@ -275,7 +275,7 @@ class OpenSearchInputTest < Test::Unit::TestCase
|
|
275
275
|
path /es/
|
276
276
|
port 123
|
277
277
|
tag raw.opensearch
|
278
|
-
|
278
|
+
check_connection false
|
279
279
|
}
|
280
280
|
instance = driver(config).instance
|
281
281
|
|
@@ -300,7 +300,7 @@ class OpenSearchInputTest < Test::Unit::TestCase
|
|
300
300
|
user default_user
|
301
301
|
password default_password
|
302
302
|
tag raw.opensearch
|
303
|
-
|
303
|
+
check_connection false
|
304
304
|
}
|
305
305
|
instance = driver(config).instance
|
306
306
|
|
@@ -329,7 +329,7 @@ class OpenSearchInputTest < Test::Unit::TestCase
|
|
329
329
|
user default_user
|
330
330
|
password default_password
|
331
331
|
tag raw.opensearch
|
332
|
-
|
332
|
+
check_connection false
|
333
333
|
}
|
334
334
|
instance = driver(config).instance
|
335
335
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-input-opensearch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- imcotop
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|