little_brother 0.0.2
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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +96 -0
- data/Rakefile +2 -0
- data/db/migrate/create_watchers.rb +19 -0
- data/lib/generators/little_brother_setup/little_brother_setup_generator.rb +24 -0
- data/lib/little_brother/record.rb +19 -0
- data/lib/little_brother/statistics.rb +42 -0
- data/lib/little_brother/utils.rb +22 -0
- data/lib/little_brother/version.rb +3 -0
- data/lib/little_brother/watcher.rb +9 -0
- data/lib/little_brother.rb +7 -0
- data/little_brother.gemspec +23 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/watcher_spec.rb +12 -0
- metadata +128 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Roger
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# LittleBrother
|
2
|
+
|
3
|
+
Tracks and stores every action (controler:action pair) passed through the controller.
|
4
|
+
|
5
|
+
The gem also supports user oriented tracking for more detailed/focus analysis.
|
6
|
+
|
7
|
+
Disclaimer: Little Brother this IS NOT Big Brother. :)
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'little_brother'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install little_brother
|
22
|
+
|
23
|
+
Run the generation
|
24
|
+
|
25
|
+
$ rails generation little_brother_setup
|
26
|
+
|
27
|
+
This will create the migration`timestamp_create_watchers.rb` so you can create the table `watchers`
|
28
|
+
Run the migration
|
29
|
+
|
30
|
+
$ rake db:migrate
|
31
|
+
|
32
|
+
## Usage
|
33
|
+
|
34
|
+
Require the module
|
35
|
+
|
36
|
+
$ require 'little_brother'
|
37
|
+
|
38
|
+
|
39
|
+
Just grab the controller you want to keep track of the actions executed and include the module `include LittleBrother::Record` to start recording.
|
40
|
+
|
41
|
+
```erb
|
42
|
+
class ApplicationController < ApplicationController
|
43
|
+
|
44
|
+
include LittleBrother::Record
|
45
|
+
|
46
|
+
...
|
47
|
+
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
### User oriented recording
|
52
|
+
If you want to keep track of the user that triggers the actions, you have to supply a `watch_user` method in the controller.
|
53
|
+
|
54
|
+
```erb
|
55
|
+
class ApplicationController < ApplicationController
|
56
|
+
|
57
|
+
include LittleBrother::Record
|
58
|
+
|
59
|
+
def watch_user
|
60
|
+
@watch_user = "John Doe"
|
61
|
+
end
|
62
|
+
...
|
63
|
+
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
## Helpers
|
68
|
+
Some managment and statistics utils are provided to retrive the stored data
|
69
|
+
|
70
|
+
### Utils provided by `LittleBrother::Utils` module:
|
71
|
+
|
72
|
+
|
73
|
+
LittleBrother::Utils.truncate_watchers
|
74
|
+
|
75
|
+
LittleBrother::Utils.keep_only_last_months
|
76
|
+
|
77
|
+
LittleBrother::Utils.user_actions_in_timeframe
|
78
|
+
|
79
|
+
|
80
|
+
### Statistics provided by `LittleBrother::Statistics` module:
|
81
|
+
|
82
|
+
LittleBrother::Statistics.most_active_users
|
83
|
+
|
84
|
+
LittleBrother::Statistics.least_active_users
|
85
|
+
|
86
|
+
LittleBrother::Statistics.most_active_users_this_month
|
87
|
+
|
88
|
+
LittleBrother::Statistics.least_active_users_this_month
|
89
|
+
|
90
|
+
LittleBrother::Statistics.most_used_action
|
91
|
+
|
92
|
+
LittleBrother::Statistics.least_used_action
|
93
|
+
|
94
|
+
LittleBrother::Statistics.most_used_controller_action
|
95
|
+
|
96
|
+
LittleBrother::Statistics.least_used_controller_action
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
class CreateWatchers < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table(:watchers) do |t|
|
4
|
+
t.string :user
|
5
|
+
t.string :controller
|
6
|
+
t.string :action
|
7
|
+
t.string :controller_action
|
8
|
+
t.string :user_ip
|
9
|
+
t.string :additional_info
|
10
|
+
t.string :params
|
11
|
+
t.timestamps
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table :watchers
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
class LittleBrotherSetupGenerator < Rails::Generators::Base
|
5
|
+
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
source_root File.expand_path('../../../../', __FILE__)
|
8
|
+
|
9
|
+
def self.next_migration_number(path)
|
10
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
11
|
+
end
|
12
|
+
|
13
|
+
def migration
|
14
|
+
unless watchers_table_exists? # SOURCE -> DESTINATION
|
15
|
+
puts "* watchers table creation migration was created!"
|
16
|
+
puts "* run rake db:migrate"
|
17
|
+
migration_template "db/migrate/create_watchers.rb", "db/migrate/create_watchers.rb"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def watchers_table_exists?
|
22
|
+
ActiveRecord::Base.connection.table_exists?(:watchers)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module LittleBrother
|
2
|
+
module Record
|
3
|
+
def self.included(base)
|
4
|
+
base.send :before_filter, :record
|
5
|
+
end
|
6
|
+
|
7
|
+
def record
|
8
|
+
unless request.nil?
|
9
|
+
w_user = defined?(watch_user) ? watch_user : ""
|
10
|
+
Watcher.create(:user_ip => request.remote_ip,
|
11
|
+
:user => w_user,
|
12
|
+
:params => params,
|
13
|
+
:controller => controller_name,
|
14
|
+
:action => action_name,
|
15
|
+
:controller_action => controller_name+":"+action_name)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module LittleBrother
|
2
|
+
class Statistics
|
3
|
+
|
4
|
+
RECORD_LIMIT=10
|
5
|
+
|
6
|
+
# User Statistics
|
7
|
+
def self.most_active_users limit=RECORD_LIMIT
|
8
|
+
Watcher.count(:all, :conditions => ['user IS NOT NULL'], :group => 'user', :order => "count_all desc", :limit => limit)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.least_active_users limit=RECORD_LIMIT
|
12
|
+
Watcher.count(:all, :conditions => ['user IS NOT NULL'], :group => 'user', :order => "count_all asc", :limit => limit)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.most_active_users_this_month limit=RECORD_LIMIT
|
16
|
+
Watcher.count(:all, :conditions => ["user IS NOT NULL and created_at BETWEEN ? AND ?", Time.now.beginning_of_month, Time.now.end_of_month], :group => 'user', :order => "count_all desc", :limit => limit)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.least_active_users_this_month limit=RECORD_LIMIT
|
20
|
+
Watcher.count(:all, :conditions => ["user IS NOT NULL and created_at BETWEEN ? AND ?", Time.now.beginning_of_month, Time.now.end_of_month], :group => 'user', :order => "count_all asc", :limit => limit)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Action Statistics
|
24
|
+
def self.most_used_action limit=RECORD_LIMIT
|
25
|
+
Watcher.count(:all, :group => 'action', :order => "count_all desc", :limit => limit)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.least_used_action limit=RECORD_LIMIT
|
29
|
+
Watcher.count(:all, :group => 'action', :order => "count_all asc", :limit => limit)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Controller Action Statistics
|
33
|
+
def self.most_used_controller_action limit=RECORD_LIMIT
|
34
|
+
Watcher.count(:all, :group => 'controller_action', :order => "count_all desc", :limit => limit)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.least_used_controller_action limit=RECORD_LIMIT
|
38
|
+
Watcher.count(:all, :group => 'controller_action', :order => "count_all asc", :limit => limit)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module LittleBrother
|
2
|
+
class Utils
|
3
|
+
module ClassMethods
|
4
|
+
|
5
|
+
def truncate_watchers
|
6
|
+
ActiveRecord::Base.connection.execute("truncate table watchers")
|
7
|
+
end
|
8
|
+
|
9
|
+
# TODO: Validate number_of_months
|
10
|
+
def keep_only_last_months(number_of_months)
|
11
|
+
Watcher.find(:all, :conditions => ['created_at < ?', Time.now-number_of_months.months])
|
12
|
+
end
|
13
|
+
|
14
|
+
def user_actions_in_timeframe(user, start_date, end_date)
|
15
|
+
unless user.nil? || start_date.nil? || end_date.nil?
|
16
|
+
where(:user => user, :created_at => start_date..end_date)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/little_brother/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Roger Correia"]
|
6
|
+
gem.email = ["rogerpcorreia@gmail.com"]
|
7
|
+
gem.description = %q{Controller request/action monitor}
|
8
|
+
gem.summary = %q{Monitors/Stores every action passed through the controller. The data is stored for conveniently for later analysis and statistics.}
|
9
|
+
gem.homepage = "https://github.com/rpc/little_brother"
|
10
|
+
|
11
|
+
gem.add_dependency('activerecord','>= 3.0.0')
|
12
|
+
gem.add_dependency('activesupport','>= 3.0.0')
|
13
|
+
gem.add_development_dependency 'rspec-rails'
|
14
|
+
gem.add_development_dependency 'rake'
|
15
|
+
|
16
|
+
gem.files = `git ls-files`.split($\)
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.name = "little_brother"
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
gem.date = '2012-08-30'
|
22
|
+
gem.version = LittleBrother::VERSION
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Configure Rails Environment
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
|
4
|
+
require 'active_record'
|
5
|
+
require 'active_support'
|
6
|
+
#require 'rspec/rails'
|
7
|
+
|
8
|
+
|
9
|
+
class TestApplicationController < ApplicationController
|
10
|
+
|
11
|
+
include LittleBrother::Record
|
12
|
+
|
13
|
+
#instance variable for watch_user
|
14
|
+
def watch_user
|
15
|
+
@watch_user = "John Doe"
|
16
|
+
end
|
17
|
+
helper_method :current_user
|
18
|
+
|
19
|
+
def index
|
20
|
+
render :text => "OK"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'TestApplication' do
|
4
|
+
|
5
|
+
it "should get index" do
|
6
|
+
# Note, rails 3.x scaffolding may add lines like get :index, {}, valid_session
|
7
|
+
# the valid_session overrides the devise login. Remove the valid_session from your specs
|
8
|
+
get 'index'
|
9
|
+
response.should be_success
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: little_brother
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Roger Correia
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-30 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activerecord
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 3.0.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.0.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: activesupport
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.0.0
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.0.0
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec-rails
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Controller request/action monitor
|
79
|
+
email:
|
80
|
+
- rogerpcorreia@gmail.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- Gemfile
|
87
|
+
- LICENSE
|
88
|
+
- README.md
|
89
|
+
- Rakefile
|
90
|
+
- db/migrate/create_watchers.rb
|
91
|
+
- lib/generators/little_brother_setup/little_brother_setup_generator.rb
|
92
|
+
- lib/little_brother.rb
|
93
|
+
- lib/little_brother/record.rb
|
94
|
+
- lib/little_brother/statistics.rb
|
95
|
+
- lib/little_brother/utils.rb
|
96
|
+
- lib/little_brother/version.rb
|
97
|
+
- lib/little_brother/watcher.rb
|
98
|
+
- little_brother.gemspec
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
- spec/watcher_spec.rb
|
101
|
+
homepage: https://github.com/rpc/little_brother
|
102
|
+
licenses: []
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 1.8.24
|
122
|
+
signing_key:
|
123
|
+
specification_version: 3
|
124
|
+
summary: Monitors/Stores every action passed through the controller. The data is stored
|
125
|
+
for conveniently for later analysis and statistics.
|
126
|
+
test_files:
|
127
|
+
- spec/spec_helper.rb
|
128
|
+
- spec/watcher_spec.rb
|