logstash-input-s3-sns-sqs 2.1.1 → 2.2.0.pre

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: 4f090986d9b42c172402ba4b1b31c60d0ddbce1d76f160cf6ad9fcb02bbcccb9
4
- data.tar.gz: a281caf8e678835b008e927ac7ca81f3edab6448f1932c8fec2116623e263e8b
3
+ metadata.gz: 9d5ea48e146f2c80413f41fa2be04ab09396ce2fd67f0275032d34641e0c6fd2
4
+ data.tar.gz: c4301ebe9b7abb940891bd06843de67b66b400cc6470bfa69b4a208320ef6387
5
5
  SHA512:
6
- metadata.gz: 993b13ece9f6fc0ac31231ea028780a4108e621c3f9e9efd905fb51f54f8aa0760b736138557fc02307ec9feeb78efdade413e9226704e8a876d397acc8f9916
7
- data.tar.gz: 6d221eb99ace6783e81e89543c84be4693d2de5a8591103ac8b4c5eeb449add26144f54ea77d1798926a9959e1fbfadac58b8170f035edac95d31b525ecf10c4
6
+ metadata.gz: 7c478aa632537f4db570327ff25df1102faab0f9480515bbb4991e52540e086cfb881935b29725e34b4bd5de65a06de77ef65d682ee6b7cc909fce72b5359080
7
+ data.tar.gz: 52cbe75d68326c5c29fdd5e2b13b3724e0c829664726667fb031c22c99318dfe04d950eb06524ee6d4d5cff76f3df13074db813c663b044f7f126907c8106a25
data/CHANGELOG.md CHANGED
@@ -1,3 +1,13 @@
1
+ ##2.2.0
2
+ -AWS-SDK-3 update
3
+ ##2.1.3
4
+ -SECURITY: Raise MIXIN to a newer Version
5
+ -fix: runs now on logstash 7.16
6
+ ##2.1.2
7
+ - FEATURE: Now it´s possible to use queue urls and names.
8
+ - FEATURE: Add sqs long polling config parameter: sqs_wait_time_seconds
9
+ - FIX: Valid UTF-8 byte sequences in logs are munged
10
+ - CLEANUP: Remove tests. (as a begin for clean testing)
1
11
  ##2.1.1
2
12
  - FEATURE: Enable Multiregion Support for included S3 client.
3
13
  - Add region by bucket feature
@@ -52,7 +52,7 @@ class S3ClientFactory
52
52
  )
53
53
  elsif credentials.key?('access_key_id') && credentials.key?('secret_access_key')
54
54
  @logger.debug("Fetch credentials", :access_key => credentials['access_key_id'])
55
- return Aws::Credentials.new(credentials)
55
+ return Aws::Credentials.new(credentials['access_key_id'], credentials['secret_access_key'])
56
56
  end
57
57
  end
58
58
 
@@ -26,17 +26,18 @@ module LogProcessor
26
26
  @logger.warn("[#{Thread.current[:name]}] Abort reading in the middle of the file, we will read it again when logstash is started")
27
27
  throw :skip_delete
28
28
  end
29
- line = line.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: "\u2370")
30
- # Potentially dangerous! See https://medium.com/@adamhooper/in-ruby-dont-use-timeout-77d9d4e5a001
31
- # Decoding a line must not last longer than a few seconds. Otherwise, the file is probably corrupt.
32
- codec.decode(line) do |event|
33
- event_count += 1
34
- decorate_event(event, metadata, type, record[:key], record[:bucket], record[:s3_data])
35
- #event_time = Time.now #PROFILING
36
- #event.set("[@metadata][progress][begin]", start_time)
37
- #event.set("[@metadata][progress][index_time]", event_time)
38
- #event.set("[@metadata][progress][line]", line_count)
39
- logstash_event_queue << event
29
+ begin
30
+ codec.decode(line) do |event|
31
+ event_count += 1
32
+ decorate_event(event, metadata, type, record[:key], record[:bucket], record[:s3_data])
33
+ #event_time = Time.now #PROFILING
34
+ #event.set("[@metadata][progress][begin]", start_time)
35
+ #event.set("[@metadata][progress][index_time]", event_time)
36
+ #event.set("[@metadata][progress][line]", line_count)
37
+ logstash_event_queue << event
38
+ end
39
+ rescue Exception => e
40
+ @logger.error("[#{Thread.current[:name]}] Unable to decode line", :line => line, :error => e)
40
41
  end
