Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to monitor Amazon S3 resource usage via a Ruby on Rails app?

Let say, I have a web application that allows users to upload images and documents and my application stores all those assets on S3, is there a way I can monitor resource usage PER user account?

For example, if a user account has a 1GB storage limit, how can I monitor how much of that allowance any individual is using?

Furthermore (but this is less of an issue to me) if that user account also has a 5GB bandwidth limit, are there any tools available that allow me to monitor just their S3 bandwidth?

like image 652
aaronrussell Avatar asked Nov 05 '22 15:11

aaronrussell


1 Answers

Yes, this is possible. You can use papreclip to manage file uploads (or any other reputable upload management plugin/gem). Most of these tools give you access to the filesize of the uploaded file. You can simply store these files in the database along with the asset_uri (which I imagine you're already storing), and to check if a user can upload another file, simply sum all the sizes of all assets with the appropriate user_id.

Users:
  id
  email_address
  first_name
  upload_limit

Assets:
  id
  user_id
  uri
  filesize
  filename

Then, to grab the total size of uploaded files by a particular user, you could do:

class User < ActiveRecord::Base
  has_many :assets

  #Check if the user can upload another file
  def can_upload?
    if Asset.sum('filesize', :conditions => 'user_id = #{self.id}') >= self.upload_limit
      return false
    else
      return true
    end
  end

  #See the user's used storage space
  def used_storage
    return Asset.sum('filesize', :conditions => 'user_id = #{self.id}')
  end

  #See how much space the user has remaining
  def available_storage
    if self.can_upload?
      return self.upload_limit - Asset.sum('filesize', :conditions => 'user_id = #{self.id}')
    else
      return 0
    end
  end
end

You can see I'm making use of the ActiveRecord sum function here to do the calculation. You could just as easily use a map or some other ruby based solution.

like image 153
Mike Trpcic Avatar answered Nov 12 '22 16:11

Mike Trpcic