nightfury 0.0.1 → 0.1.0
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/README.md +29 -5
- data/lib/nightfury.rb +1 -0
- data/lib/nightfury/metric/avg_time_series.rb +22 -0
- data/lib/nightfury/metric/time_series.rb +22 -8
- data/lib/nightfury/version.rb +1 -1
- data/spec/nightfury/metric/avg_time_series_spec.rb +22 -0
- data/spec/nightfury/metric/time_series_spec.rb +21 -1
- metadata +5 -2
data/README.md
CHANGED
@@ -1,6 +1,34 @@
|
|
1
1
|
# Nightfury
|
2
2
|
|
3
|
-
|
3
|
+
**This gem is not yet production ready**
|
4
|
+
|
5
|
+
## Concept
|
6
|
+
|
7
|
+
Nightfury provides a reporting framework built on Redis for Ruby/Ruby on Rails applications. The framework is designed
|
8
|
+
to store differnt metrics in a time series or as a single value which can be easily queried. The following are the key terms:
|
9
|
+
|
10
|
+
### Identity
|
11
|
+
|
12
|
+
Like a company or a ticket or a user (anything that we want stats on very quickly)
|
13
|
+
Has an id (can auto-generate but generally provided so you can map it to your db ids etc)
|
14
|
+
Has metrics
|
15
|
+
|
16
|
+
### Metrics
|
17
|
+
|
18
|
+
A identity has many metrics.
|
19
|
+
|
20
|
+
* Metric can be a single value or a time series.
|
21
|
+
* The value can be aggregate (average)
|
22
|
+
* When you ask for the metric back, you can specify a time range for the values that you want back (if time series)
|
23
|
+
|
24
|
+
### Tags
|
25
|
+
|
26
|
+
Identities can be tagged and have multiple tags
|
27
|
+
You can ask for stats for identities with certain tags over a particular time range (if asking for metrics that are series)
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
**See example.rb for usage**
|
4
32
|
|
5
33
|
## Installation
|
6
34
|
|
@@ -16,10 +44,6 @@ Or install it yourself as:
|
|
16
44
|
|
17
45
|
$ gem install nightfury
|
18
46
|
|
19
|
-
## Usage
|
20
|
-
|
21
|
-
TODO: Write usage instructions here
|
22
|
-
|
23
47
|
## Contributing
|
24
48
|
|
25
49
|
1. Fork it
|
data/lib/nightfury.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Nightfury
|
2
|
+
module Metric
|
3
|
+
class AvgTimeSeries < TimeSeries
|
4
|
+
|
5
|
+
def default_meta
|
6
|
+
{'count' => 0}
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def before_set(value)
|
12
|
+
count = meta['count'] + 1
|
13
|
+
raw = get
|
14
|
+
current_value = raw.nil? ? 0 : raw.values.first.to_f
|
15
|
+
result = (current_value + value) / count.to_f
|
16
|
+
meta['count'] = count
|
17
|
+
save_meta
|
18
|
+
result
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -21,10 +21,13 @@ module Nightfury
|
|
21
21
|
data_point = ''
|
22
22
|
if timestamp
|
23
23
|
timestamp = timestamp.to_i
|
24
|
-
data_point = redis.zrangebyscore(redis_key, timestamp, timestamp).
|
24
|
+
data_point = redis.zrangebyscore(redis_key, timestamp, timestamp, withscores: true).last
|
25
25
|
else
|
26
|
-
data_point = redis.zrevrange(redis_key, 0, 0).
|
26
|
+
data_point = redis.zrevrange(redis_key, 0, 0, withscores: true).last
|
27
27
|
end
|
28
|
+
|
29
|
+
return nil if data_point.nil?
|
30
|
+
return nil if data_point[1] == 0.0
|
28
31
|
|
29
32
|
time, data = decode_data_point(data_point)
|
30
33
|
{time => data}
|
@@ -34,25 +37,34 @@ module Nightfury
|
|
34
37
|
return nil unless redis.exists(redis_key)
|
35
38
|
start_time = start_time.to_i
|
36
39
|
end_time = end_time.to_i
|
37
|
-
data_points = redis.zrangebyscore(redis_key, start_time, end_time)
|
40
|
+
data_points = redis.zrangebyscore(redis_key, start_time, end_time, withscores: true)
|
38
41
|
decode_many_data_points(data_points)
|
39
42
|
end
|
40
43
|
|
41
44
|
def get_all
|
42
45
|
return nil unless redis.exists(redis_key)
|
43
|
-
data_points = redis.zrange(redis_key,1,-1)
|
46
|
+
data_points = redis.zrange(redis_key,1,-1, withscores: true)
|
44
47
|
decode_many_data_points(data_points)
|
45
48
|
end
|
46
49
|
|
47
50
|
def meta
|
48
|
-
|
49
|
-
|
51
|
+
unless @meta
|
52
|
+
json = redis.zrange(redis_key, 0, 0).first
|
53
|
+
@meta = JSON.parse(json)
|
54
|
+
end
|
55
|
+
@meta
|
50
56
|
end
|
51
57
|
|
52
58
|
def default_meta
|
53
59
|
{}
|
54
60
|
end
|
55
61
|
|
62
|
+
protected
|
63
|
+
|
64
|
+
def before_set(value)
|
65
|
+
value
|
66
|
+
end
|
67
|
+
|
56
68
|
private
|
57
69
|
|
58
70
|
def add_value_to_timeline(value, time)
|
@@ -71,6 +83,7 @@ module Nightfury
|
|
71
83
|
end
|
72
84
|
|
73
85
|
def decode_data_point(data_point)
|
86
|
+
data_point = data_point.first
|
74
87
|
colon_index = data_point.index(':')
|
75
88
|
|
76
89
|
[
|
@@ -79,8 +92,9 @@ module Nightfury
|
|
79
92
|
]
|
80
93
|
end
|
81
94
|
|
82
|
-
def
|
83
|
-
|
95
|
+
def save_meta
|
96
|
+
redis.zremrangebyscore redis_key, 0, 0
|
97
|
+
redis.zadd redis_key, 0, meta.to_json
|
84
98
|
end
|
85
99
|
|
86
100
|
def init_time_series
|
data/lib/nightfury/version.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Nightfury::Metric::AvgTimeSeries do
|
4
|
+
it "should have the right default meta" do
|
5
|
+
avg_metric = Nightfury::Metric::AvgTimeSeries.new(:avg)
|
6
|
+
avg_metric.default_meta.should == { 'count' => 0 }
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should calculate avg before saving" do
|
10
|
+
avg_metric = Nightfury::Metric::AvgTimeSeries.new(:avg)
|
11
|
+
avg_metric.set(1)
|
12
|
+
avg_metric.set(2)
|
13
|
+
avg_metric.get.values.first.should == "1.5"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should update meta update count" do
|
17
|
+
avg_metric = Nightfury::Metric::AvgTimeSeries.new(:avg)
|
18
|
+
avg_metric.set(1)
|
19
|
+
avg_metric.set(2)
|
20
|
+
avg_metric.meta['count'].should == 2
|
21
|
+
end
|
22
|
+
end
|
@@ -27,6 +27,11 @@ describe Nightfury::Metric::TimeSeries do
|
|
27
27
|
result = ts_metric.get
|
28
28
|
result[time_later.to_i.to_s].should == '2'
|
29
29
|
end
|
30
|
+
|
31
|
+
it "should return nil if there are no data points" do
|
32
|
+
ts_metric = Nightfury::Metric::TimeSeries.new(:time)
|
33
|
+
ts_metric.get.should be_nil
|
34
|
+
end
|
30
35
|
end
|
31
36
|
|
32
37
|
context "with timestamp" do
|
@@ -39,6 +44,11 @@ describe Nightfury::Metric::TimeSeries do
|
|
39
44
|
result = ts_metric.get(time_now)
|
40
45
|
result[time_now.to_i.to_s].should == '1'
|
41
46
|
end
|
47
|
+
|
48
|
+
it "should return nil if there are no data points at the timestamp" do
|
49
|
+
ts_metric = Nightfury::Metric::TimeSeries.new(:time)
|
50
|
+
ts_metric.get(Time.now).should be_nil
|
51
|
+
end
|
42
52
|
end
|
43
53
|
end
|
44
54
|
|
@@ -50,6 +60,11 @@ describe Nightfury::Metric::TimeSeries do
|
|
50
60
|
ts_metric.get_range(Time.now, Time.now).should be_nil
|
51
61
|
end
|
52
62
|
|
63
|
+
it "should return an empty array if no data points are present in the specified ranges" do
|
64
|
+
ts_metric = Nightfury::Metric::TimeSeries.new(:time)
|
65
|
+
ts_metric.get_range(Time.now, Time.now).should be_empty
|
66
|
+
end
|
67
|
+
|
53
68
|
it "should get all data points between the specified ranges" do
|
54
69
|
ts_metric = Nightfury::Metric::TimeSeries.new(:time)
|
55
70
|
time = Time.now
|
@@ -71,13 +86,18 @@ describe Nightfury::Metric::TimeSeries do
|
|
71
86
|
end
|
72
87
|
|
73
88
|
describe "#get_all" do
|
74
|
-
it "should
|
89
|
+
it "should return nil if metric key on redis is empty" do
|
75
90
|
ts_metric = Nightfury::Metric::TimeSeries.new(:time)
|
76
91
|
# delete redis key
|
77
92
|
ts_metric.redis.del ts_metric.redis_key
|
78
93
|
ts_metric.get_all.should be_nil
|
79
94
|
end
|
80
95
|
|
96
|
+
it "should return an empty array of there are no data points" do
|
97
|
+
ts_metric = Nightfury::Metric::TimeSeries.new(:time)
|
98
|
+
ts_metric.get_all.should be_empty
|
99
|
+
end
|
100
|
+
|
81
101
|
it "should get all the data points in the series" do
|
82
102
|
ts_metric = Nightfury::Metric::TimeSeries.new(:time)
|
83
103
|
time = Time.now
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nightfury
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-12-
|
13
|
+
date: 2012-12-21 00:00:00.000000000 Z
|
14
14
|
dependencies: []
|
15
15
|
description: Nightfury is a reporting/analytics backend written on Redis
|
16
16
|
email:
|
@@ -29,11 +29,13 @@ files:
|
|
29
29
|
- lib/nightfury.rb
|
30
30
|
- lib/nightfury/identity.rb
|
31
31
|
- lib/nightfury/metric.rb
|
32
|
+
- lib/nightfury/metric/avg_time_series.rb
|
32
33
|
- lib/nightfury/metric/time_series.rb
|
33
34
|
- lib/nightfury/metric/value.rb
|
34
35
|
- lib/nightfury/version.rb
|
35
36
|
- nightfury.gemspec
|
36
37
|
- spec/nightfury/identity_spec.rb
|
38
|
+
- spec/nightfury/metric/avg_time_series_spec.rb
|
37
39
|
- spec/nightfury/metric/time_series_spec.rb
|
38
40
|
- spec/nightfury/metric/value_spec.rb
|
39
41
|
- spec/nightfury/metric_spec.rb
|
@@ -66,6 +68,7 @@ specification_version: 3
|
|
66
68
|
summary: Nightfury is a reporting/analytics backend written on Redis
|
67
69
|
test_files:
|
68
70
|
- spec/nightfury/identity_spec.rb
|
71
|
+
- spec/nightfury/metric/avg_time_series_spec.rb
|
69
72
|
- spec/nightfury/metric/time_series_spec.rb
|
70
73
|
- spec/nightfury/metric/value_spec.rb
|
71
74
|
- spec/nightfury/metric_spec.rb
|