all_seeing_eye 0.0.19 → 0.0.20
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +0 -1
- data/Gemfile.lock +0 -2
- data/README.markdown +120 -0
- data/VERSION +1 -1
- data/all_seeing_eye.gemspec +7 -8
- data/examples/all_seeing_eye-nginx.conf +12 -0
- data/lib/all_seeing_eye/generators/all_seeing_eye.yml +45 -0
- data/lib/all_seeing_eye/generators/all_seeing_eye_generator.rb +7 -0
- data/lib/all_seeing_eye/model.rb +1 -27
- data/lib/all_seeing_eye/server/views/total.erb +1 -1
- data/lib/all_seeing_eye/server.rb +9 -7
- data/lib/all_seeing_eye.rb +29 -11
- data/test/base_test.rb +14 -1
- data/test/fixtures/all_seeing_eye.yml +9 -2
- data/test/model_test.rb +74 -83
- data/test/test_helper.rb +2 -2
- metadata +22 -34
- data/README.rdoc +0 -19
- data/lib/all_seeing_eye/models/request.rb +0 -3
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
data/README.markdown
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
# AllSeeingEye
|
2
|
+
|
3
|
+
A highly configurable Gem to collect specific data from requests, and view that data in a cute little Sinatra app.
|
4
|
+
|
5
|
+
AllSeeingEye writes information about each request it observes into Redis. What kind of information? Why, whatever
|
6
|
+
you want! From the relatively banal (IP address, URI, user agent) to complicated application-specific data
|
7
|
+
(user account, ordered product, money spent), anything can be recorded by AllSeeingEye, stored in Redis, and indexed to be
|
8
|
+
viewed quickly in Sinatra. With pretty Flot-based graphs, even.
|
9
|
+
|
10
|
+
It comes with a Rails2 integration by default, but I think with a little work it'd be pretty easy to get it into Rails3.
|
11
|
+
|
12
|
+
## Background
|
13
|
+
|
14
|
+
Our application receives about half a million requests every day. While we have Google Analytics, and it's totally awesome,
|
15
|
+
many of those requests come from our iPhone app, and those requests don't receive the level of tracking we need. We could load
|
16
|
+
reporting software onto a users' iOS device: but, ethical issues aside, why would we want to? Almost anything we'd be
|
17
|
+
interested in tracking requires server interaction anyway, so it's easier and faster to track it all on the server side.
|
18
|
+
|
19
|
+
The obvious solution was to mine the Rails logfiles, but we have multiple servers and weaving all the logs was a pain -- and
|
20
|
+
even when we did, some of the data we wanted wasn't exposed. My next thought was to log requests to our database, but we
|
21
|
+
experience enough database traffic as is without writing every request. A MemCached-backed write-through buffer temporarily
|
22
|
+
worked but when the writes happened the database still got very unhappy... and the table got enormous very quickly.
|
23
|
+
|
24
|
+
Redis was a good compromise though. We use it for the truly excellent Resque, so it's already part of our stack. It's fast
|
25
|
+
and, while it's persistent, it's not exactly a tragedy if the Redis DB gets hosed, as none of the request data is so important
|
26
|
+
we can't just start collecting it again. Combined with some code to store arbitrary data, we quickly had a winner on our hands.
|
27
|
+
|
28
|
+
So, AllSeeingEye was born out of our need to track incoming requests accurately, quickly, and in a way that is easily
|
29
|
+
displayable to our business users.
|
30
|
+
|
31
|
+
## Installation
|
32
|
+
|
33
|
+
Get Redis via the amazing Homebrew: `brew install redis`
|
34
|
+
|
35
|
+
Add AllSeeingEye to your project's Gemfile: `gem 'all\_seeing\_eye'`
|
36
|
+
|
37
|
+
Install it with Bundler: `bundle install`
|
38
|
+
|
39
|
+
## Setup
|
40
|
+
|
41
|
+
bundle exec ruby script/generate all\_seeing\_eye
|
42
|
+
|
43
|
+
This puts the AllSeeingEye config file at config/all\_seeing\_eye.yml. The file is annotated with all the information you
|
44
|
+
need to get started, but some quick explanation:
|
45
|
+
|
46
|
+
### Timeout
|
47
|
+
AllSeeingEye's data collection is wrapped by a timeout to ensure speediness. I keep this value at 30 milliseconds (0.03), but
|
48
|
+
feel free to change it to suit your application's needs.
|
49
|
+
|
50
|
+
### Round To Seconds
|
51
|
+
One data point per request is too many to sensibly view on a graph. This rounds the created\_at time of requests
|
52
|
+
to whatever (I choose 10 minutes), so that all requests within 10 minutes are collected and displayed together.
|
53
|
+
|
54
|
+
### Redis
|
55
|
+
Environment and then location of the redis server. If you do not include this key, AllSeeingEye tries to look for a redis.yml
|
56
|
+
or a resque.yml file instead to find the server.
|
57
|
+
|
58
|
+
### Models
|
59
|
+
You can define a number of different models to collect data with. Each has its own separate namespace, so data won't be
|
60
|
+
shared between them. I only use one right now (I call it 'request'), but if you want more then go for it.
|
61
|
+
|
62
|
+
Each model definition should be structured like this:
|
63
|
+
|
64
|
+
model\_name:
|
65
|
+
first\_field\_name:
|
66
|
+
object: object_name
|
67
|
+
method: .method_name
|
68
|
+
second\_field\_name:
|
69
|
+
object: hash
|
70
|
+
method: "['key']"
|
71
|
+
|
72
|
+
Model names and field names are completely arbitrary, and I try to humanize them as best as I can.
|
73
|
+
|
74
|
+
Object and method are the literal object and the actual method you want executed, with one exception: the object
|
75
|
+
'controller' is translated into 'self'. The result of this is stored by AllSeeingEye in redis. So, for example, an
|
76
|
+
object could be "request" and the method could be "request\_uri". I'm trying to do a little secure sanity-checking here
|
77
|
+
rather than just directly eval'ing a string, but you can still mess things up pretty badly if you choose a bad object
|
78
|
+
and/or bad method... so try not to do that.
|
79
|
+
|
80
|
+
As a helpful hint, recording "request\_uri" isn't nearly as helpful as you might think. Try to save requests without any params
|
81
|
+
and without a leading slash by defining a method in ApplicationController instead:
|
82
|
+
|
83
|
+
protected
|
84
|
+
def clean_request
|
85
|
+
request.request_uri.split('?').first[1..-1]
|
86
|
+
end
|
87
|
+
|
88
|
+
Then, in your all\_seeing\_eye.yml:
|
89
|
+
|
90
|
+
request:
|
91
|
+
uri:
|
92
|
+
object: controller
|
93
|
+
method: .clean_request
|
94
|
+
|
95
|
+
## Running
|
96
|
+
|
97
|
+
When your Rails application starts, you should see each request contain "+++ Request watched by AllSeeingEye." That means
|
98
|
+
AllSeeingEye is running successfully. Good job!
|
99
|
+
|
100
|
+
Starting the server is simple. Just type `all-seeing-eye` from the commandline and Sinatra should start automatically.
|
101
|
+
|
102
|
+
## Extras
|
103
|
+
|
104
|
+
I included the Nginx config we use for AllSeeingEye as a small bonus. It's in examples/all\_seeing\_eye-nginx.conf.
|
105
|
+
|
106
|
+
## Contributing to AllSeeingEye
|
107
|
+
|
108
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
109
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
110
|
+
* Fork the project
|
111
|
+
* Start a feature/bugfix branch
|
112
|
+
* Commit and push until you are happy with your contribution
|
113
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
114
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
115
|
+
|
116
|
+
## Copyright
|
117
|
+
|
118
|
+
Copyright (c) 2011 Josh Symonds. See LICENSE.txt for
|
119
|
+
further details.
|
120
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.20
|
data/all_seeing_eye.gemspec
CHANGED
@@ -5,33 +5,35 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{all_seeing_eye}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.20"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Josh Symonds"]
|
12
|
-
s.date = %q{2011-08-
|
12
|
+
s.date = %q{2011-08-16}
|
13
13
|
s.default_executable = %q{all-seeing-eye}
|
14
14
|
s.description = %q{AllSeeingEye observes all requests, with parameters that you specify, to Redis. Then it composes them into graphs for you to see.}
|
15
15
|
s.email = %q{veraticus@gmail.com}
|
16
16
|
s.executables = ["all-seeing-eye"]
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"LICENSE.txt",
|
19
|
-
"README.
|
19
|
+
"README.markdown"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
22
|
"Gemfile",
|
23
23
|
"Gemfile.lock",
|
24
24
|
"LICENSE.txt",
|
25
|
-
"README.
|
25
|
+
"README.markdown",
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"all_seeing_eye.gemspec",
|
29
29
|
"bin/all-seeing-eye",
|
30
|
+
"examples/all_seeing_eye-nginx.conf",
|
30
31
|
"init.rb",
|
31
32
|
"lib/all_seeing_eye.rb",
|
33
|
+
"lib/all_seeing_eye/generators/all_seeing_eye.yml",
|
34
|
+
"lib/all_seeing_eye/generators/all_seeing_eye_generator.rb",
|
32
35
|
"lib/all_seeing_eye/integrations/rails2.rb",
|
33
36
|
"lib/all_seeing_eye/model.rb",
|
34
|
-
"lib/all_seeing_eye/models/request.rb",
|
35
37
|
"lib/all_seeing_eye/server.rb",
|
36
38
|
"lib/all_seeing_eye/server/public/application.js",
|
37
39
|
"lib/all_seeing_eye/server/public/eye.png",
|
@@ -63,7 +65,6 @@ Gem::Specification.new do |s|
|
|
63
65
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
64
66
|
s.add_runtime_dependency(%q<redis>, [">= 0"])
|
65
67
|
s.add_runtime_dependency(%q<chronic>, [">= 0"])
|
66
|
-
s.add_runtime_dependency(%q<rbtree>, [">= 0"])
|
67
68
|
s.add_runtime_dependency(%q<sinatra>, [">= 0"])
|
68
69
|
s.add_runtime_dependency(%q<vegas>, [">= 0"])
|
69
70
|
s.add_runtime_dependency(%q<activesupport>, [">= 2.3.12"])
|
@@ -75,7 +76,6 @@ Gem::Specification.new do |s|
|
|
75
76
|
else
|
76
77
|
s.add_dependency(%q<redis>, [">= 0"])
|
77
78
|
s.add_dependency(%q<chronic>, [">= 0"])
|
78
|
-
s.add_dependency(%q<rbtree>, [">= 0"])
|
79
79
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
80
80
|
s.add_dependency(%q<vegas>, [">= 0"])
|
81
81
|
s.add_dependency(%q<activesupport>, [">= 2.3.12"])
|
@@ -88,7 +88,6 @@ Gem::Specification.new do |s|
|
|
88
88
|
else
|
89
89
|
s.add_dependency(%q<redis>, [">= 0"])
|
90
90
|
s.add_dependency(%q<chronic>, [">= 0"])
|
91
|
-
s.add_dependency(%q<rbtree>, [">= 0"])
|
92
91
|
s.add_dependency(%q<sinatra>, [">= 0"])
|
93
92
|
s.add_dependency(%q<vegas>, [">= 0"])
|
94
93
|
s.add_dependency(%q<activesupport>, [">= 2.3.12"])
|
@@ -0,0 +1,12 @@
|
|
1
|
+
location /all_seeing_eye
|
2
|
+
{
|
3
|
+
rewrite /all_seeing_eye/(.*) /$1 break;
|
4
|
+
|
5
|
+
proxy_set_header Host $host:1234;
|
6
|
+
proxy_set_header X-Real-IP $remote_addr;
|
7
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
8
|
+
proxy_set_header X-Forwarded-Ssl on;
|
9
|
+
proxy_set_header X-Forwarded-Proto https;
|
10
|
+
|
11
|
+
proxy_pass http://all_seeing_eye_server:all_seeing_eye_port;
|
12
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
## Timeout
|
2
|
+
# The length of time AllSeeingEye has to complete everything it does. So, at maximum,
|
3
|
+
# AllSeeingEye will add this amount of time to each of your requests.
|
4
|
+
timeout: 0.03
|
5
|
+
|
6
|
+
## Round To Seconds
|
7
|
+
# A data point for every request is too much to display sensibly.
|
8
|
+
# 10 minutes makes more sense here.
|
9
|
+
round_to_seconds: 600
|
10
|
+
|
11
|
+
## Redis
|
12
|
+
# The host and port of the redis server. We use database 7 for AllSeeingEye, so make sure that
|
13
|
+
# redis can accept up to that many databases.
|
14
|
+
redis:
|
15
|
+
development: localhost:6379
|
16
|
+
|
17
|
+
## Define each model you want to track here.
|
18
|
+
# Model names should be the root of the hash, with each attribute following.
|
19
|
+
# Attributes should have a unique name and a method of acquiring them -- specifically,
|
20
|
+
# an object and a method on that object. A couple objects you're probably
|
21
|
+
# interested in:
|
22
|
+
# request: the request object from the controller
|
23
|
+
# response: the response object from the controller
|
24
|
+
# params: the parameter hash
|
25
|
+
# controller: the controller itself ("self")
|
26
|
+
# But anything works. Be careful with what you put here.
|
27
|
+
request:
|
28
|
+
ip:
|
29
|
+
object: request
|
30
|
+
method: .remote_ip
|
31
|
+
uri:
|
32
|
+
object: request
|
33
|
+
method: .request_uri
|
34
|
+
browser:
|
35
|
+
object: request
|
36
|
+
method: .env["HTTP_USER_AGENT"]
|
37
|
+
controller:
|
38
|
+
object: params
|
39
|
+
method: '[:controller]'
|
40
|
+
action:
|
41
|
+
object: params
|
42
|
+
method: '[:action]'
|
43
|
+
status:
|
44
|
+
object: response
|
45
|
+
method: .status
|
data/lib/all_seeing_eye/model.rb
CHANGED
@@ -129,32 +129,6 @@ class AllSeeingEye::Model
|
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
def self.conglomerate(array, options = {})
|
133
|
-
return [] if array.empty?
|
134
|
-
|
135
|
-
options = {:granularity => 100}.merge(options)
|
136
|
-
if !array.first.score.nil?
|
137
|
-
array = array.sort{|a, b| a.score <=> b.score}
|
138
|
-
else
|
139
|
-
array = array.sort{|a, b| a.created_at <=> b.created_at}
|
140
|
-
end
|
141
|
-
start = array.first.created_at.utc.to_i
|
142
|
-
stop = array.last.created_at.utc.to_i
|
143
|
-
interval = (stop - start) / options[:granularity]
|
144
|
-
interval = 1 if interval == 0
|
145
|
-
|
146
|
-
tree = RBTree.new
|
147
|
-
options[:granularity].times {|n| tree[start + (interval * n)] = 0}
|
148
|
-
|
149
|
-
array.each do |o|
|
150
|
-
val = o.created_at.utc.to_i
|
151
|
-
bound = tree.lower_bound(val)
|
152
|
-
bound = tree.upper_bound(val) if bound.nil?
|
153
|
-
tree[bound.first] += 1
|
154
|
-
end
|
155
|
-
tree.to_a
|
156
|
-
end
|
157
|
-
|
158
132
|
def initialize
|
159
133
|
self.class.field_names.each do |key|
|
160
134
|
self.class.send(:attr_accessor, key.to_sym)
|
@@ -167,7 +141,7 @@ class AllSeeingEye::Model
|
|
167
141
|
end
|
168
142
|
|
169
143
|
def save
|
170
|
-
timestamp = (self.created_at.to_i /
|
144
|
+
timestamp = (self.created_at.to_i / AllSeeingEye.configuration[:all_seeing_eye]['round_to_seconds']) * AllSeeingEye.configuration[:all_seeing_eye]['round_to_seconds']
|
171
145
|
|
172
146
|
AllSeeingEye.redis["allseeingeye:#{self.class.model_name}:#{id}"] = Marshal.dump(self)
|
173
147
|
AllSeeingEye.redis.sadd("allseeingeye:#{self.class.model_name}:all", id)
|
@@ -83,13 +83,6 @@ class AllSeeingEye
|
|
83
83
|
redirect url_path("/search/#{CGI::escape(params[:query])}")
|
84
84
|
end
|
85
85
|
|
86
|
-
get %r{/search/(.*?)$} do
|
87
|
-
@field = 'total'
|
88
|
-
@query = params[:captures].first
|
89
|
-
@counts = AllSeeingEye::Request.search(@query, :count => true)
|
90
|
-
show :total
|
91
|
-
end
|
92
|
-
|
93
86
|
get "/fields" do
|
94
87
|
redirect url_path("/fields/#{AllSeeingEye::Request.field_keys.first}")
|
95
88
|
end
|
@@ -104,6 +97,7 @@ class AllSeeingEye
|
|
104
97
|
end
|
105
98
|
|
106
99
|
get %r{/search/(.*?)/#{field}$} do
|
100
|
+
@page = params[:page].blank? ? 1 : params[:page].to_i
|
107
101
|
@field = field
|
108
102
|
@query = params[:captures].first
|
109
103
|
@requests = AllSeeingEye::Request.search(@query)
|
@@ -115,6 +109,7 @@ class AllSeeingEye
|
|
115
109
|
|
116
110
|
(AllSeeingEye::Request.field_keys - [field]).each do |f|
|
117
111
|
get %r{/fields/#{field}/(.*?)/#{f}$} do
|
112
|
+
@page = params[:page].blank? ? 1 : params[:page].to_i
|
118
113
|
@field = field
|
119
114
|
@id = params[:captures].first
|
120
115
|
@view = f
|
@@ -133,6 +128,13 @@ class AllSeeingEye
|
|
133
128
|
show :total
|
134
129
|
end
|
135
130
|
end
|
131
|
+
|
132
|
+
get %r{/search/(.*?)$} do
|
133
|
+
@field = 'total'
|
134
|
+
@query = params[:captures].first
|
135
|
+
@counts = AllSeeingEye::Request.search(@query, :count => true)
|
136
|
+
show :total
|
137
|
+
end
|
136
138
|
|
137
139
|
def tabs
|
138
140
|
@tabs ||= AllSeeingEye::Request.field_keys
|
data/lib/all_seeing_eye.rb
CHANGED
@@ -6,7 +6,11 @@ class AllSeeingEye
|
|
6
6
|
def self.configuration
|
7
7
|
location = ENV['ALL_SEEING_EYE_CONFIG'] || 'config'
|
8
8
|
@@configuration ||= Hash.new
|
9
|
+
@@configuration[:all_seeing_eye] ||= YAML::load_file("./#{location}/all_seeing_eye.yml")
|
9
10
|
@@configuration[:redis] ||=
|
11
|
+
if @@configuration[:all_seeing_eye]['redis'] && @@configuration[:all_seeing_eye]['redis'][AllSeeingEye.environment]
|
12
|
+
@@configuration[:all_seeing_eye]['redis'][AllSeeingEye.environment]
|
13
|
+
else
|
10
14
|
begin
|
11
15
|
YAML::load_file("./#{location}/resque.yml")[AllSeeingEye.environment]
|
12
16
|
rescue
|
@@ -16,23 +20,37 @@ class AllSeeingEye
|
|
16
20
|
'localhost:6379'
|
17
21
|
end
|
18
22
|
end
|
19
|
-
|
23
|
+
end
|
24
|
+
@@configuration[:models] ||= []
|
25
|
+
@@configuration[:all_seeing_eye].each do |key, value|
|
26
|
+
next if self.default_keys.include?(key) || AllSeeingEye.const_defined?(key.capitalize.to_sym)
|
27
|
+
klass = Class.new(AllSeeingEye::Model)
|
28
|
+
AllSeeingEye.const_set(key.capitalize.to_sym, klass)
|
29
|
+
@@configuration[:models] << klass
|
30
|
+
end
|
20
31
|
@@configuration
|
21
32
|
end
|
22
33
|
|
34
|
+
def self.default_keys
|
35
|
+
['timeout', 'round_to_seconds', 'redis']
|
36
|
+
end
|
37
|
+
|
23
38
|
def self.redis
|
24
39
|
@@redis ||= Redis.new(:host => AllSeeingEye.configuration[:redis].split(':').first,
|
25
40
|
:port => AllSeeingEye.configuration[:redis].split(':').last,
|
26
41
|
:db => 7)
|
27
42
|
end
|
43
|
+
|
44
|
+
require 'redis'
|
45
|
+
require 'yaml'
|
46
|
+
require 'chronic'
|
47
|
+
require 'active_support'
|
48
|
+
require 'active_support/all'
|
49
|
+
require 'all_seeing_eye/model'
|
50
|
+
if defined?(Rails)
|
51
|
+
require 'all_seeing_eye/integrations/rails2'
|
52
|
+
require 'all_seeing_eye/generators/all_seeing_eye_generator'
|
53
|
+
end
|
54
|
+
|
55
|
+
self.configuration
|
28
56
|
end
|
29
|
-
|
30
|
-
require 'redis'
|
31
|
-
require 'yaml'
|
32
|
-
require 'chronic'
|
33
|
-
require 'rbtree'
|
34
|
-
require 'active_support'
|
35
|
-
require 'active_support/all'
|
36
|
-
require 'all_seeing_eye/model'
|
37
|
-
require 'all_seeing_eye/models/request'
|
38
|
-
require 'all_seeing_eye/integrations/rails2' if defined?(Rails)
|
data/test/base_test.rb
CHANGED
@@ -6,10 +6,23 @@ context 'with the base class' do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
test 'load the configuration' do
|
9
|
-
assert AllSeeingEye.configuration[:all_seeing_eye]['
|
9
|
+
assert AllSeeingEye.configuration[:all_seeing_eye]['request']
|
10
|
+
assert !AllSeeingEye.configuration[:models].empty?
|
11
|
+
assert AllSeeingEye.configuration[:redis]
|
10
12
|
end
|
11
13
|
|
12
14
|
test 'connect to Redis' do
|
13
15
|
assert_equal '1', AllSeeingEye.redis.info["connected_clients"]
|
14
16
|
end
|
17
|
+
|
18
|
+
test 'loads new classes from YML file' do
|
19
|
+
assert AllSeeingEye.const_defined?(:Request)
|
20
|
+
assert AllSeeingEye.const_defined?(:Response)
|
21
|
+
assert AllSeeingEye.configuration[:models].include?(AllSeeingEye::Request)
|
22
|
+
assert AllSeeingEye.configuration[:models].include?(AllSeeingEye::Response)
|
23
|
+
end
|
24
|
+
|
25
|
+
test 'do not load default keys as classes' do
|
26
|
+
assert !AllSeeingEye.const_defined?(:Timeout)
|
27
|
+
end
|
15
28
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
timeout: 0.01
|
2
|
-
|
2
|
+
round_to_seconds: 60
|
3
|
+
request:
|
3
4
|
ip:
|
4
5
|
object: request
|
5
6
|
method: .remote_ip
|
@@ -12,10 +13,16 @@ model:
|
|
12
13
|
controller:
|
13
14
|
object: params
|
14
15
|
method: '[:controller]'
|
15
|
-
params:
|
16
16
|
action:
|
17
17
|
object: params
|
18
18
|
method: '[:action]'
|
19
19
|
status:
|
20
20
|
object: response
|
21
21
|
method: .status
|
22
|
+
response:
|
23
|
+
ip:
|
24
|
+
object: request
|
25
|
+
method: .remote_ip
|
26
|
+
uri:
|
27
|
+
object: request
|
28
|
+
method: .request_uri
|
data/test/model_test.rb
CHANGED
@@ -6,27 +6,27 @@ context 'class methods without setup' do
|
|
6
6
|
end
|
7
7
|
|
8
8
|
test 'models know their own name' do
|
9
|
-
assert_equal '
|
9
|
+
assert_equal 'request', AllSeeingEye::Request.model_name
|
10
10
|
end
|
11
11
|
|
12
12
|
test 'models correctly find their next ID' do
|
13
|
-
id = AllSeeingEye::
|
14
|
-
(id + 1..(id + 11)).each {|n|assert_equal AllSeeingEye::
|
13
|
+
id = AllSeeingEye::Request.next_id
|
14
|
+
(id + 1..(id + 11)).each {|n|assert_equal AllSeeingEye::Request.next_id, n}
|
15
15
|
end
|
16
16
|
|
17
17
|
test 'models should get fields' do
|
18
|
-
assert_equal AllSeeingEye::
|
19
|
-
{"uri"=>{"method"=>".request_uri", "object"=>"request"}, "action"=>{"method"=>"[:action]", "object"=>"params"}, "ip"=>{"method"=>".remote_ip", "object"=>"request"}, "controller"=>{"method"=>"[:controller]", "
|
18
|
+
assert_equal AllSeeingEye::Request.fields,
|
19
|
+
{"uri"=>{"method"=>".request_uri", "object"=>"request"}, "action"=>{"method"=>"[:action]", "object"=>"params"}, "ip"=>{"method"=>".remote_ip", "object"=>"request"}, "controller"=>{"method"=>"[:controller]", "object"=>"params"}, "browser"=>{"method"=>".env[\"HTTP_USER_AGENT\"]", "object"=>"request"}, "status"=>{"method"=>".status", "object"=>"response"}}
|
20
20
|
end
|
21
21
|
|
22
22
|
test 'models should get field names' do
|
23
23
|
assert_equal ["uri", "action", "ip", "controller", "browser", "status", "time_spent", "created_at"],
|
24
|
-
AllSeeingEye::
|
24
|
+
AllSeeingEye::Request.field_names
|
25
25
|
end
|
26
26
|
|
27
27
|
test 'return a new model object' do
|
28
28
|
time = Time.now
|
29
|
-
obj = AllSeeingEye::
|
29
|
+
obj = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => time)
|
30
30
|
|
31
31
|
assert_equal '/test/', obj.uri
|
32
32
|
assert_equal '127.0.0.1', obj.ip
|
@@ -35,22 +35,22 @@ context 'class methods without setup' do
|
|
35
35
|
end
|
36
36
|
|
37
37
|
test 'create a model object' do
|
38
|
-
obj = AllSeeingEye::
|
38
|
+
obj = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1')
|
39
39
|
|
40
40
|
assert_equal '/test/', obj.uri
|
41
41
|
assert_equal '127.0.0.1', obj.ip
|
42
|
-
assert_equal Marshal.dump(obj), AllSeeingEye.redis["allseeingeye:
|
43
|
-
assert_equal '1', AllSeeingEye.redis.zscore("allseeingeye:
|
44
|
-
assert_equal '1', AllSeeingEye.redis.zscore("allseeingeye:
|
45
|
-
assert_equal [obj.id.to_s], AllSeeingEye.redis.sort("allseeingeye:
|
46
|
-
assert_equal [obj.id.to_s], AllSeeingEye.redis.sort("allseeingeye:
|
42
|
+
assert_equal Marshal.dump(obj), AllSeeingEye.redis["allseeingeye:request:#{AllSeeingEye::Request.next_id - 1}"]
|
43
|
+
assert_equal '1', AllSeeingEye.redis.zscore("allseeingeye:request:fields:uri", '/test/')
|
44
|
+
assert_equal '1', AllSeeingEye.redis.zscore("allseeingeye:request:fields:ip", '127.0.0.1')
|
45
|
+
assert_equal [obj.id.to_s], AllSeeingEye.redis.sort("allseeingeye:request:fields:uri:/test/", :by => 'nosort')
|
46
|
+
assert_equal [obj.id.to_s], AllSeeingEye.redis.sort("allseeingeye:request:fields:ip:127.0.0.1", :by => 'nosort')
|
47
47
|
end
|
48
48
|
|
49
49
|
test 'unmarshal an object with load' do
|
50
50
|
time = Time.now
|
51
|
-
raw = AllSeeingEye::
|
51
|
+
raw = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => time)
|
52
52
|
dump = Marshal.dump(raw)
|
53
|
-
obj = AllSeeingEye::
|
53
|
+
obj = AllSeeingEye::Request.load(dump)
|
54
54
|
|
55
55
|
assert_equal '/test/', obj.uri
|
56
56
|
assert_equal '127.0.0.1', obj.ip
|
@@ -60,26 +60,26 @@ context 'class methods without setup' do
|
|
60
60
|
|
61
61
|
test 'find an object by its ID' do
|
62
62
|
time = Time.now
|
63
|
-
obj = AllSeeingEye::
|
64
|
-
found = AllSeeingEye::
|
63
|
+
obj = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => time)
|
64
|
+
found = AllSeeingEye::Request.find(obj.id)
|
65
65
|
|
66
66
|
[:uri, :ip, :created_at].each {|f| assert_equal obj.send(f), found.send(f)}
|
67
67
|
end
|
68
68
|
|
69
69
|
test 'find all objects' do
|
70
|
-
obj1 = AllSeeingEye::
|
71
|
-
obj2 = AllSeeingEye::
|
72
|
-
obj3 = AllSeeingEye::
|
70
|
+
obj1 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => Time.now)
|
71
|
+
obj2 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => Time.now)
|
72
|
+
obj3 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => Time.now)
|
73
73
|
|
74
|
-
assert_equal [obj1.id, obj2.id, obj3.id], AllSeeingEye::
|
74
|
+
assert_equal [obj1.id, obj2.id, obj3.id], AllSeeingEye::Request.all.collect(&:id)
|
75
75
|
end
|
76
76
|
|
77
77
|
test 'find the count of all objects' do
|
78
|
-
obj1 = AllSeeingEye::
|
79
|
-
obj2 = AllSeeingEye::
|
80
|
-
obj3 = AllSeeingEye::
|
78
|
+
obj1 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => Time.now)
|
79
|
+
obj2 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => Time.now)
|
80
|
+
obj3 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => Time.now)
|
81
81
|
|
82
|
-
assert_equal 3, AllSeeingEye::
|
82
|
+
assert_equal 3, AllSeeingEye::Request.count
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -87,12 +87,12 @@ context 'class methods with setup' do
|
|
87
87
|
setup do
|
88
88
|
@time = Time.now
|
89
89
|
|
90
|
-
@obj1 = AllSeeingEye::
|
91
|
-
@obj2 = AllSeeingEye::
|
92
|
-
@obj3 = AllSeeingEye::
|
93
|
-
@obj4 = AllSeeingEye::
|
94
|
-
@obj5 = AllSeeingEye::
|
95
|
-
@obj6 = AllSeeingEye::
|
90
|
+
@obj1 = AllSeeingEye::Request.create(:uri => '/', :ip => '127.0.0.1', :created_at => @time - 10 * 60)
|
91
|
+
@obj2 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => @time - 5 * 60)
|
92
|
+
@obj3 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => @time - 3 * 60)
|
93
|
+
@obj4 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '192.168.0.1', :created_at => @time - 1 * 60)
|
94
|
+
@obj5 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '127.0.0.1', :created_at => @time + 2 * 60)
|
95
|
+
@obj6 = AllSeeingEye::Request.create(:uri => '/test/', :ip => '192.168.0.1', :created_at => @time + 2 * 60)
|
96
96
|
end
|
97
97
|
|
98
98
|
teardown do
|
@@ -100,7 +100,7 @@ context 'class methods with setup' do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
test 'find all objects in a date range with a start and a stop' do
|
103
|
-
results = AllSeeingEye::
|
103
|
+
results = AllSeeingEye::Request.all(:start => @time - 11 * 60, :stop => @time - 4 * 60)
|
104
104
|
|
105
105
|
assert_equal 2, results.count
|
106
106
|
assert_equal @obj1.id, results[0].id
|
@@ -108,7 +108,7 @@ context 'class methods with setup' do
|
|
108
108
|
end
|
109
109
|
|
110
110
|
test 'find all objects in a date range with only a start' do
|
111
|
-
results = AllSeeingEye::
|
111
|
+
results = AllSeeingEye::Request.all(:start => @time)
|
112
112
|
|
113
113
|
assert_equal 2, results.count
|
114
114
|
assert_equal @obj5.id, results[0].id
|
@@ -116,7 +116,7 @@ context 'class methods with setup' do
|
|
116
116
|
end
|
117
117
|
|
118
118
|
test 'find all objects in a date range with only a stop' do
|
119
|
-
results = AllSeeingEye::
|
119
|
+
results = AllSeeingEye::Request.all(:stop => @time)
|
120
120
|
|
121
121
|
assert_equal 4, results.count
|
122
122
|
assert_equal @obj1.id, results[0].id
|
@@ -126,7 +126,7 @@ context 'class methods with setup' do
|
|
126
126
|
end
|
127
127
|
|
128
128
|
test 'find model objects by a string field' do
|
129
|
-
results = AllSeeingEye::
|
129
|
+
results = AllSeeingEye::Request.find_by_field('uri', :value => '/test/')
|
130
130
|
|
131
131
|
assert_equal 5, results.count
|
132
132
|
assert results.collect(&:id).include?(@obj2.id)
|
@@ -137,7 +137,7 @@ context 'class methods with setup' do
|
|
137
137
|
end
|
138
138
|
|
139
139
|
test 'find model objects by a string field with a start' do
|
140
|
-
results = AllSeeingEye::
|
140
|
+
results = AllSeeingEye::Request.find_by_field('uri', :value => '/test/', :start => @time - 4 * 60)
|
141
141
|
|
142
142
|
assert_equal 4, results.count
|
143
143
|
assert results.collect(&:id).include?(@obj3.id)
|
@@ -147,7 +147,7 @@ context 'class methods with setup' do
|
|
147
147
|
end
|
148
148
|
|
149
149
|
test 'find model objects by a string field with a stop' do
|
150
|
-
results = AllSeeingEye::
|
150
|
+
results = AllSeeingEye::Request.find_by_field('uri', :value => '/test/', :stop => @time)
|
151
151
|
|
152
152
|
assert_equal 3, results.count
|
153
153
|
assert results.collect(&:id).include?(@obj2.id)
|
@@ -156,7 +156,7 @@ context 'class methods with setup' do
|
|
156
156
|
end
|
157
157
|
|
158
158
|
test 'find model objects by a string field with a start and a stop' do
|
159
|
-
results = AllSeeingEye::
|
159
|
+
results = AllSeeingEye::Request.find_by_field('uri', :value => '/test/', :start => @time - 4 * 60, :stop => @time)
|
160
160
|
|
161
161
|
assert_equal 2, results.count
|
162
162
|
assert results.collect(&:id).include?(@obj3.id)
|
@@ -168,7 +168,7 @@ context 'class methods with setup' do
|
|
168
168
|
end
|
169
169
|
|
170
170
|
test 'find model objects by a date field' do
|
171
|
-
results = AllSeeingEye::
|
171
|
+
results = AllSeeingEye::Request.find_by_field('created_at', :start => @obj1.created_at, :stop => @obj4.created_at)
|
172
172
|
|
173
173
|
assert_equal 4, results.count
|
174
174
|
assert_equal results.first.id, @obj1.id
|
@@ -176,19 +176,19 @@ context 'class methods with setup' do
|
|
176
176
|
end
|
177
177
|
|
178
178
|
test 'count model objects' do
|
179
|
-
assert_equal 6, AllSeeingEye::
|
179
|
+
assert_equal 6, AllSeeingEye::Request.count
|
180
180
|
end
|
181
181
|
|
182
182
|
test 'return the first object' do
|
183
|
-
assert_equal @obj1.id, AllSeeingEye::
|
183
|
+
assert_equal @obj1.id, AllSeeingEye::Request.first.id
|
184
184
|
end
|
185
185
|
|
186
186
|
test 'return the last object' do
|
187
|
-
assert_equal @obj6.id, AllSeeingEye::
|
187
|
+
assert_equal @obj6.id, AllSeeingEye::Request.last.id
|
188
188
|
end
|
189
189
|
|
190
190
|
test 'return count in a field' do
|
191
|
-
counts = AllSeeingEye::
|
191
|
+
counts = AllSeeingEye::Request.list_by_field('uri')
|
192
192
|
|
193
193
|
assert_equal '/test/', counts.first.first
|
194
194
|
assert_equal 5, counts.first.last
|
@@ -197,7 +197,7 @@ context 'class methods with setup' do
|
|
197
197
|
end
|
198
198
|
|
199
199
|
test 'search with Chronic' do
|
200
|
-
results = AllSeeingEye::
|
200
|
+
results = AllSeeingEye::Request.search('last friday to five minutes ago')
|
201
201
|
|
202
202
|
assert_equal 2, results.size
|
203
203
|
assert_equal @obj1.id, results[0].id
|
@@ -205,7 +205,7 @@ context 'class methods with setup' do
|
|
205
205
|
end
|
206
206
|
|
207
207
|
test 'search by a specific field' do
|
208
|
-
results = AllSeeingEye::
|
208
|
+
results = AllSeeingEye::Request.search('uri:/test/')
|
209
209
|
|
210
210
|
assert_equal 5, results.count
|
211
211
|
assert results.collect(&:id).include?(@obj2.id)
|
@@ -216,7 +216,7 @@ context 'class methods with setup' do
|
|
216
216
|
end
|
217
217
|
|
218
218
|
test 'search for a count on a specific field' do
|
219
|
-
results = AllSeeingEye::
|
219
|
+
results = AllSeeingEye::Request.search('uri:/test/', :count => true)
|
220
220
|
|
221
221
|
assert_equal 4, results.count
|
222
222
|
assert_equal results.last, [((@obj6.created_at.to_i / 60) * 60).to_s, 2]
|
@@ -229,36 +229,27 @@ context 'many objects' do
|
|
229
229
|
@time = Time.now
|
230
230
|
|
231
231
|
2000.times do |n|
|
232
|
-
instance_variable_set("@obj#{n}".to_sym, AllSeeingEye::
|
232
|
+
instance_variable_set("@obj#{n}".to_sym, AllSeeingEye::Request.create(:uri => '/', :ip => n % 2 == 0 ? '127.0.0.1' : '192.168.0.1', :created_at => @time - (n * (1999 - n)) * 60))
|
233
233
|
end
|
234
234
|
end
|
235
|
-
|
236
|
-
test 'conglomerate an array successfully' do
|
237
|
-
results = AllSeeingEye::Model.all
|
238
|
-
counts = AllSeeingEye::Model.conglomerate(results)
|
239
235
|
|
240
|
-
assert_equal 100, counts.count
|
241
|
-
assert_equal 2000, counts.inject(0) {|sum, k| sum + k.last}
|
242
|
-
assert_equal @obj999.created_at.to_i, counts.first.first
|
243
|
-
end
|
244
|
-
|
245
236
|
test 'get the created count' do
|
246
|
-
counts = AllSeeingEye::
|
237
|
+
counts = AllSeeingEye::Request.list_by_field('created_at')
|
247
238
|
|
248
|
-
assert_equal counts, AllSeeingEye::
|
239
|
+
assert_equal counts, AllSeeingEye::Request.search('ten years ago to one year from now', :count => true)
|
249
240
|
assert_equal (@obj999.created_at.to_i / 60) * 60, counts.first.first.to_i
|
250
241
|
assert_equal (@obj0.created_at.to_i / 60) * 60, counts.last.first.to_i
|
251
242
|
assert_equal 2000, counts.inject(0) {|sum, k| sum + k.last}
|
252
243
|
end
|
253
244
|
|
254
245
|
test 'get the created count for a value' do
|
255
|
-
counts = AllSeeingEye::
|
246
|
+
counts = AllSeeingEye::Request.list_by_field('ip', :value => '192.168.0.1')
|
256
247
|
|
257
248
|
assert_equal 1000, counts.inject(0) {|sum, k| sum + k.last}
|
258
249
|
end
|
259
250
|
|
260
251
|
test 'get only the first page of the count' do
|
261
|
-
counts = AllSeeingEye::
|
252
|
+
counts = AllSeeingEye::Request.list_by_field('created_at', :page => 1)
|
262
253
|
|
263
254
|
assert_equal 10, counts.size
|
264
255
|
assert_equal (@obj999.created_at.to_i / 60) * 60, counts.first.first.to_i
|
@@ -266,7 +257,7 @@ context 'many objects' do
|
|
266
257
|
end
|
267
258
|
|
268
259
|
test 'get only the second page of the count' do
|
269
|
-
counts = AllSeeingEye::
|
260
|
+
counts = AllSeeingEye::Request.list_by_field('created_at', :page => 2)
|
270
261
|
|
271
262
|
assert_equal 10, counts.size
|
272
263
|
assert_equal (@obj989.created_at.to_i / 60) * 60, counts.first.first.to_i
|
@@ -274,13 +265,13 @@ context 'many objects' do
|
|
274
265
|
end
|
275
266
|
|
276
267
|
test 'get only the first page of the count with a value' do
|
277
|
-
counts = AllSeeingEye::
|
268
|
+
counts = AllSeeingEye::Request.list_by_field('ip', :value => '192.168.0.1', :page => 1)
|
278
269
|
|
279
270
|
assert_equal 10, counts.size
|
280
271
|
end
|
281
272
|
|
282
273
|
test 'return the count for a field with a given value' do
|
283
|
-
assert_equal 1000, AllSeeingEye::
|
274
|
+
assert_equal 1000, AllSeeingEye::Request.count_by_field('ip', :value => '192.168.0.1')
|
284
275
|
end
|
285
276
|
end
|
286
277
|
|
@@ -290,13 +281,13 @@ context 'instance methods' do
|
|
290
281
|
end
|
291
282
|
|
292
283
|
test 'assign all attr_accessors from fields at initialization' do
|
293
|
-
obj = AllSeeingEye::
|
284
|
+
obj = AllSeeingEye::Request.new
|
294
285
|
|
295
|
-
AllSeeingEye::
|
286
|
+
AllSeeingEye::Request.field_names.each {|f| assert obj.respond_to?(f.to_sym); assert obj.respond_to?("#{f}=".to_sym)}
|
296
287
|
end
|
297
288
|
|
298
289
|
test 'assign an object an ID if it does not have one' do
|
299
|
-
obj = AllSeeingEye::
|
290
|
+
obj = AllSeeingEye::Request.new
|
300
291
|
|
301
292
|
assert_equal nil, obj.instance_variable_get(:@id)
|
302
293
|
assert_equal 1, obj.id
|
@@ -304,44 +295,44 @@ context 'instance methods' do
|
|
304
295
|
end
|
305
296
|
|
306
297
|
test 'save a new model object' do
|
307
|
-
obj = AllSeeingEye::
|
298
|
+
obj = AllSeeingEye::Request.new(:uri => '/test/', :ip => '127.0.0.1')
|
308
299
|
|
309
300
|
assert obj.save
|
310
301
|
assert_equal '/test/', obj.uri
|
311
302
|
assert_equal '127.0.0.1', obj.ip
|
312
|
-
assert_equal Marshal.dump(obj), AllSeeingEye.redis["allseeingeye:
|
313
|
-
assert_equal '1', AllSeeingEye.redis.zscore("allseeingeye:
|
314
|
-
assert_equal '1', AllSeeingEye.redis.zscore("allseeingeye:
|
315
|
-
assert_equal [obj.id.to_s], AllSeeingEye.redis.sort("allseeingeye:
|
303
|
+
assert_equal Marshal.dump(obj), AllSeeingEye.redis["allseeingeye:request:#{AllSeeingEye::Request.next_id - 1}"]
|
304
|
+
assert_equal '1', AllSeeingEye.redis.zscore("allseeingeye:request:fields:uri", '/test/')
|
305
|
+
assert_equal '1', AllSeeingEye.redis.zscore("allseeingeye:request:fields:ip", '127.0.0.1')
|
306
|
+
assert_equal [obj.id.to_s], AllSeeingEye.redis.sort("allseeingeye:request:fields:uri:/test/", :by => 'nosort')
|
316
307
|
end
|
317
308
|
|
318
309
|
test 'save a new model object with date attributes' do
|
319
310
|
time = Time.now
|
320
|
-
obj = AllSeeingEye::
|
311
|
+
obj = AllSeeingEye::Request.new(:created_at => time)
|
321
312
|
|
322
313
|
assert obj.save
|
323
314
|
assert_equal time, obj.created_at
|
324
|
-
assert_equal Marshal.dump(obj), AllSeeingEye.redis["allseeingeye:
|
325
|
-
assert_equal time.to_i.to_s, AllSeeingEye.redis.zscore("allseeingeye:
|
315
|
+
assert_equal Marshal.dump(obj), AllSeeingEye.redis["allseeingeye:request:#{AllSeeingEye::Request.next_id - 1}"]
|
316
|
+
assert_equal time.to_i.to_s, AllSeeingEye.redis.zscore("allseeingeye:request:fields:created_at", obj.id)
|
326
317
|
end
|
327
318
|
|
328
319
|
test 'ignore empty and nil attributes in model object creation' do
|
329
320
|
time = Time.now
|
330
|
-
obj = AllSeeingEye::
|
321
|
+
obj = AllSeeingEye::Request.new(:created_at => time, :uri => '/test/', :ip => nil, :action => '')
|
331
322
|
|
332
323
|
assert obj.save
|
333
324
|
assert_equal time, obj.created_at
|
334
325
|
assert_equal '/test/', obj.uri
|
335
326
|
assert_equal nil, obj.ip
|
336
327
|
assert_equal '', obj.action
|
337
|
-
assert_equal Marshal.dump(obj), AllSeeingEye.redis["allseeingeye:
|
338
|
-
assert_equal time.to_i.to_s, AllSeeingEye.redis.zscore("allseeingeye:
|
339
|
-
assert_equal '1', AllSeeingEye.redis.zscore("allseeingeye:
|
340
|
-
assert_equal nil, AllSeeingEye.redis.zscore("allseeingeye:
|
341
|
-
assert_equal nil, AllSeeingEye.redis.zscore("allseeingeye:
|
342
|
-
assert_equal [obj.id.to_s], AllSeeingEye.redis.sort("allseeingeye:
|
343
|
-
assert_equal [], AllSeeingEye.redis.sort("allseeingeye:
|
344
|
-
assert_equal [], AllSeeingEye.redis.sort("allseeingeye:
|
328
|
+
assert_equal Marshal.dump(obj), AllSeeingEye.redis["allseeingeye:request:#{AllSeeingEye::Request.next_id - 1}"]
|
329
|
+
assert_equal time.to_i.to_s, AllSeeingEye.redis.zscore("allseeingeye:request:fields:created_at", obj.id)
|
330
|
+
assert_equal '1', AllSeeingEye.redis.zscore("allseeingeye:request:fields:uri", '/test/')
|
331
|
+
assert_equal nil, AllSeeingEye.redis.zscore("allseeingeye:request:fields:ip", nil)
|
332
|
+
assert_equal nil, AllSeeingEye.redis.zscore("allseeingeye:request:fields:action", '')
|
333
|
+
assert_equal [obj.id.to_s], AllSeeingEye.redis.sort("allseeingeye:request:fields:uri:/test/", :by => 'nosort')
|
334
|
+
assert_equal [], AllSeeingEye.redis.sort("allseeingeye:request:fields:ip:", :by => 'nosort')
|
335
|
+
assert_equal [], AllSeeingEye.redis.sort("allseeingeye:request:fields:action:", :by => 'nosort')
|
345
336
|
end
|
346
337
|
|
347
338
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
|
3
|
+
ENV['ALL_SEEING_EYE_ENV'] = 'test'
|
4
|
+
ENV['ALL_SEEING_EYE_CONFIG'] = 'test/fixtures'
|
3
5
|
dir = File.dirname(File.expand_path(__FILE__))
|
4
6
|
$LOAD_PATH.unshift dir + '/../lib'
|
5
7
|
require 'test/unit'
|
6
8
|
require 'yaml'
|
7
9
|
require 'all_seeing_eye'
|
8
|
-
ENV['ALL_SEEING_EYE_ENV'] = 'test'
|
9
|
-
ENV['ALL_SEEING_EYE_CONFIG'] = 'test/fixtures'
|
10
10
|
|
11
11
|
if !system("which redis-server")
|
12
12
|
puts '', "** can't find `redis-server` in your path"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: all_seeing_eye
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 55
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 20
|
10
|
+
version: 0.0.20
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Josh Symonds
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-08-
|
18
|
+
date: 2011-08-16 00:00:00 -05:00
|
19
19
|
default_executable: all-seeing-eye
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -57,7 +57,7 @@ dependencies:
|
|
57
57
|
segments:
|
58
58
|
- 0
|
59
59
|
version: "0"
|
60
|
-
name:
|
60
|
+
name: sinatra
|
61
61
|
version_requirements: *id003
|
62
62
|
prerelease: false
|
63
63
|
- !ruby/object:Gem::Dependency
|
@@ -71,26 +71,12 @@ dependencies:
|
|
71
71
|
segments:
|
72
72
|
- 0
|
73
73
|
version: "0"
|
74
|
-
name:
|
74
|
+
name: vegas
|
75
75
|
version_requirements: *id004
|
76
76
|
prerelease: false
|
77
77
|
- !ruby/object:Gem::Dependency
|
78
78
|
type: :runtime
|
79
79
|
requirement: &id005 !ruby/object:Gem::Requirement
|
80
|
-
none: false
|
81
|
-
requirements:
|
82
|
-
- - ">="
|
83
|
-
- !ruby/object:Gem::Version
|
84
|
-
hash: 3
|
85
|
-
segments:
|
86
|
-
- 0
|
87
|
-
version: "0"
|
88
|
-
name: vegas
|
89
|
-
version_requirements: *id005
|
90
|
-
prerelease: false
|
91
|
-
- !ruby/object:Gem::Dependency
|
92
|
-
type: :runtime
|
93
|
-
requirement: &id006 !ruby/object:Gem::Requirement
|
94
80
|
none: false
|
95
81
|
requirements:
|
96
82
|
- - ">="
|
@@ -102,11 +88,11 @@ dependencies:
|
|
102
88
|
- 12
|
103
89
|
version: 2.3.12
|
104
90
|
name: activesupport
|
105
|
-
version_requirements: *
|
91
|
+
version_requirements: *id005
|
106
92
|
prerelease: false
|
107
93
|
- !ruby/object:Gem::Dependency
|
108
94
|
type: :runtime
|
109
|
-
requirement: &
|
95
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
110
96
|
none: false
|
111
97
|
requirements:
|
112
98
|
- - ">="
|
@@ -116,11 +102,11 @@ dependencies:
|
|
116
102
|
- 0
|
117
103
|
version: "0"
|
118
104
|
name: i18n
|
119
|
-
version_requirements: *
|
105
|
+
version_requirements: *id006
|
120
106
|
prerelease: false
|
121
107
|
- !ruby/object:Gem::Dependency
|
122
108
|
type: :runtime
|
123
|
-
requirement: &
|
109
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
124
110
|
none: false
|
125
111
|
requirements:
|
126
112
|
- - ">="
|
@@ -130,11 +116,11 @@ dependencies:
|
|
130
116
|
- 0
|
131
117
|
version: "0"
|
132
118
|
name: thin
|
133
|
-
version_requirements: *
|
119
|
+
version_requirements: *id007
|
134
120
|
prerelease: false
|
135
121
|
- !ruby/object:Gem::Dependency
|
136
122
|
type: :development
|
137
|
-
requirement: &
|
123
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
138
124
|
none: false
|
139
125
|
requirements:
|
140
126
|
- - ~>
|
@@ -146,11 +132,11 @@ dependencies:
|
|
146
132
|
- 0
|
147
133
|
version: 1.0.0
|
148
134
|
name: bundler
|
149
|
-
version_requirements: *
|
135
|
+
version_requirements: *id008
|
150
136
|
prerelease: false
|
151
137
|
- !ruby/object:Gem::Dependency
|
152
138
|
type: :development
|
153
|
-
requirement: &
|
139
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
154
140
|
none: false
|
155
141
|
requirements:
|
156
142
|
- - ~>
|
@@ -162,11 +148,11 @@ dependencies:
|
|
162
148
|
- 4
|
163
149
|
version: 1.6.4
|
164
150
|
name: jeweler
|
165
|
-
version_requirements: *
|
151
|
+
version_requirements: *id009
|
166
152
|
prerelease: false
|
167
153
|
- !ruby/object:Gem::Dependency
|
168
154
|
type: :development
|
169
|
-
requirement: &
|
155
|
+
requirement: &id010 !ruby/object:Gem::Requirement
|
170
156
|
none: false
|
171
157
|
requirements:
|
172
158
|
- - ">="
|
@@ -176,7 +162,7 @@ dependencies:
|
|
176
162
|
- 0
|
177
163
|
version: "0"
|
178
164
|
name: rcov
|
179
|
-
version_requirements: *
|
165
|
+
version_requirements: *id010
|
180
166
|
prerelease: false
|
181
167
|
description: AllSeeingEye observes all requests, with parameters that you specify, to Redis. Then it composes them into graphs for you to see.
|
182
168
|
email: veraticus@gmail.com
|
@@ -186,21 +172,23 @@ extensions: []
|
|
186
172
|
|
187
173
|
extra_rdoc_files:
|
188
174
|
- LICENSE.txt
|
189
|
-
- README.
|
175
|
+
- README.markdown
|
190
176
|
files:
|
191
177
|
- Gemfile
|
192
178
|
- Gemfile.lock
|
193
179
|
- LICENSE.txt
|
194
|
-
- README.
|
180
|
+
- README.markdown
|
195
181
|
- Rakefile
|
196
182
|
- VERSION
|
197
183
|
- all_seeing_eye.gemspec
|
198
184
|
- bin/all-seeing-eye
|
185
|
+
- examples/all_seeing_eye-nginx.conf
|
199
186
|
- init.rb
|
200
187
|
- lib/all_seeing_eye.rb
|
188
|
+
- lib/all_seeing_eye/generators/all_seeing_eye.yml
|
189
|
+
- lib/all_seeing_eye/generators/all_seeing_eye_generator.rb
|
201
190
|
- lib/all_seeing_eye/integrations/rails2.rb
|
202
191
|
- lib/all_seeing_eye/model.rb
|
203
|
-
- lib/all_seeing_eye/models/request.rb
|
204
192
|
- lib/all_seeing_eye/server.rb
|
205
193
|
- lib/all_seeing_eye/server/public/application.js
|
206
194
|
- lib/all_seeing_eye/server/public/eye.png
|
data/README.rdoc
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
= all_seeing_eye
|
2
|
-
|
3
|
-
A highly configurable Gem that lets you view requests as they occur, backed by Redis.
|
4
|
-
|
5
|
-
== Contributing to all_seeing_eye
|
6
|
-
|
7
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
8
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
9
|
-
* Fork the project
|
10
|
-
* Start a feature/bugfix branch
|
11
|
-
* Commit and push until you are happy with your contribution
|
12
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2011 Josh Symonds. See LICENSE.txt for
|
18
|
-
further details.
|
19
|
-
|