hitimes 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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( name, additional_data = {} )
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
- if @sampling_start_interval then
64
- @sampling_start_time ||= self.utc_microseconds()
65
- else
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
- if @sampling_delta > 0 then
88
- (self.sampling_start_time + (@sampling_delta * 1_000_000))
89
- else
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
- { 'sampling_start_time' => self.sampling_start_time,
103
- 'sampling_stop_time' => self.sampling_stop_time,
104
- 'additional_data' => self.additional_data,
105
- 'name' => self.name }
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
- self.sub_path("lib", *args)
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,*args)
50
+ def self.sub_path(sub, *args)
49
51
  sp = ::File.join(root_dir, sub) + File::SEPARATOR
50
- sp = ::File.join(sp, *args) if args
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 'stringio'
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[ count max mean min rate stddev sum sumsq ]
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
- return value
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
- return @sum / @count
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
- return @count / @sum
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
- Math.sqrt((@sumsq - ((@sum * @sum)/@count)) / (@count - 1))
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( *args )
123
- h = {}
124
- args = [ args ].flatten
125
- args = STATS if args.empty?
126
- args.each do |meth|
127
- h[meth] = self.send( meth )
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
- return h
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( *args )
142
- h = to_hash( *args )
143
- a = []
144
- s = StringIO.new
141
+ def to_json(*args)
142
+ stats = to_hash(*args)
143
+ slugs = []
144
+ out = StringIO.new
145
145
 
146
- s.print "{ "
147
- h.each_pair do |k,v|
148
- a << "\"#{k}\": #{v}"
146
+ out.print "{ "
147
+ stats.each_pair do |key, val|
148
+ slugs << "\"#{key}\": #{val}"
149
149
  end
150
- s.print a.join(", ")
151
- s.print "}"
152
- return s.string
150
+ out.print slugs.join(", ")
151
+ out.print "}"
152
+ out.string
153
153
  end
154
154
  end
155
155
  end
@@ -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 'forwardable'
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( name, additional_data = {} )
45
- t = TimedMetric.new( name, additional_data )
46
- t.start
47
- return t
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( name, additional_data = {} )
60
- super( name, additional_data )
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
- if not @current_interval.running? then
84
- @current_interval.start
85
- @sampling_start_time ||= self.utc_microseconds()
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? then
102
- d = @current_interval.stop
103
- @stats.update( d )
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 d
111
+ return duration
110
112
  end
111
- return false
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( &block )
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
- return return_value
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? then
147
+ def split
148
+ if @current_interval.running?
147
149
  next_interval = @current_interval.split
148
- d = @current_interval.duration
149
- @stats.update( d )
150
- @current_interval = next_interval
151
- return d
152
- end
153
- return false
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
- h = super
164
- Stats::STATS.each do |s|
165
- h[s] = self.send( s )
165
+ result = super
166
+ Stats::STATS.each do |stat|
167
+ result[stat] = send(stat)
166
168
  end
167
- return h
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 :duration :sum
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( name, additional_data = {} )
44
- t = TimedValueMetric.new( name, additional_data )
45
- t.start
46
- return t
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( name, additional_data = {} )
59
- super( name, additional_data )
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
- if not @current_interval.running? then
85
+ unless @current_interval.running?
84
86
  @current_interval.start
85
- @sampling_start_time ||= self.utc_microseconds()
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
- def stop( value )
107
- if @current_interval.running? then
108
- d = @current_interval.stop
109
- @timed_stats.update( d )
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( value )
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 d
118
+ return duration
117
119
  end
118
- return false
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( value, &block )
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( value )
137
+ stop(value)
136
138
  end
137
- return return_value
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( value )
155
- if @current_interval.running? then
156
+ def split(value)
157
+ if @current_interval.running?
156
158
  next_interval = @current_interval.split
157
- d = @current_interval.duration
158
- @timed_stats.update( d )
159
- @value_stats.update( value )
160
- @current_interval = next_interval
161
- return d
162
- end
163
- return false
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
- h = super
224
- h['timed_stats'] = @timed_stats.to_hash
225
- h['value_stats'] = @value_stats.to_hash( Stats::STATS - %w[ rate ] )
226
- h['rate'] = self.rate
227
- h['unit_count'] = self.unit_count
228
- return h
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