41
42
  end
42
43
  file_t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC) #PROFILING
@@ -5,8 +5,9 @@ require "logstash/timestamp"
5
5
  require "logstash/plugin_mixins/aws_config"
6
6
  require "logstash/shutdown_watcher"
7
7
  require "logstash/errors"
8
- require 'logstash/inputs/s3sqs/patch'
9
- require "aws-sdk"
8
+ require "aws-sdk-s3"
9
+ require "aws-sdk-sns"
10
+ require "aws-sdk-sqs"
10
11
 
11
12
  # "object-oriented interfaces on top of API clients"...
12
13
  # => Overhead. FIXME: needed?
@@ -35,8 +36,6 @@ require_relative 's3/downloader'
35
36
  require_relative 'codec_factory'
36
37
  require_relative 's3snssqs/log_processor'
37
38
 
38
- Aws.eager_autoload!
39
-
40
39
  # Get logs from AWS s3 buckets as issued by an object-created event via sqs.
41
40
  #
42
41
  # This plugin is based on the logstash-input-sqs plugin but doesn't log the sqs event itself.
@@ -173,6 +172,7 @@ class LogStash::Inputs::S3SNSSQS < LogStash::Inputs::Threadable
173
172
  # Whether the event is processed though an SNS to SQS. (S3>SNS>SQS = true |S3>SQS=false)
174
173
  config :from_sns, :validate => :boolean, :default => true
175
174
  config :sqs_skip_delete, :validate => :boolean, :default => false
175
+ config :sqs_wait_time_seconds, :validate => :number, :required => false
176
176
  config :sqs_delete_on_failure, :validate => :boolean, :default => true
177
177
 
178
178
  config :visibility_timeout, :validate => :number, :default => 120
