11
11
require "fileutils"
12
12
require "set"
13
13
require "pathname"
14
+ require "aws-sdk"
15
+ require "logstash/outputs/s3/patch"
14
16
17
+ Aws . eager_autoload!
15
18
16
19
# INFORMATION:
17
20
#
@@ -118,7 +121,7 @@ class LogStash::Outputs::S3 < LogStash::Outputs::Base
118
121
## This is hack for not destroy the new files after restoring the initial files.
119
122
## If you do not specify "restore => true" when logstash crashes or is restarted, the files are not sent into the bucket,
120
123
## for example if you have single Instance.
121
- config :restore , :validate => :boolean , :default => false
124
+ config :restore , :validate => :boolean , :default => true
122
125
123
126
# The S3 canned ACL to use when putting the file. Defaults to "private".
124
127
config :canned_acl , :validate => [ "private" , "public_read" , "public_read_write" , "authenticated_read" ] ,
@@ -191,20 +194,21 @@ def register
191
194
@file_repository = FileRepository . new ( @tags , @encoding , @temporary_directory )
192
195
193
196
@rotation = rotation_strategy
194
- @uploader = Uploader . new ( bucket_resource , @logger , Concurrent ::ThreadPoolExecutor . new ( {
195
- :min_threads => 1 ,
196
- :max_threads => @upload_workers_count ,
197
- :max_queue => @upload_queue_size ,
198
- :fallback_policy => :caller_runs
199
- } ) )
197
+
198
+ executor = Concurrent ::ThreadPoolExecutor . new ( { :min_threads => 1 ,
199
+ :max_threads => @upload_workers_count ,
200
+ :max_queue => @upload_queue_size ,
201
+ :fallback_policy => :caller_runs } )
202
+
203
+ @uploader = Uploader . new ( bucket_resource , @logger , executor )
200
204
201
205
# Restoring from crash will use a new threadpool to slowly recover
202
206
# New events should have more priority.
203
207
restore_from_crash if @restore
204
208
205
209
# If we need time based rotation we need to do periodic check on the file
206
210
# to take care of file that were not updated recently
207
- start_periodic_check if @rotation . need_periodic ?
211
+ start_periodic_check if @rotation . needs_periodic ?
208
212
end
209
213
210
214
def multi_receive_encoded ( events_and_encoded )
@@ -229,7 +233,7 @@ def multi_receive_encoded(events_and_encoded)
229
233
end
230
234
231
235
def close
232
- stop_periodic_check if @rotation . need_periodic ?
236
+ stop_periodic_check if @rotation . needs_periodic ?
233
237
234
238
@logger . debug ( "Uploading current workspace" )
235
239
@@ -294,7 +298,8 @@ def upload_options
294
298
295
299
def rotate_if_needed ( prefixes )
296
300
prefixes . each do |prefix |
297
- # Each file access is thread safe, until the rotation is done then only
301
+ # Each file access is thread safe,
302
+ # until the rotation is done then only
298
303
# one thread has access to the resource.
299
304
@file_repository . get_factory ( prefix ) do |factory |
300
305
temp_file = factory . current
@@ -316,7 +321,7 @@ def upload_file(temp_file)
316
321
@logger . debug ( "Queue for upload" , :path => temp_file . path )
317
322
318
323
# if the queue is full the calling thread will be used to upload
319
- temp_file . fsync # make sure we flush the fd before uploading it.
324
+ temp_file . close # make sure the content is on disk
320
325
if temp_file . size > 0
321
326
@uploader . upload_async ( temp_file ,
322
327
:on_complete => method ( :clean_temporary_file ) ,
@@ -346,14 +351,12 @@ def restore_from_crash
346
351
@crash_uploader = Uploader . new ( bucket_resource , @logger , CRASH_RECOVERY_THREADPOOL )
347
352
348
353
temp_folder_path = Pathname . new ( @temporary_directory )
349
- Dir . glob ( ::File . join ( @temporary_directory , "**/*" ) ) do |file |
350
- if ::File . file? ( file )
351
- key_parts = Pathname . new ( file ) . relative_path_from ( temp_folder_path ) . to_s . split ( ::File ::SEPARATOR )
352
- temp_file = TemporaryFile . new ( key_parts . slice ( 1 , key_parts . size ) . join ( "/" ) , ::File . open ( file , "r" ) , key_parts . slice ( 0 , 1 ) )
353
-
354
- @logger . debug ( "Recovering from crash and uploading" , :file => temp_file . path )
355
- @crash_uploader . upload_async ( temp_file , :on_complete => method ( :clean_temporary_file ) )
356
- end
354
+ Dir . glob ( ::File . join ( @temporary_directory , "**/*" ) )
355
+ . select { |file | ::File . file? ( file ) }
356
+ . each do |file |
357
+ temp_file = TemporaryFile . create_from_existing_file ( file , temp_folder_path )
358
+ @logger . debug ( "Recovering from crash and uploading" , :file => temp_file . path )
359
+ @crash_uploader . upload_async ( temp_file , :on_complete => method ( :clean_temporary_file ) )
357
360
end
358
361
end
359
362
end
0 commit comments