reportier 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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +0 -0
- data/README.md +94 -0
- data/lib/reportier.rb +15 -0
- data/lib/reportier/defaults.rb +58 -0
- data/lib/reportier/naming.rb +38 -0
- data/lib/reportier/persister.rb +65 -0
- data/lib/reportier/reporter.rb +48 -0
- data/lib/reportier/stats.rb +57 -0
- data/lib/reportier/time.rb +31 -0
- data/lib/reportier/version.rb +3 -0
- metadata +54 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b7aed0447a45d12d75dac3467f024b34ccff230a
|
4
|
+
data.tar.gz: d26b31a8cb45c81d7ee4ca51d70f77643f99b18c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 269014b83979ca883e041891f90eaa80a0c4743cd6b716f6150e1c08e73a80d882483601c841aece9784835319873b9f4ee427665006cff16dfd5cd5f316b602
|
7
|
+
data.tar.gz: 7c2c0872876920642f9cadd16b132527135885a19cf845d07d41172968a1a3646ea37004374bd263476e2c824e1011079a8f0e43d1e6267c7070d795ffebe538
|
data/CHANGELOG.md
ADDED
File without changes
|
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# Reportier the stat tracker
|
2
|
+
|
3
|
+
This is a tracker that tracks the count of events.
|
4
|
+
|
5
|
+
## Use
|
6
|
+
|
7
|
+
Using the Tracker is fairly simple, by default there are 4 types of trackers.
|
8
|
+
An `Hourly`, a `Daily` a `Weekly` and a `Monthly`.
|
9
|
+
To add something to a tracker simply `.get` it and `#add` something.
|
10
|
+
|
11
|
+
You can also `#report` the current state of the tracker, however trackers report and reset by themselves
|
12
|
+
as long as you keep adding items to them.
|
13
|
+
|
14
|
+
Examples:
|
15
|
+
|
16
|
+
```
|
17
|
+
Reportier::Daily.get.add('new user registration')
|
18
|
+
|
19
|
+
Reportier::Daily.get.report
|
20
|
+
# -> Daily report started at 2016-06-17T15:34:40+03:00
|
21
|
+
# @new_user_registrations: 1
|
22
|
+
```
|
23
|
+
|
24
|
+
You can also use `Reportier.add_to_all('we need to track this')` and it will add the item to all trackers.
|
25
|
+
If you keep adding this way, each tracker will report when his time is due, and you have to worry about
|
26
|
+
nothing else.
|
27
|
+
|
28
|
+
Trackers also have a `#to_json` method for converting tracked items to json.
|
29
|
+
|
30
|
+
|
31
|
+
## Setting defaults
|
32
|
+
|
33
|
+
Reportier has 3 methods for setting defaults.
|
34
|
+
|
35
|
+
`.set_default_reporting_vars`
|
36
|
+
|
37
|
+
This is for setting default things you want to track. Example use would be.
|
38
|
+
|
39
|
+
```
|
40
|
+
Reportier.set_default_reporting_vars active_users: User.active, open_conversations: Conversation.all.count
|
41
|
+
```
|
42
|
+
|
43
|
+
`.set_default_types`
|
44
|
+
|
45
|
+
This is for setting default tracker types, by type we mean how much time it needs for reset.
|
46
|
+
So the usage would be
|
47
|
+
|
48
|
+
|
49
|
+
```
|
50
|
+
Reportier.set_default_types 'Yearly' => 1.year, 'BiDay' => 2.days
|
51
|
+
```
|
52
|
+
|
53
|
+
These new tracker classes will be created and can be used normally like any other tracker,
|
54
|
+
also `Reportier.add_to_all` will take this new classes in account.
|
55
|
+
Note that if you don't use Rails you can `import` or `extend` `Reportier::Time` to you current environment
|
56
|
+
and use `hours(1)`, `days(1)`, `weeks(1)`, `months(1)`, `years(1)`, years and months are not exact.
|
57
|
+
|
58
|
+
`.set_default_reporters`
|
59
|
+
|
60
|
+
This is for setting default reporters, by default Reportier will only report to console
|
61
|
+
but we also support reporting to slack and logger, and you can easily create your custom reporting methods.
|
62
|
+
|
63
|
+
```
|
64
|
+
Reportier.set_default_reporters slack: 'slack-reporter', logger: 'logger'
|
65
|
+
```
|
66
|
+
|
67
|
+
If you want to add custom reporters just add their name and library and then define a `to_#{name)` method to the `Reporter`
|
68
|
+
e.x.
|
69
|
+
|
70
|
+
```
|
71
|
+
Reportier.set_default_reporters twilio: 'twilio-ruby'
|
72
|
+
|
73
|
+
class Reportier::Reporter
|
74
|
+
def to_twilio
|
75
|
+
## you code here
|
76
|
+
end
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
|
81
|
+
## More
|
82
|
+
|
83
|
+
There are many more features to come, as persiters.
|
84
|
+
This has been kind of a personal project, please give me feedback on anything that has room for improvement.
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
data/lib/reportier.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'reportier/naming'
|
2
|
+
require_relative 'reportier/time'
|
3
|
+
require_relative 'reportier/reporter'
|
4
|
+
require_relative 'reportier/persister'
|
5
|
+
require_relative 'reportier/stats'
|
6
|
+
require_relative 'reportier/defaults'
|
7
|
+
require_relative 'reportier/version'
|
8
|
+
|
9
|
+
module Reportier
|
10
|
+
def self.add_to_all(item)
|
11
|
+
Default::TYPES.each do |type, v|
|
12
|
+
eval "#{type}.get.add(item)"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Reportier
|
2
|
+
module Default
|
3
|
+
extend Time
|
4
|
+
|
5
|
+
TYPES = {
|
6
|
+
'Hourly' => hours(1),
|
7
|
+
'Daily' => days(1),
|
8
|
+
'Weekly' => weeks(1),
|
9
|
+
'Monthly' => months(1)
|
10
|
+
}
|
11
|
+
|
12
|
+
REPORTING_VARS = {}
|
13
|
+
|
14
|
+
REPORTERS = {
|
15
|
+
console: nil
|
16
|
+
}
|
17
|
+
|
18
|
+
PERSISTER = :memory
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.set_default_reporting_vars(opts={})
|
23
|
+
Default::REPORTING_VARS.merge!(opts)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.set_default_types(opts={})
|
27
|
+
Default::TYPES.merge!(opts)
|
28
|
+
_default_classes_create
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.set_default_reporters(opts={})
|
32
|
+
Default::REPORTERS.merge!(opts)
|
33
|
+
_require_reporter_libraries
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def self._require_reporter_libraries
|
39
|
+
Default::REPORTERS.each do |name, lib|
|
40
|
+
require lib if lib
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self._default_classes_create
|
45
|
+
Default::TYPES.each do |key, val|
|
46
|
+
raise TypeError unless val.kind_of? Integer
|
47
|
+
s_key = Namer.new.name_class(key)
|
48
|
+
eval %{
|
49
|
+
class #{s_key} < Instant
|
50
|
+
def expires_at
|
51
|
+
@started_at + #{val}
|
52
|
+
end
|
53
|
+
end
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
_default_classes_create
|
58
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Reportier
|
2
|
+
class Namer
|
3
|
+
|
4
|
+
def name_class(item)
|
5
|
+
create_string(item).capitalize
|
6
|
+
end
|
7
|
+
|
8
|
+
def name_item(item)
|
9
|
+
pluralize(create_string(item))
|
10
|
+
end
|
11
|
+
|
12
|
+
def name(item)
|
13
|
+
create_string(item)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def create_string(item)
|
19
|
+
return secure(item.to_s) if stringy?(item)
|
20
|
+
item.class.to_s.downcase
|
21
|
+
end
|
22
|
+
|
23
|
+
def secure(string)
|
24
|
+
string.gsub("\n",'_').gsub('\n', '_').gsub(';', '').gsub(' ', '_') \
|
25
|
+
.gsub('"', '').gsub('\'','')
|
26
|
+
end
|
27
|
+
|
28
|
+
def stringy?(item)
|
29
|
+
item.is_a?(String) || item.is_a?(Symbol)
|
30
|
+
end
|
31
|
+
|
32
|
+
def pluralize(string)
|
33
|
+
string.pluralize
|
34
|
+
rescue NoMethodError
|
35
|
+
string + 's'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Reportier
|
2
|
+
class Persister
|
3
|
+
def self.get
|
4
|
+
eval "#{Namer.new.name_class(Default::PERSISTER)}Persister.new"
|
5
|
+
end
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
_initialize_default_reporting_vars
|
9
|
+
end
|
10
|
+
|
11
|
+
def save(item)
|
12
|
+
create_accessor(item) unless (eval "@#{item}")
|
13
|
+
eval "@#{item} += 1"
|
14
|
+
end
|
15
|
+
|
16
|
+
def report
|
17
|
+
attr_messages.inject(&:+).to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_json
|
21
|
+
"{#{to_hash.map { |k,v| "\"#{k.to_s}\": #{v.to_s}" }.flatten.join(",\n")}}"
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def attr_messages
|
27
|
+
reporting_vars.map do |var|
|
28
|
+
"#{var}: #{eval var.to_s}\n"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_accessor(name)
|
33
|
+
self.class.module_eval "attr_accessor :#{name}"
|
34
|
+
eval "@#{name} ||= 0"
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_hash
|
38
|
+
Hash[ *reporting_vars.collect { |v| [ v.to_s, (eval v.to_s) ] }.flatten ]
|
39
|
+
end
|
40
|
+
|
41
|
+
def reporting_vars
|
42
|
+
instance_variables
|
43
|
+
end
|
44
|
+
|
45
|
+
def clear
|
46
|
+
reporting_vars.each do |var|
|
47
|
+
eval "#{var} = 0"
|
48
|
+
end
|
49
|
+
initialize
|
50
|
+
end
|
51
|
+
|
52
|
+
def _initialize_default_reporting_vars
|
53
|
+
Default::REPORTING_VARS.each do |key, val|
|
54
|
+
raise TypeError unless val.kind_of? Integer
|
55
|
+
eval "@#{Namer.new.name(key)} = #{val}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
class MemoryPersister < Persister; end
|
60
|
+
class RedisPersister < Persister
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Reportier
|
2
|
+
class Reporter
|
3
|
+
attr_accessor :reporters
|
4
|
+
|
5
|
+
def self.get
|
6
|
+
@current ||= new(Default::REPORTERS)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(reporters)
|
10
|
+
@reporters = reporters
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(tracker, &blk)
|
14
|
+
@reporters.each do |reporter, v|
|
15
|
+
eval "to_#{Namer.new.name(reporter)} \"#{blk.call}\""
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def to_console(message)
|
22
|
+
puts message
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_slack(message)
|
26
|
+
type = message.split.first + '_tracker'
|
27
|
+
SlackReporter.new(type).call do
|
28
|
+
message
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_logger(message)
|
33
|
+
create_dir('log') unless Dir.exists? 'log'
|
34
|
+
Logger.new('log/reportier.log').info("\n" + message)
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_twilio
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def create_dir(dir)
|
44
|
+
require 'fileutils'
|
45
|
+
FileUtils.mkdir_p dir
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Reportier
|
2
|
+
|
3
|
+
class Instant
|
4
|
+
attr_accessor :reporter, :persister
|
5
|
+
|
6
|
+
def self.get
|
7
|
+
@current ||= new
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(opts = {})
|
11
|
+
@report_type = self.class.to_s.sub('Reportier::','')
|
12
|
+
@started_at = DateTime.now
|
13
|
+
@reporter = opts[:reporter] || Reporter.get
|
14
|
+
@persister = opts[:persister] || Persister.get
|
15
|
+
end
|
16
|
+
|
17
|
+
def add(item)
|
18
|
+
(report && clear) unless active?
|
19
|
+
item_name = name(item)
|
20
|
+
@persister.save(item_name)
|
21
|
+
item_added
|
22
|
+
end
|
23
|
+
|
24
|
+
def report
|
25
|
+
@reporter.call(self) do
|
26
|
+
"#{@report_type} report started at #{@started_at}\n" +
|
27
|
+
@persister.report
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_json
|
32
|
+
@persister.to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
def active?
|
36
|
+
DateTime.now < expires_at
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def clear
|
42
|
+
@persister.clear
|
43
|
+
end
|
44
|
+
|
45
|
+
def item_added
|
46
|
+
"item added"
|
47
|
+
end
|
48
|
+
|
49
|
+
def name(item)
|
50
|
+
Namer.new.name_item(item)
|
51
|
+
end
|
52
|
+
|
53
|
+
def expires_at
|
54
|
+
@started_at
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Reportier
|
2
|
+
module Time
|
3
|
+
def seconds(int)
|
4
|
+
int
|
5
|
+
end
|
6
|
+
|
7
|
+
def minutes(int)
|
8
|
+
int * 60
|
9
|
+
end
|
10
|
+
|
11
|
+
def hours(int)
|
12
|
+
minutes(int) * 60
|
13
|
+
end
|
14
|
+
|
15
|
+
def days(int)
|
16
|
+
hours(int) * 24
|
17
|
+
end
|
18
|
+
|
19
|
+
def weeks(int)
|
20
|
+
days(int) * 7
|
21
|
+
end
|
22
|
+
|
23
|
+
def months(int)
|
24
|
+
days(int) * 30
|
25
|
+
end
|
26
|
+
|
27
|
+
def years(int)
|
28
|
+
months(int) * 12
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: reportier
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.4'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Vasilis Spilka
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-13 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A stat tracker that reports automatically as you just add items
|
14
|
+
email: vasspilka@gmail.com
|
15
|
+
executables: []
|
16
|
+
extensions: []
|
17
|
+
extra_rdoc_files: []
|
18
|
+
files:
|
19
|
+
- CHANGELOG.md
|
20
|
+
- README.md
|
21
|
+
- lib/reportier.rb
|
22
|
+
- lib/reportier/defaults.rb
|
23
|
+
- lib/reportier/naming.rb
|
24
|
+
- lib/reportier/persister.rb
|
25
|
+
- lib/reportier/reporter.rb
|
26
|
+
- lib/reportier/stats.rb
|
27
|
+
- lib/reportier/time.rb
|
28
|
+
- lib/reportier/version.rb
|
29
|
+
homepage: http://rubygems.org/gems/reportier
|
30
|
+
licenses:
|
31
|
+
- MIT
|
32
|
+
metadata: {}
|
33
|
+
post_install_message:
|
34
|
+
rdoc_options: []
|
35
|
+
require_paths:
|
36
|
+
- lib
|
37
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: 2.2.0
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 2.5.1
|
50
|
+
signing_key:
|
51
|
+
specification_version: 4
|
52
|
+
summary: A stat tracker that reports
|
53
|
+
test_files: []
|
54
|
+
has_rdoc:
|