@@ -251,7 +251,8 @@ class LogStash::Inputs::S3SNSSQS < LogStash::Inputs::Threadable
251
251
  @sqs_poller = SqsPoller.new(@logger, @received_stop,
252
252
  {
253
253
  visibility_timeout: @visibility_timeout,
254
- skip_delete: @sqs_skip_delete
254
+ skip_delete: @sqs_skip_delete,
255
+ wait_time_seconds: @sqs_wait_time_seconds
255
256
  },
256
257
  {
257
258
  sqs_queue: @queue,
@@ -46,13 +46,19 @@ class SqsPoller
46
46
  begin
47
47
  @logger.info("Registering SQS input", :queue => @queue)
48
48
  sqs_client = Aws::SQS::Client.new(aws_options_hash)
49
- queue_url = sqs_client.get_queue_url({
50
- queue_name: @queue,
51
- queue_owner_aws_account_id: client_options[:queue_owner_aws_account_id]
52
- }).queue_url # is a method according to docs. Was [:queue_url].
49
+ if uri?(@queue)
50
+ queue_url = @queue
51
+ else
52
+ queue_url = sqs_client.get_queue_url({
53
+ queue_name: @queue,
54
+ queue_owner_aws_account_id: client_options[:queue_owner_aws_account_id]
55
+ }).queue_url
56
+ end
57
+
53
58
  @poller = Aws::SQS::QueuePoller.new(queue_url,
54
59
  :client => sqs_client
55
60
  )
61
+ @logger.info("[#{Thread.current[:name]}] connected to queue.", :queue_url => queue_url)
56
62
  rescue Aws::SQS::Errors::ServiceError => e
57
63
  @logger.error("Cannot establish connection to Amazon SQS", :error => e)
58
64
  raise LogStash::ConfigurationError, "Verify the SQS queue name and your credentials"
@@ -185,6 +191,16 @@ class SqsPoller
185
191
  end
186
192
  end
187
193
 
194
+ def uri?(string)
195
+ uri = URI.parse(string)
196
+ %w( http https ).include?(uri.scheme)
197
+ rescue URI::BadURIError
198
+ false
199
+ rescue URI::InvalidURIError
200
+ false
201
+ end
202
+
203
+
188
204
  def get_object_path(key)
189
205
  folder = ::File.dirname(key)
190
206
  return '' if folder == '.'
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-input-s3-sns-sqs'
3
- s.version = '2.1.1'
3
+ s.version = '2.2.0.pre'
4
4
  s.licenses = ['Apache-2.0']
5
5
  s.summary = "Get logs from AWS s3 buckets as issued by an object-created event via sns -> sqs."
6
6
  s.description = "This gem is a logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not a stand-alone program"
@@ -20,9 +20,21 @@ Gem::Specification.new do |s|
20
20
 
21
21
  # Gem dependencies
22
22
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 2.1.12", "<= 2.99"
23
+ s.add_runtime_dependency "concurrent-ruby"
24
+ s.add_runtime_dependency "logstash-codec-json"
25
+ s.add_runtime_dependency "logstash-codec-plain"
26
+ s.add_runtime_dependency "aws-sdk-core", "~> 3"
27
+ s.add_runtime_dependency "aws-sdk-s3"
28
+ s.add_runtime_dependency "aws-sdk-sqs"
29
+ s.add_runtime_dependency "aws-sdk-sns"
30
+ s.add_runtime_dependency "aws-sdk-resourcegroups"
31
+
32
+ s.add_development_dependency "logstash-codec-json_lines"
33
+ s.add_development_dependency "logstash-codec-multiline"
34
+ s.add_development_dependency "logstash-codec-json"
35
+ s.add_development_dependency "logstash-codec-line"
36
+ s.add_development_dependency "logstash-devutils"
37
+ s.add_development_dependency "logstash-input-generator"
38
+ s.add_development_dependency "timecop"
23
39
 
24
- s.add_runtime_dependency 'logstash-codec-json', '~> 3.0'
25
- s.add_runtime_dependency 'logstash-mixin-aws', '~> 4.3'
26
- s.add_development_dependency 'logstash-codec-json_stream', '~> 1.0'
27
- s.add_development_dependency 'logstash-devutils', '~> 1.3'
28
40
  end
@@ -15,11 +15,13 @@ require 'rspec/expectations'
15
15
 
16
16
  describe LogStash::Inputs::S3SNSSQS do
17
17
  class LogStash::Inputs::S3SNSSQS
18
- public :process_local_log # use method without error logging for better visibility of errors
18
+ public :process # use method without error logging for better visibility of errors
19
19
  end
20
20
  let(:codec_options) { {} }
21
21
 
22
22
  let(:input) { LogStash::Inputs::S3SNSSQS.new(config) }
23
+
24
+ let(:codec_factory) { CodecFactory.new(@logger, { default_codec: @codec, codec_by_folder: @codec_by_folder }) }
23
25
  subject { input }
24
26
 
25
27
  context "default parser choice" do
@@ -28,11 +30,11 @@ describe LogStash::Inputs::S3SNSSQS do
28
30
  end
29
31
  end
30
32
 
31
- let(:compressed_log_file) { File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'log-stream.real-formatted') }
33
+ let(:record) {{"local_file" => File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'log-stream.real-formatted') }}
32
34
  let(:key) { "arn:aws:iam::123456789012:role/AuthorizedRole" }
33
35
  let(:folder) { "arn:aws:iam::123456789012:role/AuthorizedRole" }
34
36
  let(:instance_codec) { "json" }
35
- let(:queue) { "arn:aws:iam::123456789012:role/AuthorizedRole" }
37
+ let(:logstash_event_queue) { "arn:aws:iam::123456789012:role/AuthorizedRole" }
36
38
  let(:bucket) { "arn:aws:iam::123456789012:role/AuthorizedRole" }
37
39
  let(:message) { "arn:aws:iam::123456789012:role/AuthorizedRole" }
38
40
  let(:size) { "123344" }
@@ -43,18 +45,22 @@ describe LogStash::Inputs::S3SNSSQS do
43
45
  subject do
