Permalink
Browse files

Cleaner support for intersection, though limited in functionality. Up…

…dated rdoc as well.
  • Loading branch information...
1 parent 84b45a9 commit 0667d71dea9204116468305179cc2f7d01940325 masonoise committed Apr 16, 2010
Showing with 50 additions and 13 deletions.
  1. +38 −9 README.rdoc
  2. +11 −3 lib/redis_logger.rb
  3. +1 −1 redis_logger.gemspec
View
@@ -2,20 +2,27 @@
Application logging to redis.
+== Version
+
+Version 0.1.0
+
== Installation
sudo gem install redis_logger
You will also want to install the web interface for viewing the log entries:
- sudo gem install redis_logger_web
+ http://github.com/masonoise/redis_logger-web
-== Using
+== Using RedisLogger
-1. Install redis
+1. Install redis (http://code.google.com/p/redis/) and redis_logger
-2. In your application code, place a call to RedisLogger, using one of: debug, warn, error. Each call is expected to pass a Hash of data, and an optional list of groups to which you want the log entry to belong. For example, you might want to log all of your requests to a group called "requests", so you might put this call into your application_controller.rb file in a before_filter:
+2. In your application code, place a call to RedisLogger, using one of: debug, warn, error. Each call is expected to
+ pass a Hash of data, and an optional list of groups to which you want the log entry to belong. For example, you
+ might want to log all of your requests to a group called "requests", so you might put this call into your
+ application_controller.rb file in a before_filter:
RedisLogger.debug({ "request" => request.url,
"remote_ip" => request.remote_ip,
@@ -29,11 +36,32 @@ all user signup activity into a "signup" group, for example. Using the web inter
in a group or all the entries in an intersection of multiple groups -- for example, all errors in the signup
process.
+If you want to use redis-cli to look things over instead of the web interface, here are the basics:
+
+ ./redis-cli
+ sort logger:set:debug limit 0 10 desc
+ ==> returns most recent 10 keys from the debug group, each of which maps to a Hash of log fields
+ hgetall log:1271274209
+ ==> returns the keys and values for that log entry
+ smembers logger:sets
+ ==> returns list of the groups that have been logged into
+
+== Known Issues
----
+1. Currently the log keys are simply the longint timestamps of each entry. If multiple threads are going
+ it's very possible that they'll log at the same instant and only one entry will survive. Need to work
+ out a way to identify each server with a unique id that could be added to the log keys, such as
+ log:1:<timestamp>, log:2:<timestamp>, etc.
+2. It would be nice to cache the group names so it doesn't have to add the group to logger:sets each time.
+3. Support for viewing intersection of groups is limited to most recent 100 entries right now. It will
+ be nice to keep the stored intersection set around for viewing, pagination, and export, but we need to
+ have a way to clean up the stored sets periodically.
+
+== Contributing
+
+This is very young and simple thus far. If you have some cool ideas, go for it, give it a try, if it seems
+good to you then get in touch and we'll see about merging it in.
-== 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
@@ -42,6 +70,7 @@ process.
(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
+== Author
+
+Mason Jones ~~~ stuff@charnel.com ~~~ @masonoise
-Copyright (c) 2010 Mason Jones. See LICENSE for details.
View
@@ -40,10 +40,12 @@ def self.debug(log_entry, sets = nil)
add_entry(log_entry, "debug", sets)
end
+
def self.warn(log_entry, sets = nil)
add_entry(log_entry, "warn", sets)
end
+ # Standard method for error messages. See comment above about debug()
def self.error(log_entry, sets = nil)
add_entry(log_entry, "error", sets)
end
@@ -82,11 +84,17 @@ def self.entries(group, start=0, per_page=50)
#
# Get the entries for an intersection of groups. Takes an array of group names and
- # returns the resulting entries.
+ # returns the top 100 resulting entries. This is done by intersecting into a new set,
+ # fetching the first 100 entries, then deleting the set.
+ # TODO: Save the intersected set, allow paginating, and use a cron to delete the temp sets
#
def self.intersect(groups)
- entry_list = redis.sinter(groups.collect {|g| "logger:set:#{g}"})
- fetch_entries(entry_list)
+ counter = redis.incrby("logger:index", 1)
+ redis.sinterstore("logger:inter:#{counter}", groups.collect {|g| "logger:set:#{g}"})
+ entry_list = redis.sort("logger:inter:#{counter}", { :limit => [ 0, 100 ], :order => "DESC" })
+ entries = fetch_entries(entry_list)
+ redis.del("logger:inter:#{counter}")
+ return entries
end
#
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["masonoise"]
- s.date = %q{2010-04-15}
+ s.date = %q{2010-04-16}
s.description = %q{Provides support for applicationlogging to Redis, including grouping log entries and timestamping}
s.email = %q{masonoise@charnel.com}
s.extra_rdoc_files = [

0 comments on commit 0667d71

Please sign in to comment.