almaz-revelation 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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