Sir Tracks Alot is a ruby library designed to aid in the tracking, collating and analysis of arbitrary usage data. You can use it to record anything! Then summarize what's been recorded into useful graphs. The primary use case for Sir Tracks Alot was to instrument web usage of Rails applications.

For example, to that a specific user has viewed a specific page:

SirTracksAlot.record_activity :owner => 'owner', :actor => '/users/123', :target => '/pages/1'

To include information taken from a web request (such as the user agent), simple include it:

SirTracksAlot.record_activity :owner => 'owner', :actor => '/users/123', :target => '/pages/1', :request => request

You can also include the notion of action type:

SirTracksAlot.record_activity :owner => 'owner', :actor => '/users/123', :target => '/pages/1', :action => 'create' To investigate what's been stored you can filter activities with a variety of method and any attribute can be queried.

Direct queries work on strings. For example, to search for all activities by a certain owner:

Activity.filter(:owner => 'owner') Regular expressions can be used:

Activity.filter(:owner => 'owner', :target => //pages/d+/)

You can also combine permutations of various options. For example, to find all 'create' and 'view' actions for both '/pages' and '/profiles' targets:

Activity.filter(:owner => 'owner', :target => ['/pages', '/profiles'], :actions => ['create', 'destroy'])

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so I don't break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  • Send me a pull request. Bonus points for topic branches.

Copyright © 2010 Peter T. Brown. See LICENSE for details.

# resolution can be: hourly = %Y/%m/%d %H, daily = %Y/%m/%d or any valid strftime string # def self.count_by(resolution, options_for_find = {})

# groups = {} #

# filter(options_for_find) do |activity| # activity.views(resolution).each do |time, count| # groups ||= 0 # groups += count # end # end #

# groups # end

# def self.count(what, options_for_find)

# what = [what] unless what.kind_of?(Array)

# views, visits = 0, 0

# session_duration = options_for_find.delete(:session_duration) # resolution = options_for_find.delete(:resolution) #

# filter(options_for_find) do |activity| # views = activity.views(resolution) if what.include?(:views) # visits = activity.visits(session_duration) if what.include?(:visits) # end


# return [views, visits] if what == [:views, :visits] # return [visits, views] if what == [:visits, :views] # return views if what == [:views] # return visits if what == [:visits] # raise ArgumentError(“what must be one or more of :views, :visits”) # end