almaz-revelation 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ dump.rdb
2
+ pkg
3
+ almaz-*.gem
4
+ almaz.gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2009 James Pozdena
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,26 @@
1
+ h1. Almaz
2
+
3
+ <img src='http://jpoz.net/almaz-medium-transparent.png'/>
4
+
5
+ Almaz is always watching!
6
+
7
+ h2. Explanation
8
+
9
+ Almaz is rack middlware which logs request information to a redis server, under a preset user session variable.
10
+
11
+ h2. Example
12
+
13
+ h3. Almaz::Capture
14
+
15
+ <pre>
16
+ <code>
17
+ require 'almaz'
18
+
19
+ use Almaz::Capture
20
+
21
+ Almaz.config[:redis] = {:db => 0, :host => 'localhost', :port => 6379} # this is also the default
22
+ Almaz.config[:session_variable] = :user #this is also the default
23
+ </code>
24
+ </pre>
25
+
26
+ By using Almaz::Capture and setting the session_variable to :user, all requests are now logged under 'almaz::user::(session[:user])' in redis. Each user gets a separate list in the redis DB. All requests that don't have the session variable :user are logged under 'almaz::user::'.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'spec'
4
+
5
+ begin
6
+ require 'jeweler'
7
+ Jeweler::Tasks.new do |gem|
8
+ gem.name = "almaz-revelation"
9
+ gem.summary = "Almaz is watching!"
10
+ gem.description = "Almaz is a ruby rack middleware redis logger"
11
+ gem.email = "ops@revelationglobal.com"
12
+ gem.homepage = "http://github.com/revelation/almaz"
13
+ gem.authors = ['James Pozdena', 'Max Ogden', 'Andrew Kurtz', 'Dan Herrera']
14
+ gem.add_dependency "redis"
15
+ gem.add_dependency "json"
16
+ gem.add_development_dependency 'timecop'
17
+ gem.add_development_dependency 'sinatra'
18
+ end
19
+ Jeweler::GemcutterTasks.new
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
+ end
23
+
24
+ require 'spec/rake/spectask'
25
+ Spec::Rake::SpecTask.new(:spec) do |spec|
26
+ spec.libs << 'lib' << 'spec'
27
+ spec.spec_files = FileList['spec/**/*_spec.rb']
28
+ end
29
+
30
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
31
+ spec.libs << 'lib' << 'spec'
32
+ spec.pattern = 'spec/**/*_spec.rb'
33
+ spec.rcov = true
34
+ end
35
+
36
+ task :spec => :check_dependencies
37
+
38
+ task :default => :spec
data/lib/almaz.rb ADDED
@@ -0,0 +1,43 @@
1
+ require 'redis'
2
+ require 'json'
3
+
4
+ class Almaz
5
+ @config = { :redis => {:db => 0},
6
+ :session_variable => :user,
7
+ :max_list_size => 100,
8
+ :capture_keys => [:request_method, :path_info, :referrer, :params, :ip]
9
+ }
10
+
11
+ def self.config
12
+ @config
13
+ end
14
+
15
+ class Capture
16
+ def initialize(app)
17
+ @app = app
18
+ @r = Redis.new(Almaz.config[:redis])
19
+ end
20
+
21
+ def call(env)
22
+ begin
23
+ request = Rack::Request.new(env)
24
+ key = "almaz::#{Almaz.config[:session_variable]}::#{env['rack.session'][Almaz.config[:session_variable]]}"
25
+ @r.rpush(key, capture_keys(request).to_json)
26
+ @r.ltrim(key, 0, Almaz.config[:max_list_size] - 1)
27
+ rescue => e
28
+ puts "ALMAZ ERROR: #{e}"
29
+ end
30
+
31
+ @app.call(env)
32
+ end
33
+
34
+ def capture_keys(request)
35
+ captured = {}
36
+ Rack::Request.public_instance_methods(false).each do |request_method|
37
+ captured[request_method] = request.send(request_method.to_sym) if Almaz.config[:capture_keys].include?(request_method.to_sym)
38
+ end
39
+ captured.merge!(:time => Time.now.to_s)
40
+ captured
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,64 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
2
+ require 'rack/test'
3
+
4
+ describe Almaz do
5
+ before(:each) do
6
+ Almaz.config[:redis] = {:db => 15}
7
+ end
8
+
9
+ describe Almaz::Capture do
10
+ include Rack::Test::Methods
11
+
12
+ def app
13
+ use Rack::Session::Cookie, :key => '_max_project_session'
14
+ use Almaz::Capture
15
+ Sinatra::Application
16
+ end
17
+
18
+ describe "with session's user id" do
19
+
20
+ before(:each) do
21
+ session_info = {:user => 1}
22
+ rack_mock_session.set_cookie("_max_project_session=#{[Marshal.dump(session_info)].pack("m*")}")
23
+ end
24
+
25
+ it "should capture the request path under the session_variable" do
26
+ get '/awesome/controller'
27
+ @db.lrange('almaz::user::1',0,-1).first.should include('/awesome/controller')
28
+ end
29
+
30
+ it "should capture the request query params under the session_variable" do
31
+ get '/awesome/controller?whos=yourdaddy&what=doeshedo'
32
+ logged_request = @db.lrange('almaz::user::1',0,-1).first
33
+ JSON.parse(logged_request)['params'].should == {"whos"=>"yourdaddy", "what"=>"doeshedo"}
34
+ end
35
+
36
+ it "should capture the request method params under the session_variable" do
37
+ get '/awesome/controller'
38
+ @db.lrange('almaz::user::1',0,-1).first.should include('GET')
39
+ end
40
+
41
+ it "should capture the post params under the session_variable" do
42
+ post '/awesome/controller', :didyouknow => 'thatyouremyhero'
43
+ logged_request = @db.lrange('almaz::user::1',0,-1).first
44
+ JSON.parse(logged_request)['params'].should == {"didyouknow"=>"thatyouremyhero"}
45
+ end
46
+
47
+ it "should record a timestamp on each request" do
48
+ Timecop.freeze(Date.today + 30) do
49
+ post '/awesome/controller', :didyouknow => 'thatyouremyhero'
50
+ @db.lrange('almaz::user::1',0,-1).first.should include(Time.now.to_s)
51
+ end
52
+ end
53
+
54
+ it "should only store the most recent requests up to the maximum configured length" do
55
+ max_size = Almaz.config[:max_list_size] = 10
56
+ post '/awesome/controller', :didyouknow => 'thisshouldbedeleted'
57
+ max_size.times {|taco| post '/awesome/controller', :didyouknow => 'thatyouremyhero'}
58
+ @db.llen('almaz::user::1').should == max_size
59
+ logged_request = @db.lrange('almaz::user::1', -1, -1).first
60
+ JSON.parse(logged_request)['params'].should_not == {"didyouknow"=>"thisshouldbedeleted"}
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,36 @@
1
+ require 'rubygems'
2
+ gem 'rspec', '>= 1.2.8'
3
+ require 'spec'
4
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'almaz')
5
+ require 'base64'
6
+ require 'timecop'
7
+ require 'logger'
8
+ require 'date'
9
+ require 'sinatra'
10
+
11
+ Spec::Runner.configure do |config|
12
+ config.before(:all) {
13
+ @db = Redis.new(:db => 15) #, :logger => Logger.new(STDOUT), :debug => true)
14
+ }
15
+
16
+ config.after(:each) {
17
+ @db.flushdb
18
+ }
19
+
20
+ config.after(:all) {
21
+ @db.quit
22
+ }
23
+ end
24
+
25
+ def encode_credentials(username, password)
26
+ "Basic " + Base64.encode64("#{username}:#{password}")
27
+ end
28
+
29
+
30
+ class ExampleSinatraApp < Sinatra::Base
31
+
32
+ get '/awesome/controller' do
33
+ 'wooo hoo'
34
+ end
35
+
36
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: almaz-revelation
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 4
9
+ version: 0.0.4
10
+ platform: ruby
11
+ authors:
12
+ - James Pozdena
13
+ - Max Ogden
14
+ - Andrew Kurtz
15
+ - Dan Herrera
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2010-07-06 00:00:00 -07:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: redis
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: json
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :runtime
46
+ version_requirements: *id002
47
+ - !ruby/object:Gem::Dependency
48
+ name: timecop
49
+ prerelease: false
50
+ requirement: &id003 !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: sinatra
61
+ prerelease: false
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ type: :development
70
+ version_requirements: *id004
71
+ description: Almaz is a ruby rack middleware redis logger
72
+ email: ops@revelationglobal.com
73
+ executables: []
74
+
75
+ extensions: []
76
+
77
+ extra_rdoc_files:
78
+ - README.textile
79
+ files:
80
+ - .gitignore
81
+ - MIT-LICENSE
82
+ - README.textile
83
+ - Rakefile
84
+ - lib/almaz.rb
85
+ - spec/almaz_spec.rb
86
+ - spec/spec_helper.rb
87
+ has_rdoc: true
88
+ homepage: http://github.com/revelation/almaz
89
+ licenses: []
90
+
91
+ post_install_message:
92
+ rdoc_options:
93
+ - --charset=UTF-8
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ requirements: []
111
+
112
+ rubyforge_project:
113
+ rubygems_version: 1.3.6
114
+ signing_key:
115
+ specification_version: 3
116
+ summary: Almaz is watching!
117
+ test_files:
118
+ - spec/almaz_spec.rb
119
+ - spec/spec_helper.rb