ezmetrics 1.1.0 → 1.1.1
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 +4 -4
- data/README.md +20 -22
- data/lib/ezmetrics.rb +19 -24
- data/lib/ezmetrics/benchmark.rb +2 -2
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 518d9350ed026801311bdc695857fdd057856f6b7fe40715bf8072c990e8e5b8
|
4
|
+
data.tar.gz: 7d36fbd3e63994789ce8ac04212fb44c30041fd33f7173fbfdf1a6257beea99a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42e990916d474ed52f08330bd7210b4c6f464a0199354cfc1fe3710817b9d57790d445d0d1f88c8fccd6daeb627638a80dd8b578c685544f6a4f9c7765522a5f
|
7
|
+
data.tar.gz: 5b49eec021acaef39af2c9401681fa85f02d368f36231a60a64faf595e5b0c1432ce07a67fb86ce9c8b3041835fd4480da86ea5d91f7ca0939ef5b40592e6a49
|
data/README.md
CHANGED
@@ -31,22 +31,20 @@ You can change the timeframe according to your needs and save the metrics by cal
|
|
31
31
|
EZmetrics.new.log(duration: 100.5, views: 40.7, db: 59.8, queries: 4, status: 200)
|
32
32
|
```
|
33
33
|
|
34
|
-
or
|
35
|
-
|
36
34
|
```ruby
|
37
35
|
# Store the metrics for 10 minutes
|
38
36
|
EZmetrics.new(10.minutes).log(duration: 100.5, views: 40.7, db: 59.8, queries: 4, status: 200)
|
39
37
|
```
|
40
38
|
|
41
|
-
|
39
|
+
---
|
40
|
+
|
41
|
+
For displaying metrics you need to call `show` method:
|
42
42
|
|
43
43
|
```ruby
|
44
44
|
# Aggregate and show metrics for last 60 seconds (default behaviour)
|
45
45
|
EZmetrics.new.show
|
46
46
|
```
|
47
47
|
|
48
|
-
or
|
49
|
-
|
50
48
|
```ruby
|
51
49
|
# Aggregate and show metrics for last 10 minutes
|
52
50
|
EZmetrics.new(10.minutes).show
|
@@ -121,11 +119,11 @@ This will return a hash with the following structure:
|
|
121
119
|
}
|
122
120
|
```
|
123
121
|
|
124
|
-
###
|
122
|
+
### Aggregation options
|
125
123
|
|
126
|
-
The
|
124
|
+
The aggregation can be easily configured by specifying aggregation options as in the following examples:
|
127
125
|
|
128
|
-
1. Single
|
126
|
+
**1. Single**
|
129
127
|
|
130
128
|
```ruby
|
131
129
|
EZmetrics.new.show(duration: :max)
|
@@ -139,7 +137,9 @@ EZmetrics.new.show(duration: :max)
|
|
139
137
|
}
|
140
138
|
```
|
141
139
|
|
142
|
-
|
140
|
+
---
|
141
|
+
|
142
|
+
**2. Multiple**
|
143
143
|
|
144
144
|
```ruby
|
145
145
|
EZmetrics.new.show(queries: [:max, :avg])
|
@@ -154,7 +154,9 @@ EZmetrics.new.show(queries: [:max, :avg])
|
|
154
154
|
}
|
155
155
|
```
|
156
156
|
|
157
|
-
|
157
|
+
---
|
158
|
+
|
159
|
+
**3. Requests**
|
158
160
|
|
159
161
|
```ruby
|
160
162
|
EZmetrics.new.show(requests: true)
|
@@ -174,7 +176,9 @@ EZmetrics.new.show(requests: true)
|
|
174
176
|
}
|
175
177
|
```
|
176
178
|
|
177
|
-
|
179
|
+
---
|
180
|
+
|
181
|
+
**4. Combined**
|
178
182
|
|
179
183
|
```ruby
|
180
184
|
EZmetrics.new.show(views: :avg, :db: [:avg, :max], requests: true)
|
@@ -203,13 +207,7 @@ EZmetrics.new.show(views: :avg, :db: [:avg, :max], requests: true)
|
|
203
207
|
|
204
208
|
### Performance
|
205
209
|
|
206
|
-
The
|
207
|
-
|
208
|
-
- [`get`](https://redis.io/commands/get)
|
209
|
-
- [`mget`](https://redis.io/commands/mget)
|
210
|
-
- [`setex`](https://redis.io/commands/setex)
|
211
|
-
|
212
|
-
which are extremely fast.
|
210
|
+
The aggregation speed relies on the performance of **Redis** (data storage) and **Oj** (json serialization/parsing).
|
213
211
|
|
214
212
|
You can check the **aggregation** time by running:
|
215
213
|
|
@@ -222,7 +220,7 @@ The result of running this benchmark on a _2017 Macbook Pro 2.9 GHz Intel Core i
|
|
222
220
|
| Interval | Duration (seconds) |
|
223
221
|
| :------: | :----------------: |
|
224
222
|
| 1 minute | 0.0 |
|
225
|
-
| 1 hour | 0.
|
226
|
-
| 12 hours | 0.
|
227
|
-
| 24 hours | 1.
|
228
|
-
| 48 hours |
|
223
|
+
| 1 hour | 0.04 |
|
224
|
+
| 12 hours | 0.49 |
|
225
|
+
| 24 hours | 1.51 |
|
226
|
+
| 48 hours | 3.48 |
|
data/lib/ezmetrics.rb
CHANGED
@@ -9,7 +9,6 @@ class EZmetrics
|
|
9
9
|
def initialize(interval_seconds=60)
|
10
10
|
@interval_seconds = interval_seconds.to_i
|
11
11
|
@redis = Redis.new
|
12
|
-
@storage_key = "ez-metrics"
|
13
12
|
end
|
14
13
|
|
15
14
|
def log(payload={duration: 0.0, views: 0.0, db: 0.0, queries: 0, status: 200})
|
@@ -23,7 +22,7 @@ class EZmetrics
|
|
23
22
|
|
24
23
|
this_second = Time.now.to_i
|
25
24
|
status_group = "#{payload[:status].to_s[0]}xx"
|
26
|
-
@this_second_metrics = redis.get(
|
25
|
+
@this_second_metrics = redis.get(this_second)
|
27
26
|
|
28
27
|
if this_second_metrics
|
29
28
|
@this_second_metrics = Oj.load(this_second_metrics)
|
@@ -51,7 +50,7 @@ class EZmetrics
|
|
51
50
|
this_second_metrics["statuses"][status_group] = 1
|
52
51
|
end
|
53
52
|
|
54
|
-
redis.setex(
|
53
|
+
redis.setex(this_second, interval_seconds, Oj.dump(this_second_metrics))
|
55
54
|
true
|
56
55
|
rescue => error
|
57
56
|
formatted_error(error)
|
@@ -60,12 +59,12 @@ class EZmetrics
|
|
60
59
|
def show(options=nil)
|
61
60
|
@options = options || default_options
|
62
61
|
interval_start = Time.now.to_i - interval_seconds
|
63
|
-
interval_keys = (interval_start..Time.now.to_i).to_a
|
62
|
+
interval_keys = (interval_start..Time.now.to_i).to_a
|
64
63
|
@interval_metrics = redis.mget(interval_keys).compact.map { |hash| Oj.load(hash) }
|
65
64
|
|
66
65
|
return {} unless interval_metrics.any?
|
67
66
|
|
68
|
-
@requests = interval_metrics.
|
67
|
+
@requests = interval_metrics.sum { |hash| hash["statuses"]["all"] }
|
69
68
|
build_result
|
70
69
|
rescue
|
71
70
|
{}
|
@@ -79,17 +78,7 @@ class EZmetrics
|
|
79
78
|
def build_result
|
80
79
|
result = {}
|
81
80
|
|
82
|
-
if options[:requests]
|
83
|
-
result[:requests] = {
|
84
|
-
all: requests,
|
85
|
-
grouped: {
|
86
|
-
"2xx" => count("2xx"),
|
87
|
-
"3xx" => count("3xx"),
|
88
|
-
"4xx" => count("4xx"),
|
89
|
-
"5xx" => count("5xx")
|
90
|
-
}
|
91
|
-
}
|
92
|
-
end
|
81
|
+
result[:requests] = { all: requests, grouped: count_all_status_groups } if options[:requests]
|
93
82
|
|
94
83
|
options.each do |metrics, aggregation_functions|
|
95
84
|
next unless METRICS.include?(metrics)
|
@@ -108,29 +97,35 @@ class EZmetrics
|
|
108
97
|
|
109
98
|
def aggregate(metrics, aggregation_function)
|
110
99
|
return unless AGGREGATION_FUNCTIONS.include?(aggregation_function)
|
111
|
-
return avg("#{metrics}_sum"
|
112
|
-
return max("#{metrics}_max"
|
100
|
+
return avg("#{metrics}_sum") if aggregation_function == :avg
|
101
|
+
return max("#{metrics}_max") if aggregation_function == :max
|
113
102
|
end
|
114
103
|
|
115
104
|
def update_sum(metrics)
|
116
|
-
this_second_metrics["#{metrics}_sum"] += safe_payload[metrics
|
105
|
+
this_second_metrics["#{metrics}_sum"] += safe_payload[metrics]
|
117
106
|
end
|
118
107
|
|
119
108
|
def update_max(metrics)
|
120
|
-
max_value = [safe_payload[metrics
|
109
|
+
max_value = [safe_payload[metrics], this_second_metrics["#{metrics}_max"]].max
|
121
110
|
this_second_metrics["#{metrics}_max"] = max_value
|
122
111
|
end
|
123
112
|
|
124
113
|
def avg(metrics)
|
125
|
-
(interval_metrics.
|
114
|
+
(interval_metrics.sum { |h| h[metrics] }.to_f / requests).round
|
126
115
|
end
|
127
116
|
|
128
117
|
def max(metrics)
|
129
|
-
interval_metrics.
|
118
|
+
interval_metrics.max { |h| h[metrics] }[metrics].round
|
130
119
|
end
|
131
120
|
|
132
|
-
def
|
133
|
-
interval_metrics.
|
121
|
+
def count_all_status_groups
|
122
|
+
interval_metrics.inject({ "2xx" => 0, "3xx" => 0, "4xx" => 0, "5xx" => 0 }) do |result, h|
|
123
|
+
result["2xx"] += h["statuses"]["2xx"]
|
124
|
+
result["3xx"] += h["statuses"]["3xx"]
|
125
|
+
result["4xx"] += h["statuses"]["4xx"]
|
126
|
+
result["5xx"] += h["statuses"]["5xx"]
|
127
|
+
result
|
128
|
+
end
|
134
129
|
end
|
135
130
|
|
136
131
|
def default_options
|
data/lib/ezmetrics/benchmark.rb
CHANGED
@@ -52,14 +52,14 @@ class EZmetrics::Benchmark
|
|
52
52
|
"all" => rand(40)
|
53
53
|
}
|
54
54
|
}
|
55
|
-
redis.setex(
|
55
|
+
redis.setex(second, seconds, Oj.dump(payload))
|
56
56
|
end
|
57
57
|
nil
|
58
58
|
end
|
59
59
|
|
60
60
|
def cleanup_metrics
|
61
61
|
interval_start = Time.now.to_i - intervals.values.max - 100
|
62
|
-
interval_keys = (interval_start..Time.now.to_i).to_a
|
62
|
+
interval_keys = (interval_start..Time.now.to_i).to_a
|
63
63
|
redis.del(interval_keys)
|
64
64
|
end
|
65
65
|
|