One small issue with the current version (0.4.0) of the AWS/S3 ruby library is that there is no way to determine the name or path for an instance of an s3 log file (AWS::S3::Logging:Log) …

    1 require 'aws/s3'
    2 s3_logs = AWS::S3::Bucket.logs_for AWS_S3_BUCKET
    3 s3_logs.each do |s3_log|
    4   # This will raise an exception b/c AWS::S3::Logging:Log class has no path attribute!
    5   puts "Loading log file: #{s3_log.path}"
    6 end

Line 5 above will result in an exception b/c that attribute does not exist … In fact the only thing you can get from an instance of this object is a collection of the lines within the log file. In my use of this library, one of the things I needed was the relative path of the log file, so that after processing it, I could record it in the application database.

If you look in the logging.rb file, you will see something like (note I’ve removed some lines of code) …

    1 class Log
    2   def initialize(log_object) #:nodoc:
    3     @log = log_object
    4   end
    5   # ...
    6   # some other stuff here that I've removed b/c it's not important 
    7   # ...
    8   def inspect #:nodoc:
    9     "#<%s:0x%s '%s'>" % [self.class.name, object_id, log.path]
   10   end
   11   
   12   private
   13     attr_reader :log
   14 
   15   # ... some other stuff ...
   16 end

So the log instance variable is made private but it has a .path attribute being used by the inspect method. That makes life easy… all we have to do to expose the .path attribute is create the following monkey patch:

    1 class AWS::S3::Logging::Log
    2   def path
    3     return log.path
    4   end
    5 end

Save it as a .rb file in your application’s lib directory (eg: aws_patch.rb) and require it before you make the call:

    1 require 'aws/s3'
    2 require 'aws_patch'
    3 s3_logs = AWS::S3::Bucket.logs_for AWS_S3_BUCKET
    4 s3_logs.each do |s3_log|
    5   # This will no longer raise an exception
    6   puts "Loading log file: #{s3_log.path}"
    7 end

Remember that (for obvious reasons) you cannot apply this fix before requiring ‘aws/s3’ , only after (see example above).

Cheers

Sorry, comments are closed for this article.