hitimes 2.0.0 → 3.0.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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +1 -1
- data/HISTORY.md +20 -3
- data/Manifest.txt +2 -17
- data/README.md +38 -43
- data/hitimes.gemspec +26 -0
- data/lib/hitimes/initialize.rb +83 -44
- data/lib/hitimes/instant.rb +9 -33
- data/lib/hitimes/interval.rb +15 -15
- data/lib/hitimes/metric.rb +18 -22
- data/lib/hitimes/mutexed_stats.rb +2 -4
- data/lib/hitimes/paths.rb +16 -14
- data/lib/hitimes/stats.rb +33 -33
- data/lib/hitimes/timed_metric.rb +43 -42
- data/lib/hitimes/timed_value_metric.rb +43 -43
- data/lib/hitimes/value_metric.rb +16 -15
- data/lib/hitimes/version.rb +3 -1
- data/lib/hitimes.rb +12 -11
- metadata +20 -113
- data/Rakefile +0 -19
- data/examples/benchmarks.rb +0 -113
- data/examples/stats.rb +0 -31
- data/spec/hitimes_spec.rb +0 -24
- data/spec/interval_spec.rb +0 -136
- data/spec/metric_spec.rb +0 -28
- data/spec/mutex_stats_spec.rb +0 -29
- data/spec/paths_spec.rb +0 -11
- data/spec/spec_helper.rb +0 -11
- data/spec/stats_spec.rb +0 -98
- data/spec/timed_metric_spec.rb +0 -155
- data/spec/timed_value_metric_spec.rb +0 -171
- data/spec/value_metric_spec.rb +0 -108
- data/spec/version_spec.rb +0 -7
- data/tasks/default.rake +0 -242
- data/tasks/this.rb +0 -208
- /data/{LICENSE → LICENSE.txt} +0 -0
data/lib/hitimes/metric.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
#--
|
3
4
|
# Copyright (c) 2008, 2009 Jeremy Hinegardner
|
@@ -13,15 +14,14 @@ module Hitimes
|
|
13
14
|
# * The name of the metric
|
14
15
|
# * The time of day the first measurement is taken
|
15
16
|
# * The time of day the last measurement is taken
|
16
|
-
# * additional data
|
17
|
+
# * additional data
|
17
18
|
#
|
18
19
|
# Each derived class is assumed to set the sampling_start_time and
|
19
20
|
# sampling_stop_time appropriately.
|
20
|
-
#
|
21
|
+
#
|
21
22
|
# Metric itself should generally not be used. Only use the derived classes.
|
22
23
|
#
|
23
24
|
class Metric
|
24
|
-
|
25
25
|
# the number of seconds as a float since the sampling_start_time
|
26
26
|
attr_reader :sampling_delta
|
27
27
|
|
@@ -41,7 +41,7 @@ module Hitimes
|
|
41
41
|
# +additional_data+ may be anything that follows the +to_hash+ protocol.
|
42
42
|
# +name+ may be anything that follows the +to_s+ protocol.
|
43
43
|
#
|
44
|
-
def initialize(
|
44
|
+
def initialize(name, additional_data = {})
|
45
45
|
@sampling_start_time = nil
|
46
46
|
@sampling_start_interval = nil
|
47
47
|
@sampling_delta = 0
|
@@ -51,7 +51,7 @@ module Hitimes
|
|
51
51
|
end
|
52
52
|
|
53
53
|
#
|
54
|
-
# :call-seq:
|
54
|
+
# :call-seq:
|
55
55
|
# metric.sampling_start_time -> Float or nil
|
56
56
|
#
|
57
57
|
# The time at which the first sample was taken.
|
@@ -60,11 +60,9 @@ module Hitimes
|
|
60
60
|
# If the metric has not started measuring then the start time is nil.
|
61
61
|
#
|
62
62
|
def sampling_start_time
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
nil
|
67
|
-
end
|
63
|
+
return unless @sampling_start_interval
|
64
|
+
|
65
|
+
@sampling_start_time ||= utc_microseconds
|
68
66
|
end
|
69
67
|
|
70
68
|
#
|
@@ -73,8 +71,8 @@ module Hitimes
|
|
73
71
|
#
|
74
72
|
# The time at which the last sample was taken
|
75
73
|
# This is the number of microseconds since UNIX epoch UTC as a Float
|
76
|
-
#
|
77
|
-
# If the metric has not completely measured at least one thing then
|
74
|
+
#
|
75
|
+
# If the metric has not completely measured at least one thing then
|
78
76
|
# stop time is nil.
|
79
77
|
#
|
80
78
|
# Because accessing the actual 'time of day' is an expesive operation, we
|
@@ -84,11 +82,9 @@ module Hitimes
|
|
84
82
|
# When sampling_stop_time is called, the actual time of day is caculated.
|
85
83
|
#
|
86
84
|
def sampling_stop_time
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
nil
|
91
|
-
end
|
85
|
+
return unless @sampling_delta.positive?
|
86
|
+
|
87
|
+
(sampling_start_time + (@sampling_delta * 1_000_000))
|
92
88
|
end
|
93
89
|
|
94
90
|
#
|
@@ -96,13 +92,13 @@ module Hitimes
|
|
96
92
|
# metric.to_hash -> Hash
|
97
93
|
# metric.to_hash
|
98
94
|
#
|
99
|
-
# Convert the metric to a Hash.
|
95
|
+
# Convert the metric to a Hash.
|
100
96
|
#
|
101
97
|
def to_hash
|
102
|
-
{
|
103
|
-
|
104
|
-
|
105
|
-
|
98
|
+
{ "sampling_start_time" => sampling_start_time,
|
99
|
+
"sampling_stop_time" => sampling_stop_time,
|
100
|
+
"additional_data" => additional_data,
|
101
|
+
"name" => name, }
|
106
102
|
end
|
107
103
|
|
108
104
|
#
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
4
|
# Copyright (c) 2008, 2009 Jeremy Hinegardner
|
3
5
|
# All rights reserved. See LICENSE and/or COPYING for details.
|
4
6
|
#++
|
5
7
|
|
6
|
-
require 'thread'
|
7
|
-
|
8
8
|
module Hitimes
|
9
9
|
#
|
10
10
|
# MutexedStats is the start of a threadsafe Stats class. Currently, on MRI
|
@@ -13,5 +13,3 @@ module Hitimes
|
|
13
13
|
#
|
14
14
|
MutexedStats = Stats
|
15
15
|
end
|
16
|
-
|
17
|
-
|
data/lib/hitimes/paths.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
4
|
# Copyright (c) 2008 Jeremy Hinegardner
|
3
5
|
# All rights reserved. See LICENSE and/or COPYING for details.
|
@@ -8,34 +10,34 @@ module Hitimes
|
|
8
10
|
# Access to various paths inside the project programatically
|
9
11
|
#
|
10
12
|
module Paths
|
11
|
-
#
|
13
|
+
#
|
12
14
|
# :call-seq:
|
13
15
|
# Hitimes::Paths.root_dir -> String
|
14
16
|
#
|
15
17
|
# Returns The full expanded path of the parent directory of +lib+
|
16
|
-
# going up the path from the current file. A trailing File::SEPARATOR
|
18
|
+
# going up the path from the current file. A trailing File::SEPARATOR
|
17
19
|
# is guaranteed.
|
18
|
-
#
|
20
|
+
#
|
19
21
|
def self.root_dir
|
20
|
-
@root_dir ||=
|
22
|
+
@root_dir ||= begin
|
21
23
|
path_parts = ::File.expand_path(__FILE__).split(::File::SEPARATOR)
|
22
24
|
lib_index = path_parts.rindex("lib")
|
23
25
|
@root_dir = path_parts[0...lib_index].join(::File::SEPARATOR) + ::File::SEPARATOR
|
24
|
-
|
25
|
-
end
|
26
|
+
end
|
27
|
+
end
|
26
28
|
|
27
|
-
#
|
29
|
+
#
|
28
30
|
# :call-seq:
|
29
31
|
# Hitimes::Paths.lib_path( *args ) -> String
|
30
32
|
#
|
31
33
|
# Returns The full expanded path of the +lib+ directory below
|
32
|
-
# _root_dir_. All parameters passed in are joined onto the
|
33
|
-
# result. A trailing File::SEPARATOR is guaranteed if
|
34
|
+
# _root_dir_. All parameters passed in are joined onto the
|
35
|
+
# result. A trailing File::SEPARATOR is guaranteed if
|
34
36
|
# _args_ are *not* present.
|
35
|
-
#
|
37
|
+
#
|
36
38
|
def self.lib_path(*args)
|
37
|
-
|
38
|
-
end
|
39
|
+
sub_path("lib", *args)
|
40
|
+
end
|
39
41
|
|
40
42
|
#
|
41
43
|
# :call-seq:
|
@@ -45,9 +47,9 @@ module Hitimes
|
|
45
47
|
# _arg_ parameters passed in are joined onto the result. A trailing
|
46
48
|
# File::SEPARATOR is guaranteed if _args_ are *not* present.
|
47
49
|
#
|
48
|
-
def self.sub_path(sub
|
50
|
+
def self.sub_path(sub, *args)
|
49
51
|
sp = ::File.join(root_dir, sub) + File::SEPARATOR
|
50
|
-
|
52
|
+
::File.join(sp, *args) if args
|
51
53
|
end
|
52
54
|
end
|
53
55
|
end
|
data/lib/hitimes/stats.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
4
|
# Copyright (c) 2008, 2009 Jeremy Hinegardner
|
3
5
|
# All rights reserved. See LICENSE and/or COPYING for details.
|
4
6
|
#++
|
5
7
|
|
6
|
-
require
|
7
|
-
require 'thread'
|
8
|
+
require "stringio"
|
8
9
|
module Hitimes
|
9
10
|
#
|
10
11
|
# The Stats class encapulsates capturing and reporting statistics. It is
|
11
12
|
# modeled after the RFuzz::Sampler class, but implemented in C. For general use
|
12
13
|
# you allocate a new Stats object, and then update it with new values. The
|
13
|
-
# Stats object will keep track of the _min_, _max_, _count_, _sum_ and _sumsq_
|
14
|
+
# Stats object will keep track of the _min_, _max_, _count_, _sum_ and _sumsq_
|
14
15
|
# and when you want you may also retrieve the _mean_, _stddev_ and _rate_.
|
15
16
|
#
|
16
17
|
# this contrived example shows getting a list of all the files in a directory
|
@@ -31,13 +32,9 @@ module Hitimes
|
|
31
32
|
#
|
32
33
|
class Stats
|
33
34
|
# A list of the available stats
|
34
|
-
STATS = %w[
|
35
|
+
STATS = %w[count max mean min rate stddev sum sumsq].freeze
|
35
36
|
|
36
|
-
attr_reader :min
|
37
|
-
attr_reader :max
|
38
|
-
attr_reader :count
|
39
|
-
attr_reader :sum
|
40
|
-
attr_reader :sumsq
|
37
|
+
attr_reader :min, :max, :count, :sum, :sumsq
|
41
38
|
|
42
39
|
def initialize
|
43
40
|
@mutex = Mutex.new
|
@@ -63,17 +60,18 @@ module Hitimes
|
|
63
60
|
@sumsq += (value * value)
|
64
61
|
end
|
65
62
|
|
66
|
-
|
63
|
+
value
|
67
64
|
end
|
68
65
|
|
69
66
|
# call-seq:
|
70
67
|
# stat.mean -> Float
|
71
|
-
#
|
68
|
+
#
|
72
69
|
# Return the arithmetic mean of the values put into the Stats object. If no
|
73
70
|
# values have passed through the stats object then 0.0 is returned;
|
74
71
|
def mean
|
75
72
|
return 0.0 if @count.zero?
|
76
|
-
|
73
|
+
|
74
|
+
@sum / @count
|
77
75
|
end
|
78
76
|
|
79
77
|
# call-seq:
|
@@ -91,7 +89,8 @@ module Hitimes
|
|
91
89
|
#
|
92
90
|
def rate
|
93
91
|
return 0.0 if @sum.zero?
|
94
|
-
|
92
|
+
|
93
|
+
@count / @sum
|
95
94
|
end
|
96
95
|
|
97
96
|
#
|
@@ -104,29 +103,30 @@ module Hitimes
|
|
104
103
|
#
|
105
104
|
def stddev
|
106
105
|
return 0.0 unless @count > 1
|
107
|
-
|
106
|
+
|
107
|
+
Math.sqrt((@sumsq - ((@sum * @sum) / @count)) / (@count - 1))
|
108
108
|
end
|
109
109
|
|
110
|
-
#
|
110
|
+
#
|
111
111
|
# call-seq:
|
112
112
|
# stat.to_hash -> Hash
|
113
113
|
# stat.to_hash( %w[ count max mean ]) -> Hash
|
114
114
|
#
|
115
115
|
# return a hash of the stats. By default this returns a hash of all stats
|
116
116
|
# but passing in an array of items will limit the stats returned to only
|
117
|
-
# those in the Array.
|
117
|
+
# those in the Array.
|
118
118
|
#
|
119
119
|
# If passed in an empty array or nil to to_hash then STATS is assumed to be
|
120
120
|
# the list of stats to return in the hash.
|
121
121
|
#
|
122
|
-
def to_hash(
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
122
|
+
def to_hash(*args)
|
123
|
+
result = {}
|
124
|
+
fields = [args].flatten
|
125
|
+
fields = STATS if fields.empty?
|
126
|
+
fields.each do |meth|
|
127
|
+
result[meth] = send(meth)
|
128
128
|
end
|
129
|
-
|
129
|
+
result
|
130
130
|
end
|
131
131
|
|
132
132
|
#
|
@@ -138,18 +138,18 @@ module Hitimes
|
|
138
138
|
# of all the stats. If an array of items is passed in, those that match the
|
139
139
|
# known stats will be all that is included in the json output.
|
140
140
|
#
|
141
|
-
def to_json(
|
142
|
-
|
143
|
-
|
144
|
-
|
141
|
+
def to_json(*args)
|
142
|
+
stats = to_hash(*args)
|
143
|
+
slugs = []
|
144
|
+
out = StringIO.new
|
145
145
|
|
146
|
-
|
147
|
-
|
148
|
-
|
146
|
+
out.print "{ "
|
147
|
+
stats.each_pair do |key, val|
|
148
|
+
slugs << "\"#{key}\": #{val}"
|
149
149
|
end
|
150
|
-
|
151
|
-
|
152
|
-
|
150
|
+
out.print slugs.join(", ")
|
151
|
+
out.print "}"
|
152
|
+
out.string
|
153
153
|
end
|
154
154
|
end
|
155
155
|
end
|
data/lib/hitimes/timed_metric.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
4
|
# Copyright (c) 2008, 2009 Jeremy Hinegardner
|
3
5
|
# All rights reserved. See LICENSE and/or COPYING for details.
|
4
6
|
#++
|
5
7
|
|
6
|
-
require
|
8
|
+
require "forwardable"
|
7
9
|
module Hitimes
|
8
10
|
#
|
9
11
|
# A TimedMetric holds the metrics on how long it takes to do something. For
|
@@ -11,11 +13,11 @@ module Hitimes
|
|
11
13
|
#
|
12
14
|
# tm = TimedMetric.new( 'my-method' )
|
13
15
|
#
|
14
|
-
# 200.times do
|
15
|
-
# my_method_result = tm.measure do
|
16
|
+
# 200.times do
|
17
|
+
# my_method_result = tm.measure do
|
16
18
|
# my_method( ... )
|
17
19
|
# end
|
18
|
-
# end
|
20
|
+
# end
|
19
21
|
#
|
20
22
|
# puts "#{ tm.name } operated at a rate of #{ tm.rate } calls per second"
|
21
23
|
#
|
@@ -23,9 +25,9 @@ module Hitimes
|
|
23
25
|
# Metric API also.
|
24
26
|
#
|
25
27
|
# A TimedMetric measures the execution time of an option with the Interval
|
26
|
-
# class.
|
27
|
-
#
|
28
|
-
# A TimedMetric contains a Stats object, therefore TimedMetric has +count+, +max+,
|
28
|
+
# class.
|
29
|
+
#
|
30
|
+
# A TimedMetric contains a Stats object, therefore TimedMetric has +count+, +max+,
|
29
31
|
# +mean+, +min+, +rate+, +stddev+, +sum+, +sumsq+ methods that delegate to that Stats
|
30
32
|
# object for convenience.
|
31
33
|
#
|
@@ -41,10 +43,10 @@ module Hitimes
|
|
41
43
|
#
|
42
44
|
# Return a TimedMetric that has been started
|
43
45
|
#
|
44
|
-
def now(
|
45
|
-
|
46
|
-
|
47
|
-
|
46
|
+
def now(name, additional_data = {})
|
47
|
+
tm = TimedMetric.new(name, additional_data)
|
48
|
+
tm.start
|
49
|
+
tm
|
48
50
|
end
|
49
51
|
end
|
50
52
|
|
@@ -56,8 +58,8 @@ module Hitimes
|
|
56
58
|
# Create a new TimedMetric giving it a name and additional data.
|
57
59
|
# +additional_data+ may be anything that follows the +to_hash+ protocol
|
58
60
|
#
|
59
|
-
def initialize(
|
60
|
-
super(
|
61
|
+
def initialize(name, additional_data = {})
|
62
|
+
super(name, additional_data)
|
61
63
|
@stats = Stats.new
|
62
64
|
@current_interval = Interval.new
|
63
65
|
end
|
@@ -66,23 +68,23 @@ module Hitimes
|
|
66
68
|
# :call-seq:
|
67
69
|
# timed_metric.running? -> true or false
|
68
70
|
#
|
69
|
-
# return whether or not the timer is currently running.
|
71
|
+
# return whether or not the timer is currently running.
|
70
72
|
#
|
71
73
|
def running?
|
72
74
|
@current_interval.running?
|
73
75
|
end
|
74
76
|
|
75
|
-
#
|
77
|
+
#
|
76
78
|
# :call-seq:
|
77
79
|
# timed_metric.start -> nil
|
78
80
|
#
|
79
81
|
# Start the current metric, if the current metric is already started, then
|
80
|
-
# this is a noop.
|
82
|
+
# this is a noop.
|
81
83
|
#
|
82
84
|
def start
|
83
|
-
|
84
|
-
@current_interval.start
|
85
|
-
@sampling_start_time ||=
|
85
|
+
unless @current_interval.running?
|
86
|
+
@current_interval.start
|
87
|
+
@sampling_start_time ||= utc_microseconds
|
86
88
|
@sampling_start_interval ||= Interval.now
|
87
89
|
end
|
88
90
|
nil
|
@@ -96,19 +98,19 @@ module Hitimes
|
|
96
98
|
# interval. If the timer was stopped then the duration of the last Interval
|
97
99
|
# is returned. If the timer was already stopped then false is returned and
|
98
100
|
# no stats are updated.
|
99
|
-
#
|
101
|
+
#
|
100
102
|
def stop
|
101
|
-
if @current_interval.running?
|
102
|
-
|
103
|
-
@stats.update(
|
103
|
+
if @current_interval.running?
|
104
|
+
duration = @current_interval.stop
|
105
|
+
@stats.update(duration)
|
104
106
|
@current_interval = Interval.new
|
105
107
|
|
106
108
|
# update the length of time we have been sampling
|
107
109
|
@sampling_delta = @sampling_start_interval.duration_so_far
|
108
110
|
|
109
|
-
return
|
111
|
+
return duration
|
110
112
|
end
|
111
|
-
|
113
|
+
false
|
112
114
|
end
|
113
115
|
|
114
116
|
#
|
@@ -118,7 +120,7 @@ module Hitimes
|
|
118
120
|
# Measure the execution of a block and add those stats to the running stats.
|
119
121
|
# The return value is the return value of the block
|
120
122
|
#
|
121
|
-
def measure
|
123
|
+
def measure
|
122
124
|
return_value = nil
|
123
125
|
begin
|
124
126
|
start
|
@@ -126,7 +128,7 @@ module Hitimes
|
|
126
128
|
ensure
|
127
129
|
stop
|
128
130
|
end
|
129
|
-
|
131
|
+
return_value
|
130
132
|
end
|
131
133
|
|
132
134
|
#
|
@@ -142,35 +144,34 @@ module Hitimes
|
|
142
144
|
# interval, i.e. the split-time. If the timer is not running, nothing
|
143
145
|
# happens and false is returned.
|
144
146
|
#
|
145
|
-
def split
|
146
|
-
if @current_interval.running?
|
147
|
+
def split
|
148
|
+
if @current_interval.running?
|
147
149
|
next_interval = @current_interval.split
|
148
|
-
|
149
|
-
@stats.update(
|
150
|
-
@current_interval = next_interval
|
151
|
-
return
|
152
|
-
end
|
153
|
-
|
150
|
+
duration = @current_interval.duration
|
151
|
+
@stats.update(duration)
|
152
|
+
@current_interval = next_interval
|
153
|
+
return duration
|
154
|
+
end
|
155
|
+
false
|
154
156
|
end
|
155
157
|
|
156
158
|
#
|
157
159
|
# :call-seq:
|
158
160
|
# metric.to_hash -> Hash
|
159
|
-
#
|
161
|
+
#
|
160
162
|
# Convert the metric to a hash
|
161
163
|
#
|
162
164
|
def to_hash
|
163
|
-
|
164
|
-
Stats::STATS.each do |
|
165
|
-
|
165
|
+
result = super
|
166
|
+
Stats::STATS.each do |stat|
|
167
|
+
result[stat] = send(stat)
|
166
168
|
end
|
167
|
-
|
169
|
+
result
|
168
170
|
end
|
169
171
|
|
170
|
-
|
171
172
|
# forward appropriate calls directly to the stats object
|
172
173
|
extend Forwardable
|
173
174
|
def_delegators :@stats, :count, :max, :mean, :min, :rate, :stddev, :sum, :sumsq
|
174
|
-
alias
|
175
|
+
alias duration sum
|
175
176
|
end
|
176
177
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#--
|
2
4
|
# Copyright (c) 2008, 2009 Jeremy Hinegardner
|
3
5
|
# All rights reserved. See LICENSE and/or COPYING for details.
|
@@ -10,7 +12,7 @@ module Hitimes
|
|
10
12
|
#
|
11
13
|
# tm = TimedValueMetric.new( 'my-batch-method' )
|
12
14
|
#
|
13
|
-
# 42.times do
|
15
|
+
# 42.times do
|
14
16
|
# tm.start
|
15
17
|
# number_of_items_processed = do_something
|
16
18
|
# tm.stop( number_of_items_processed )
|
@@ -40,10 +42,10 @@ module Hitimes
|
|
40
42
|
#
|
41
43
|
# Return a TimedValueMetric that has been started
|
42
44
|
#
|
43
|
-
def now(
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
def now(name, additional_data = {})
|
46
|
+
tvm = TimedValueMetric.new(name, additional_data)
|
47
|
+
tvm.start
|
48
|
+
tvm
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
@@ -55,8 +57,8 @@ module Hitimes
|
|
55
57
|
# Create a new TimedValueMetric giving it a name and additional data.
|
56
58
|
# +additional_data+ may be anything that follows the +to_hash+ protocol
|
57
59
|
#
|
58
|
-
def initialize(
|
59
|
-
super(
|
60
|
+
def initialize(name, additional_data = {})
|
61
|
+
super(name, additional_data)
|
60
62
|
@timed_stats = Stats.new
|
61
63
|
@value_stats = Stats.new
|
62
64
|
@current_interval = Interval.new
|
@@ -72,17 +74,17 @@ module Hitimes
|
|
72
74
|
@current_interval.running?
|
73
75
|
end
|
74
76
|
|
75
|
-
#
|
77
|
+
#
|
76
78
|
# :call-seq:
|
77
79
|
# timed_value_metric.start -> nil
|
78
80
|
#
|
79
81
|
# Start the current timer, if the current timer is already started, then
|
80
|
-
# this is a noop.
|
82
|
+
# this is a noop.
|
81
83
|
#
|
82
84
|
def start
|
83
|
-
|
85
|
+
unless @current_interval.running?
|
84
86
|
@current_interval.start
|
85
|
-
@sampling_start_time ||=
|
87
|
+
@sampling_start_time ||= utc_microseconds
|
86
88
|
@sampling_start_interval ||= Interval.now
|
87
89
|
end
|
88
90
|
nil
|
@@ -101,21 +103,21 @@ module Hitimes
|
|
101
103
|
# the current interval. If the metric is stopped then the duration of the
|
102
104
|
# last Interval is returned. If the metric was already stopped before this
|
103
105
|
# call, then false is returned and no stats are updated.
|
104
|
-
#
|
105
106
|
#
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
@
|
107
|
+
#
|
108
|
+
def stop(value)
|
109
|
+
if @current_interval.running?
|
110
|
+
duration = @current_interval.stop
|
111
|
+
@timed_stats.update(duration)
|
110
112
|
@current_interval = Interval.new
|
111
|
-
@value_stats.update(
|
113
|
+
@value_stats.update(value)
|
112
114
|
|
113
115
|
# update the lenght of time we have been sampling
|
114
116
|
@sampling_delta = @sampling_start_interval.duration_so_far
|
115
117
|
|
116
|
-
return
|
118
|
+
return duration
|
117
119
|
end
|
118
|
-
|
120
|
+
false
|
119
121
|
end
|
120
122
|
|
121
123
|
#
|
@@ -126,15 +128,15 @@ module Hitimes
|
|
126
128
|
# The return value is the return value of the block. A value must be passed
|
127
129
|
# into +measure+ to update the +value_stats+ portion of the TimedValueMetric.
|
128
130
|
#
|
129
|
-
def measure(
|
131
|
+
def measure(value)
|
130
132
|
return_value = nil
|
131
133
|
begin
|
132
134
|
start
|
133
135
|
return_value = yield
|
134
136
|
ensure
|
135
|
-
stop(
|
137
|
+
stop(value)
|
136
138
|
end
|
137
|
-
|
139
|
+
return_value
|
138
140
|
end
|
139
141
|
|
140
142
|
#
|
@@ -148,19 +150,19 @@ module Hitimes
|
|
148
150
|
#
|
149
151
|
# If the metric is running, then split returns the duration of the previous
|
150
152
|
# interval, i.e. the split-time. If the metric is not running, nothing
|
151
|
-
# happens, no stats are updated, and false is returned.
|
153
|
+
# happens, no stats are updated, and false is returned.
|
152
154
|
#
|
153
155
|
#
|
154
|
-
def split(
|
155
|
-
if @current_interval.running?
|
156
|
+
def split(value)
|
157
|
+
if @current_interval.running?
|
156
158
|
next_interval = @current_interval.split
|
157
|
-
|
158
|
-
@timed_stats.update(
|
159
|
-
@value_stats.update(
|
160
|
-
@current_interval = next_interval
|
161
|
-
return
|
162
|
-
end
|
163
|
-
|
159
|
+
duration = @current_interval.duration
|
160
|
+
@timed_stats.update(duration)
|
161
|
+
@value_stats.update(value)
|
162
|
+
@current_interval = next_interval
|
163
|
+
return duration
|
164
|
+
end
|
165
|
+
false
|
164
166
|
end
|
165
167
|
|
166
168
|
#
|
@@ -192,7 +194,7 @@ module Hitimes
|
|
192
194
|
# associated with a quantity of things done during that unit of time. So
|
193
195
|
# the +rate+ for a TimedValueMetric is the (sum of all quantities sampled) /
|
194
196
|
# ( sum of all durations measured )
|
195
|
-
#
|
197
|
+
#
|
196
198
|
# For example, say you were measuring, using a TimedValueMetric batch jobs
|
197
199
|
# that had individual units of work.
|
198
200
|
#
|
@@ -208,7 +210,7 @@ module Hitimes
|
|
208
210
|
# At this point the rate of units per second is calculated as ( 12 + 42 ) / ( duration1 + duration2 )
|
209
211
|
#
|
210
212
|
# some_batch_rate = tvm.rate # returns ( 34 / ( duration1+duration2 ) )
|
211
|
-
#
|
213
|
+
#
|
212
214
|
def rate
|
213
215
|
@value_stats.sum / @timed_stats.sum
|
214
216
|
end
|
@@ -216,18 +218,16 @@ module Hitimes
|
|
216
218
|
#
|
217
219
|
# :call-seq:
|
218
220
|
# metric.to_hash -> Hash
|
219
|
-
#
|
221
|
+
#
|
220
222
|
# Convert the metric to a hash
|
221
223
|
#
|
222
224
|
def to_hash
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
225
|
+
result = super
|
226
|
+
result["timed_stats"] = @timed_stats.to_hash
|
227
|
+
result["value_stats"] = @value_stats.to_hash(Stats::STATS - %w[rate])
|
228
|
+
result["rate"] = rate
|
229
|
+
result["unit_count"] = unit_count
|
230
|
+
result
|
229
231
|
end
|
230
|
-
|
231
|
-
|
232
232
|
end
|
233
233
|
end
|