44
46
  LogStash::Inputs::S3SNSSQS.new(config)
45
47
  end
48
+ # end
46
49
  let(:queue) { [] }
47
50
  before do
48
51
  @codec = LogStash::Codecs::JSONStream.new
49
52
  @codec.charset = "UTF-8"
50
- expect( subject.process_local_log(compressed_log_file, key, folder, @codec.clone, queue, bucket, message, size) ).to be true
53
+ @codec_factory = CodecFactory.new(@logger, {
54
+ default_codec: @codec,
55
+ codec_by_folder: @codec_by_folder
56
+ })
57
+ expect( subject.process(record, logstash_event_queue) ).to be true
51
58
  $stderr.puts "method #{queue.to_s}"
52
59
  end
53
60
 
54
- it '.process_local_log => process compressed log file and verfied logstash event queue with the correct number of events' do
55
- expect( queue.size ).to eq(38)
56
- expect( queue.clear).to be_empty
57
- end
58
-
61
+ #it '.process_local_log => process compressed log file and verfied logstash event queue with the correct number of events' do
62
+ # expect( queue.size ).to eq(38)
63
+ # expect( queue.clear).to be_empty
64
+ #end
59
65
  end
60
66
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-input-s3-sns-sqs
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.2.0.pre
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christian Herweg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-23 00:00:00.000000000 Z
11
+ date: 2022-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -33,59 +33,213 @@ dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
34
  requirement: !ruby/object:Gem::Requirement
35
35
  requirements:
36
- - - "~>"
36
+ - - ">="
37
37
  - !ruby/object:Gem::Version
38
- version: '3.0'
38
+ version: '0'
39
+ name: concurrent-ruby
40
+ prerelease: false
41
+ type: :runtime
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
39
53
  name: logstash-codec-json
40
54
  prerelease: false
41
55
  type: :runtime
42
56
  version_requirements: !ruby/object:Gem::Requirement
43
57
  requirements:
44
- - - "~>"
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ name: logstash-codec-plain
68
+ prerelease: false
69
+ type: :runtime
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
45
73
  - !ruby/object:Gem::Version
46
- version: '3.0'
74
+ version: '0'
47
75
  - !ruby/object:Gem::Dependency
48
76
  requirement: !ruby/object:Gem::Requirement
49
77
  requirements:
50
78
  - - "~>"
51
79
  - !ruby/object:Gem::Version
52
- version: '4.3'
53
- name: logstash-mixin-aws
80
+ version: '3'
81
+ name: aws-sdk-core
54
82
  prerelease: false
55
83
  type: :runtime
56
84
  version_requirements: !ruby/object:Gem::Requirement
57
85
  requirements:
58
86
  - - "~>"
59
87
  - !ruby/object:Gem::Version
60
- version: '4.3'
88
+ version: '3'
61
89
  - !ruby/object:Gem::Dependency
62
90
  requirement: !ruby/object:Gem::Requirement
63
91
  requirements:
64
- - - "~>"
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ name: aws-sdk-s3
96
+ prerelease: false
97
+ type: :runtime
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ requirement: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ name: aws-sdk-sqs
110
+ prerelease: false
111
+ type: :runtime
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ requirement: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ name: aws-sdk-sns
124
+ prerelease: false
125
+ type: :runtime
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ requirement: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ name: aws-sdk-resourcegroups
138
+ prerelease: false
139
+ type: :runtime
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ requirement: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
65
149
  - !ruby/object:Gem::Version
66
- version: '1.0'
67
- name: logstash-codec-json_stream
150
+ version: '0'
151
+ name: logstash-codec-json_lines
68
152
  prerelease: false
69
153
  type: :development
70
154
  version_requirements: !ruby/object:Gem::Requirement
71
155
  requirements:
72
- - - "~>"
156
+ - - ">="
73
157
  - !ruby/object:Gem::Version
74
- version: '1.0'
158
+ version: '0'
75
159
  - !ruby/object:Gem::Dependency
76
160
  requirement: !ruby/object:Gem::Requirement
77
161
  requirements:
