babysitter 0.0.2 → 0.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.
- data/README.md +1 -1
- data/babysitter.gemspec +1 -0
- data/lib/babysitter.rb +5 -4
- data/lib/babysitter/{progress_counter.rb → counter.rb} +16 -13
- data/lib/babysitter/monitor.rb +56 -0
- data/lib/babysitter/progress.rb +31 -36
- data/lib/babysitter/version.rb +1 -1
- data/spec/lib/babysitter/{progress_spec.rb → monitor_spec.rb} +72 -10
- data/spec/lib/babysitter_spec.rb +41 -0
- data/spec/spec_helper.rb +1 -1
- metadata +25 -6
data/README.md
CHANGED
data/babysitter.gemspec
CHANGED
@@ -17,6 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
19
|
gem.add_dependency 'fozzie'
|
20
|
+
gem.add_dependency 'timecop'
|
20
21
|
|
21
22
|
gem.add_development_dependency 'awesome_print'
|
22
23
|
gem.add_development_dependency 'rspec'
|
data/lib/babysitter.rb
CHANGED
@@ -4,14 +4,15 @@ require_relative "babysitter/version"
|
|
4
4
|
require_relative "babysitter/null_logger"
|
5
5
|
require_relative "babysitter/configuration"
|
6
6
|
require_relative "babysitter/logging"
|
7
|
-
require_relative "babysitter/progress_counter"
|
8
7
|
require_relative "babysitter/progress"
|
9
|
-
|
8
|
+
require_relative "babysitter/monitor"
|
9
|
+
require_relative "babysitter/counter"
|
10
|
+
require 'fozzie'
|
10
11
|
|
11
12
|
module Babysitter
|
12
13
|
|
13
14
|
def self.monitor(*args)
|
14
|
-
|
15
|
+
Monitor.new(*args)
|
15
16
|
end
|
16
17
|
|
17
18
|
def self.configuration
|
@@ -27,4 +28,4 @@ module Babysitter
|
|
27
28
|
end
|
28
29
|
|
29
30
|
|
30
|
-
end
|
31
|
+
end
|
@@ -1,16 +1,17 @@
|
|
1
1
|
module Babysitter
|
2
|
-
class
|
2
|
+
class Counter
|
3
3
|
include Logging
|
4
4
|
|
5
|
-
attr_reader :count, :
|
6
|
-
attr_accessor :log_every
|
5
|
+
attr_reader :count, :log_every, :template, :logged_count, :stat_name, :counting
|
7
6
|
|
8
|
-
|
7
|
+
attr_accessor :template
|
8
|
+
|
9
|
+
def initialize(log_every, opts)
|
9
10
|
@count = 0
|
10
11
|
@logged_count = 0
|
11
|
-
@stat_name = stat_name
|
12
|
-
@counting = :iterations
|
13
12
|
@log_every = log_every
|
13
|
+
@stat_name = opts.delete(:stat_name)
|
14
|
+
@counting = opts.delete(:counting)
|
14
15
|
@timer_start = Time.now
|
15
16
|
end
|
16
17
|
|
@@ -23,16 +24,14 @@ module Babysitter
|
|
23
24
|
log_counter_messsage if log_this_time
|
24
25
|
end
|
25
26
|
|
26
|
-
def final_report
|
27
|
-
log_counter_messsage if !(template.nil? or template.empty?) && count != logged_count
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
27
|
def block_number(count)
|
33
28
|
count / @log_every
|
34
29
|
end
|
35
30
|
|
31
|
+
def final_report?
|
32
|
+
!(template.nil? or template.empty?) && count != logged_count
|
33
|
+
end
|
34
|
+
|
36
35
|
def log_counter_messsage
|
37
36
|
logger.info( "Done: #{template.gsub("{{count}}", count.to_s)}" )
|
38
37
|
send_progress_stats(count - logged_count)
|
@@ -53,5 +52,9 @@ module Babysitter
|
|
53
52
|
Stats.count stat_name+[counting, :progress], progress unless stat_name.nil?
|
54
53
|
end
|
55
54
|
|
55
|
+
def send_total_stats
|
56
|
+
Stats.gauge stat_name+[counting, :total], count
|
57
|
+
end
|
58
|
+
|
56
59
|
end
|
57
|
-
end
|
60
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Babysitter
|
2
|
+
class Monitor
|
3
|
+
include Logging
|
4
|
+
|
5
|
+
attr_accessor :stat_name
|
6
|
+
|
7
|
+
def initialize(stat_name=nil)
|
8
|
+
@stat_name = convert_stat_name_to_array(stat_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
def start(msg=nil, log_every=100, &blk)
|
12
|
+
raise ArgumentError, "Stats bucket name must not be blank" if stat_name.nil? or stat_name.empty?
|
13
|
+
log_msg = format_log_message(msg)
|
14
|
+
progress = Progress.new(log_every, stat_name)
|
15
|
+
logger.info "Start: #{log_msg}"
|
16
|
+
|
17
|
+
begin
|
18
|
+
result = Stats.time_to_do stat_name+[:overall] do
|
19
|
+
blk.call(progress)
|
20
|
+
end
|
21
|
+
rescue Exception => e
|
22
|
+
progress.final_report rescue nil
|
23
|
+
log_exception_details( log_msg, e )
|
24
|
+
raise
|
25
|
+
end
|
26
|
+
|
27
|
+
progress.send_total_stats
|
28
|
+
progress.final_report
|
29
|
+
logger.info "End: #{log_msg}"
|
30
|
+
result
|
31
|
+
end
|
32
|
+
|
33
|
+
def completed(msg)
|
34
|
+
logger.info "Done: #{msg}"
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def format_log_message(msg)
|
40
|
+
log_msg = stat_name.join('.')
|
41
|
+
[log_msg,msg].compact.join(' ')
|
42
|
+
end
|
43
|
+
|
44
|
+
def convert_stat_name_to_array(stat_name)
|
45
|
+
stat_name.is_a?(Array) ? stat_name : stat_name.split('.') unless stat_name.nil? or stat_name.empty?
|
46
|
+
end
|
47
|
+
|
48
|
+
def log_exception_details( msg, exception )
|
49
|
+
logger.error "Aborting: #{msg} due to exception #{exception.class}: #{exception}"
|
50
|
+
if exception.backtrace
|
51
|
+
exception.backtrace.each { |line| logger.error " #{line}" }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/lib/babysitter/progress.rb
CHANGED
@@ -2,56 +2,51 @@ module Babysitter
|
|
2
2
|
class Progress
|
3
3
|
include Logging
|
4
4
|
|
5
|
-
|
5
|
+
attr_reader :counting, :stat_name, :counter
|
6
|
+
attr_accessor :log_every
|
7
|
+
|
8
|
+
def initialize(log_every, stat_name=nil)
|
9
|
+
@stat_name = stat_name
|
10
|
+
@counting = :iterations
|
11
|
+
@log_every = log_every
|
12
|
+
@counter = Counter.new(log_every, stat_name: stat_name, counting: counting)
|
13
|
+
end
|
14
|
+
|
15
|
+
def inc(*args)
|
16
|
+
counter.inc(*args)
|
17
|
+
end
|
6
18
|
|
7
|
-
def
|
8
|
-
|
19
|
+
def count
|
20
|
+
counter.count
|
9
21
|
end
|
10
22
|
|
11
|
-
def
|
12
|
-
|
13
|
-
|
14
|
-
counter = ProgressCounter.new(log_every, stat_name)
|
15
|
-
logger.info "Start: #{log_msg}"
|
23
|
+
def final_report
|
24
|
+
counter.log_counter_messsage if counter.final_report?
|
25
|
+
end
|
16
26
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
rescue Exception => e
|
22
|
-
counter.final_report rescue nil
|
23
|
-
log_exception_details( log_msg, e )
|
24
|
-
raise
|
25
|
-
end
|
27
|
+
def warn(partial_bucket_name, message)
|
28
|
+
logger.warn(message)
|
29
|
+
send_warning_stat(partial_bucket_name)
|
30
|
+
end
|
26
31
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
result
|
32
|
+
def error(partial_bucket_name, message)
|
33
|
+
logger.error(message)
|
34
|
+
send_error_stat(partial_bucket_name)
|
31
35
|
end
|
32
36
|
|
33
|
-
def
|
34
|
-
|
37
|
+
def send_total_stats
|
38
|
+
counter.send_total_stats
|
35
39
|
end
|
36
40
|
|
37
41
|
private
|
38
42
|
|
39
|
-
def
|
40
|
-
|
41
|
-
[log_msg,msg].compact.join(' ')
|
43
|
+
def send_warning_stat(partial_bucket_name)
|
44
|
+
Stats.increment stat_name+[partial_bucket_name, :warnings] unless stat_name.nil?
|
42
45
|
end
|
43
46
|
|
44
|
-
def
|
45
|
-
|
47
|
+
def send_error_stat(partial_bucket_name)
|
48
|
+
Stats.increment stat_name+[partial_bucket_name, :errors] unless stat_name.nil?
|
46
49
|
end
|
47
50
|
|
48
|
-
def log_exception_details( msg, exception )
|
49
|
-
logger.error "Aborting: #{msg} due to exception #{exception.class}: #{exception}"
|
50
|
-
if exception.backtrace
|
51
|
-
exception.backtrace.each { |line| Babysitter.logger.error " #{line}" }
|
52
|
-
end
|
53
|
-
end
|
54
51
|
end
|
55
|
-
|
56
|
-
|
57
52
|
end
|
data/lib/babysitter/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module Babysitter
|
4
|
-
describe
|
4
|
+
describe Monitor do
|
5
5
|
before(:each) do
|
6
6
|
Stats.stub!(:count).with(anything, anything)
|
7
7
|
Stats.stub!(:gauge).with(anything, anything)
|
@@ -9,7 +9,7 @@ module Babysitter
|
|
9
9
|
|
10
10
|
context 'when initialized with a dot separated bucket name' do
|
11
11
|
|
12
|
-
subject{
|
12
|
+
subject{ Monitor.new(bucket_name) }
|
13
13
|
let(:bucket_name) { 'my.splendid.bucket.name' }
|
14
14
|
let(:start_block) { Proc.new{ block_result } }
|
15
15
|
let(:block_result) { double('block result').as_null_object }
|
@@ -17,7 +17,7 @@ module Babysitter
|
|
17
17
|
|
18
18
|
describe '#completed' do
|
19
19
|
it 'logs a done message' do
|
20
|
-
|
20
|
+
Monitor.any_instance.stub(:logger).and_return(logger)
|
21
21
|
logger.should_receive(:info).with("Done: the completed thing")
|
22
22
|
subject.completed('the completed thing')
|
23
23
|
end
|
@@ -36,26 +36,26 @@ module Babysitter
|
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'calls logger.info with start message' do
|
39
|
-
|
39
|
+
Monitor.any_instance.stub(:logger).and_return(logger)
|
40
40
|
logger.should_receive(:info).with("Start: #{bucket_name}")
|
41
41
|
subject.start(&start_block)
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'calls logger.info with end message' do
|
45
|
-
|
45
|
+
Monitor.any_instance.stub(:logger).and_return(logger)
|
46
46
|
logger.should_receive(:info).with("End: #{bucket_name}")
|
47
47
|
subject.start(&start_block)
|
48
48
|
end
|
49
49
|
|
50
50
|
context 'when the start method is given a message' do
|
51
51
|
it 'calls logger.info with start message' do
|
52
|
-
|
52
|
+
Monitor.any_instance.stub(:logger).and_return(logger)
|
53
53
|
logger.should_receive(:info).with("Start: #{bucket_name} special message")
|
54
54
|
subject.start('special message', &start_block)
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'calls logger.info with end message' do
|
58
|
-
|
58
|
+
Monitor.any_instance.stub(:logger).and_return(logger)
|
59
59
|
logger.should_receive(:info).with("End: #{bucket_name} special message")
|
60
60
|
subject.start('special message', &start_block)
|
61
61
|
end
|
@@ -75,7 +75,7 @@ module Babysitter
|
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'calls logger.info with each done message once' do
|
78
|
-
|
78
|
+
Counter.any_instance.stub(:logger).and_return(logger)
|
79
79
|
[5,10].each { |inc| logger.should_receive(:info).with( "Done: incrementing by #{inc} things").once }
|
80
80
|
subject.start('short message', 5, &start_block_two_increments)
|
81
81
|
end
|
@@ -95,7 +95,7 @@ module Babysitter
|
|
95
95
|
end
|
96
96
|
|
97
97
|
it 'calls logger.info with each done message once' do
|
98
|
-
|
98
|
+
Counter.any_instance.stub(:logger).and_return(logger)
|
99
99
|
[5,7].each { |inc| logger.should_receive(:info).with( "Done: incrementing by #{inc} things").once }
|
100
100
|
subject.start('short message', 5, &start_block_seven_increments)
|
101
101
|
end
|
@@ -109,12 +109,74 @@ module Babysitter
|
|
109
109
|
end
|
110
110
|
|
111
111
|
it 'calls logger.info with increments 18,27,36,45,54,63' do
|
112
|
-
|
112
|
+
Counter.any_instance.stub(:logger).and_return(logger)
|
113
113
|
[18,27,36,45,54,63].each { |inc| logger.should_receive(:info).with( "Done: incrementing by #{inc} things").once }
|
114
114
|
subject.start('short message', 10, &start_block_three_increments)
|
115
115
|
end
|
116
116
|
end # context 'when logging every 10th call, and the block increments the counter 7 times, each with a count of 9, and identifies counted objects' do
|
117
117
|
|
118
|
+
context "when the block logs a warning" do
|
119
|
+
let(:start_block_with_warning) do
|
120
|
+
Proc.new do |monitor|
|
121
|
+
monitor.warn(:my_warning_bucket, 'my warning message')
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'calls logger.info with the warning message' do
|
126
|
+
Progress.any_instance.stub(:logger).and_return(logger)
|
127
|
+
logger.should_receive(:warn).with( "my warning message")
|
128
|
+
Stats.stub!(:increment)
|
129
|
+
subject.start(&start_block_with_warning)
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'calls Stats.count with warning bucket name' do
|
133
|
+
expected_bucket_name = bucket_name.split('.') + [:my_warning_bucket, :warnings]
|
134
|
+
Stats.should_receive(:increment).with(expected_bucket_name)
|
135
|
+
subject.start(&start_block_with_warning)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "when the block logs an error" do
|
140
|
+
let(:start_block_with_error) do
|
141
|
+
Proc.new do |monitor|
|
142
|
+
monitor.error(:my_error_bucket, 'my error message')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'calls logger.error with the error message' do
|
147
|
+
Progress.any_instance.stub(:logger).and_return(logger)
|
148
|
+
logger.should_receive(:error).with( "my error message")
|
149
|
+
Stats.stub!(:increment)
|
150
|
+
subject.start(&start_block_with_error)
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'calls Stats.count with error bucket name' do
|
154
|
+
expected_bucket_name = bucket_name.split('.') + [:my_error_bucket, :errors]
|
155
|
+
Stats.should_receive(:increment).with(expected_bucket_name)
|
156
|
+
subject.start(&start_block_with_error)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'when the block increments 2 times at intervals of 2 seconds' do
|
161
|
+
let(:start_block_for_timing) do
|
162
|
+
Proc.new do |counter|
|
163
|
+
2.times do
|
164
|
+
Timecop.travel(Time.now+2) # move on 2 seconds
|
165
|
+
counter.inc('doing increment',1)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
before(:each) { Timecop.travel(Time.now) }
|
170
|
+
after(:each) { Timecop.return }
|
171
|
+
|
172
|
+
it 'calculates a rate close to 0.5 per second' do
|
173
|
+
Counter.any_instance.should_receive(:send_rate_stats) do |rate|
|
174
|
+
rate.should be_within(0.01).of(0.5)
|
175
|
+
end
|
176
|
+
subject.start(&start_block_for_timing)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
118
180
|
end
|
119
181
|
|
120
182
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Babysitter do
|
4
|
+
|
5
|
+
describe '.monitor' do
|
6
|
+
it 'returns an instance of Monitor' do
|
7
|
+
Babysitter.monitor.should be_an_instance_of(Babysitter::Monitor)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '.configuration' do
|
12
|
+
it 'returns an instance of Configuration' do
|
13
|
+
Babysitter.configuration.should be_an_instance_of(Babysitter::Configuration)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'returns the same instance every time' do
|
17
|
+
c = Babysitter.configuration
|
18
|
+
Babysitter.configuration.should eql(c)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '.configure' do
|
23
|
+
describe 'object yielded to block' do
|
24
|
+
it 'is the unique configuration object' do
|
25
|
+
Babysitter.configure do |c|
|
26
|
+
c.should eql(Babysitter.configuration)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '.logger' do
|
33
|
+
let(:configured_logger) { double('configured logger').as_null_object }
|
34
|
+
|
35
|
+
it 'returns the logger from the configuration' do
|
36
|
+
Babysitter::Configuration.any_instance.stub(:logger).and_return(configured_logger)
|
37
|
+
Babysitter.logger.should eql(configured_logger)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: babysitter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-01-
|
14
|
+
date: 2013-01-23 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: fozzie
|
@@ -29,6 +29,22 @@ dependencies:
|
|
29
29
|
- - ! '>='
|
30
30
|
- !ruby/object:Gem::Version
|
31
31
|
version: '0'
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
name: timecop
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
none: false
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
32
48
|
- !ruby/object:Gem::Dependency
|
33
49
|
name: awesome_print
|
34
50
|
requirement: !ruby/object:Gem::Requirement
|
@@ -78,13 +94,15 @@ files:
|
|
78
94
|
- babysitter.gemspec
|
79
95
|
- lib/babysitter.rb
|
80
96
|
- lib/babysitter/configuration.rb
|
97
|
+
- lib/babysitter/counter.rb
|
81
98
|
- lib/babysitter/logging.rb
|
99
|
+
- lib/babysitter/monitor.rb
|
82
100
|
- lib/babysitter/null_logger.rb
|
83
101
|
- lib/babysitter/progress.rb
|
84
|
-
- lib/babysitter/progress_counter.rb
|
85
102
|
- lib/babysitter/version.rb
|
86
103
|
- spec/lib/babysitter/configuration_spec.rb
|
87
|
-
- spec/lib/babysitter/
|
104
|
+
- spec/lib/babysitter/monitor_spec.rb
|
105
|
+
- spec/lib/babysitter_spec.rb
|
88
106
|
- spec/spec_helper.rb
|
89
107
|
homepage: ''
|
90
108
|
licenses: []
|
@@ -106,11 +124,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
124
|
version: '0'
|
107
125
|
requirements: []
|
108
126
|
rubyforge_project:
|
109
|
-
rubygems_version: 1.8.
|
127
|
+
rubygems_version: 1.8.22
|
110
128
|
signing_key:
|
111
129
|
specification_version: 3
|
112
130
|
summary: Babysits long-running processes and reports progress or failures
|
113
131
|
test_files:
|
114
132
|
- spec/lib/babysitter/configuration_spec.rb
|
115
|
-
- spec/lib/babysitter/
|
133
|
+
- spec/lib/babysitter/monitor_spec.rb
|
134
|
+
- spec/lib/babysitter_spec.rb
|
116
135
|
- spec/spec_helper.rb
|