78
- - - "~>"
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ name: logstash-codec-multiline
166
+ prerelease: false
167
+ type: :development
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ - !ruby/object:Gem::Dependency
174
+ requirement: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ name: logstash-codec-json
180
+ prerelease: false
181
+ type: :development
182
+ version_requirements: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ - !ruby/object:Gem::Dependency
188
+ requirement: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ name: logstash-codec-line
194
+ prerelease: false
195
+ type: :development
196
+ version_requirements: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
79
199
  - !ruby/object:Gem::Version
80
- version: '1.3'
200
+ version: '0'
201
+ - !ruby/object:Gem::Dependency
202
+ requirement: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ version: '0'
81
207
  name: logstash-devutils
82
208
  prerelease: false
83
209
  type: :development
84
210
  version_requirements: !ruby/object:Gem::Requirement
85
211
  requirements:
86
- - - "~>"
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: '0'
215
+ - !ruby/object:Gem::Dependency
216
+ requirement: !ruby/object:Gem::Requirement
217
+ requirements:
218
+ - - ">="
219
+ - !ruby/object:Gem::Version
220
+ version: '0'
221
+ name: logstash-input-generator
222
+ prerelease: false
223
+ type: :development
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - ">="
227
+ - !ruby/object:Gem::Version
228
+ version: '0'
229
+ - !ruby/object:Gem::Dependency
230
+ requirement: !ruby/object:Gem::Requirement
231
+ requirements:
232
+ - - ">="
87
233
  - !ruby/object:Gem::Version
88
- version: '1.3'
234
+ version: '0'
235
+ name: timecop
236
+ prerelease: false
237
+ type: :development
238
+ version_requirements: !ruby/object:Gem::Requirement
239
+ requirements:
240
+ - - ">="
241
+ - !ruby/object:Gem::Version
242
+ version: '0'
89
243
  description: This gem is a logstash plugin required to be installed on top of the
90
244
  Logstash core pipeline using $LS_HOME/bin/plugin install gemname. This gem is not
91
245
  a stand-alone program
@@ -106,7 +260,6 @@ files:
106
260
  - lib/logstash/inputs/s3/downloader.rb
107
261
  - lib/logstash/inputs/s3snssqs.rb
108
262
  - lib/logstash/inputs/s3snssqs/log_processor.rb
109
- - lib/logstash/inputs/s3sqs/patch.rb
110
263
  - lib/logstash/inputs/sqs/poller.rb
111
264
  - logstash-input-s3-sns-sqs.gemspec
112
265
  - spec/inputs/s3sqs_spec.rb
@@ -127,12 +280,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
127
280
  version: '0'
128
281
  required_rubygems_version: !ruby/object:Gem::Requirement
129
282
  requirements:
130
- - - ">="
283
+ - - ">"
131
284
  - !ruby/object:Gem::Version
132
- version: '0'
285
+ version: 1.3.1
133
286
  requirements: []
134
- rubyforge_project:
135
- rubygems_version: 2.6.13
287
+ rubygems_version: 3.1.6
136
288
  signing_key:
137
289
  specification_version: 4
138
290
  summary: Get logs from AWS s3 buckets as issued by an object-created event via sns
@@ -1,22 +0,0 @@
1
- # This patch was stolen from logstash-plugins/logstash-output-s3#102.
2
- #
3
- # This patch is a workaround for a JRuby issue which has been fixed in JRuby
4
- # 9000, but not in JRuby 1.7. See https://github.com/jruby/jruby/issues/3645
5
- # and https://github.com/jruby/jruby/issues/3920. This is necessary because the
6
- # `aws-sdk` is doing tricky name discovery to generate the correct error class.
7
- #
8
- # As per https://github.com/aws/aws-sdk-ruby/issues/1301#issuecomment-261115960,
9
- # this patch may be short-lived anyway.
10
- require 'aws-sdk'
11
-
12
- begin
13
- old_stderr = $stderr
14
- $stderr = StringIO.new
15
-
16
- module Aws
17
- const_set(:S3, Aws::S3)
18
- const_set(:SQS, Aws::SQS)
19
- end
20
- ensure
21
- $stderr = old_stderr
22
- end