dynamo-autoscale 0.1.4 → 0.2
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/.gitignore +1 -1
- data/CHANGELOG +6 -0
- data/Gemfile.lock +27 -8
- data/README.md +85 -47
- data/bin/dynamo-autoscale +15 -113
- data/config/dynamo-autoscale-test.yml +11 -0
- data/config/environment/common.rb +100 -25
- data/config/environment/test.rb +3 -0
- data/config/services/aws.rb +2 -19
- data/config/services/logger.rb +23 -27
- data/config/services/signals.rb +15 -0
- data/dynamo-autoscale.gemspec +1 -0
- data/dynamo-autoscale.sample.yml +79 -0
- data/lib/dynamo-autoscale/actioner.rb +27 -13
- data/lib/dynamo-autoscale/cw_poller.rb +1 -0
- data/lib/dynamo-autoscale/dispatcher.rb +10 -2
- data/lib/dynamo-autoscale/dynamo_actioner.rb +6 -5
- data/lib/dynamo-autoscale/local_actioner.rb +15 -2
- data/lib/dynamo-autoscale/local_data_poll.rb +2 -0
- data/lib/dynamo-autoscale/logger.rb +4 -0
- data/lib/dynamo-autoscale/metrics.rb +1 -1
- data/lib/dynamo-autoscale/poller.rb +7 -5
- data/lib/dynamo-autoscale/rule.rb +1 -0
- data/lib/dynamo-autoscale/rule_set.rb +4 -0
- data/lib/dynamo-autoscale/scale_report.rb +39 -0
- data/lib/dynamo-autoscale/table_tracker.rb +26 -19
- data/lib/dynamo-autoscale/version.rb +1 -1
- data/script/historic_data +17 -8
- data/script/monitor +9 -26
- data/script/simulator +16 -14
- data/script/test +29 -23
- data/script/validate_ruleset +1 -3
- data/spec/actioner_spec.rb +6 -0
- data/spec/rule_spec.rb +6 -0
- data/templates/scale_report_email.erb +17 -0
- metadata +23 -3
- data/config/logger.yml +0 -11
data/script/monitor
CHANGED
@@ -11,37 +11,20 @@
|
|
11
11
|
# To exit the program entirely, drop into the REPL and run "exit!".
|
12
12
|
|
13
13
|
require_relative '../config/environment/common'
|
14
|
-
require 'pp'
|
15
|
-
require 'timecop'
|
16
14
|
include DynamoAutoscale
|
17
15
|
|
18
|
-
|
19
|
-
|
16
|
+
if ARGV[0]
|
17
|
+
DynamoAutoscale.setup_from_config(ARGV[0], dry_run: true)
|
18
|
+
elsif ARGV[0].nil?
|
19
|
+
STDERR.puts "Usage: script/monitor path/to/config.yml"
|
20
20
|
|
21
|
-
if tables.empty? or ruleset.nil?
|
22
|
-
STDERR.puts "Usage: script/monitor ruleset table_name [another_table_name ... ]"
|
23
21
|
exit 1
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
# reads and writes when the local data enters the system. It makes it look like
|
28
|
-
# we're actually modifying the provisioned numbers.
|
29
|
-
filters = [
|
30
|
-
Proc.new do |time, datum|
|
31
|
-
if writes = DynamoAutoscale.actioner.provisioned_writes(table).last
|
32
|
-
datum[:provisioned_writes] = writes.last
|
33
|
-
end
|
34
|
-
|
35
|
-
if reads = DynamoAutoscale.actioner.provisioned_reads(table).last
|
36
|
-
datum[:provisioned_reads] = reads.last
|
37
|
-
end
|
38
|
-
end,
|
39
|
-
]
|
22
|
+
elsif ARGV[0] and !File.exists?(ARGV[0])
|
23
|
+
STDERR.puts "Usage: script/monitor path/to/config.yml"
|
24
|
+
STDERR.puts "Error: The path you specified is to a file that does not exist."
|
40
25
|
|
41
|
-
|
42
|
-
|
43
|
-
DynamoAutoscale.poller = CWPoller.new(tables: tables)
|
44
|
-
DynamoAutoscale.actioner_class = LocalActioner
|
26
|
+
exit 1
|
27
|
+
end
|
45
28
|
|
46
29
|
begin
|
47
30
|
DynamoAutoscale.poller.run
|
data/script/simulator
CHANGED
@@ -5,27 +5,29 @@
|
|
5
5
|
# through the data chronologically, dropping you into a REPL with each new
|
6
6
|
# timeslice.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
8
|
+
# You will first need to have obtained historic data on the tables in your
|
9
|
+
# config file. To do this, run:
|
10
|
+
#
|
11
|
+
# $ script/historic_data path/to/config.yml
|
12
|
+
#
|
13
|
+
# This script does not change any throughputs on DynamoDB whatsoever. The
|
14
|
+
# historic script data will hit CloudWatch fairly hard to get its data, though.
|
10
15
|
|
11
16
|
require_relative '../config/environment/common'
|
12
|
-
require 'timecop'
|
13
|
-
require 'pp'
|
14
17
|
include DynamoAutoscale
|
15
18
|
|
16
|
-
|
17
|
-
|
19
|
+
if ARGV[0]
|
20
|
+
DynamoAutoscale.setup_from_config(ARGV[0], dry_run: true)
|
21
|
+
elsif ARGV[0].nil?
|
22
|
+
STDERR.puts "Usage: script/simulator path/to/config.yml"
|
18
23
|
|
19
|
-
if ruleset.nil? or tables.empty?
|
20
|
-
STDERR.puts "Usage: script/simulator ruleset table_name [another_table_name ... ]"
|
21
24
|
exit 1
|
22
|
-
|
25
|
+
elsif ARGV[0] and !File.exists?(ARGV[0])
|
26
|
+
STDERR.puts "Usage: script/simulator path/to/config.yml"
|
27
|
+
STDERR.puts "Error: The path you specified is to a file that does not exist."
|
23
28
|
|
24
|
-
|
25
|
-
|
26
|
-
DynamoAutoscale.dispatcher = Dispatcher.new
|
27
|
-
DynamoAutoscale.poller = LocalDataPoll.new(tables: tables, filters: filters)
|
28
|
-
DynamoAutoscale.actioner_class = LocalActioner
|
29
|
+
exit 1
|
30
|
+
end
|
29
31
|
|
30
32
|
DynamoAutoscale.poller.run do |table, time, datum|
|
31
33
|
Timecop.travel(time)
|
data/script/test
CHANGED
@@ -1,34 +1,42 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
# This script will locally test the tables and options you have specified in
|
4
|
+
# your config passed in as ARGV[0].
|
5
|
+
#
|
6
|
+
# You will first need to have obtained historic data on the tables in your
|
7
|
+
# config file. To do this, run:
|
8
|
+
#
|
9
|
+
# $ script/historic_data path/to/config.yml
|
10
|
+
#
|
11
|
+
# This script does not change any throughputs on DynamoDB whatsoever. The
|
12
|
+
# historic script data will hit CloudWatch fairly hard to get its data, though.
|
13
|
+
|
3
14
|
require_relative '../config/environment/common'
|
4
|
-
require 'pp'
|
5
|
-
require 'timecop'
|
6
|
-
include DynamoAutoscale
|
7
|
-
extend DynamoAutoscale
|
8
15
|
|
9
|
-
|
10
|
-
|
11
|
-
|
16
|
+
OptionParser.new do |opts|
|
17
|
+
opts.on("--graph") do
|
18
|
+
GRAPH = true
|
19
|
+
end
|
20
|
+
end.parse!
|
21
|
+
|
22
|
+
if ARGV[0]
|
23
|
+
DynamoAutoscale.setup_from_config(ARGV[0], dry_run: true)
|
24
|
+
elsif ARGV[0].nil?
|
25
|
+
STDERR.puts "Usage: script/test path/to/config.yml"
|
12
26
|
|
13
|
-
if tables.empty? or ruleset.nil?
|
14
|
-
STDERR.puts "Usage: script/test ruleset table_name [another_table_name ... ] [-g|--graph]"
|
15
27
|
exit 1
|
16
|
-
|
28
|
+
elsif ARGV[0] and !File.exists?(ARGV[0])
|
29
|
+
STDERR.puts "Usage: script/test path/to/config.yml"
|
30
|
+
STDERR.puts "Error: The path you specified is to a file that does not exist."
|
17
31
|
|
18
|
-
|
19
|
-
|
20
|
-
DynamoAutoscale.dispatcher = Dispatcher.new
|
21
|
-
DynamoAutoscale.poller = LocalDataPoll.new(tables: tables, filters: filters)
|
22
|
-
DynamoAutoscale.actioner_class = LocalActioner
|
23
|
-
DynamoAutoscale.actioner_opts = { group_downscales: true, flush_after: 2.hours }
|
32
|
+
exit 1
|
33
|
+
end
|
24
34
|
|
25
35
|
# Uncomment this and the below RubyProf lines if you want profiling information.
|
26
36
|
# RubyProf.start
|
27
37
|
|
28
38
|
begin
|
29
|
-
DynamoAutoscale.poller.run
|
30
|
-
Timecop.travel(time)
|
31
|
-
end
|
39
|
+
DynamoAutoscale.poller.run { |table_name, time| Timecop.travel(time) }
|
32
40
|
rescue Interrupt
|
33
41
|
Ripl.start binding: binding
|
34
42
|
end
|
@@ -40,12 +48,10 @@ end
|
|
40
48
|
# Uncomment this if you want to drop into a REPL at the end of the test.
|
41
49
|
# Ripl.start binding: binding
|
42
50
|
|
43
|
-
tables.each do |
|
44
|
-
table = DynamoAutoscale.tables[table_name]
|
45
|
-
|
51
|
+
DynamoAutoscale.tables.each do |_, table|
|
46
52
|
table.report!
|
47
53
|
|
48
|
-
if
|
54
|
+
if GRAPH
|
49
55
|
path = table.graph! open: true
|
50
56
|
puts "Graph saved to #{path}"
|
51
57
|
end
|
data/script/validate_ruleset
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
3
|
require_relative '../config/environment/common'
|
4
|
-
include DynamoAutoscale
|
5
|
-
extend DynamoAutoscale
|
6
4
|
|
7
5
|
ruleset = ARGV.shift
|
8
6
|
|
@@ -12,7 +10,7 @@ if ruleset.nil?
|
|
12
10
|
end
|
13
11
|
|
14
12
|
begin
|
15
|
-
RuleSet.new(ruleset)
|
13
|
+
DynamoAutoscale::RuleSet.new(ruleset)
|
16
14
|
puts "Rules seem legit."
|
17
15
|
rescue ArgumentError => e
|
18
16
|
puts "Ruleset has problem: #{e.message}"
|
data/spec/actioner_spec.rb
CHANGED
@@ -16,6 +16,12 @@ describe DynamoAutoscale::Actioner do
|
|
16
16
|
})
|
17
17
|
end
|
18
18
|
|
19
|
+
it "should add a scale event to its table" do
|
20
|
+
Timecop.travel(10.minutes.from_now)
|
21
|
+
actioner.set(:writes, 90).should be_true
|
22
|
+
table.scale_events.should_not be_empty
|
23
|
+
end
|
24
|
+
|
19
25
|
it "should not be allowed more than 4 times per day" do
|
20
26
|
actioner.set(:writes, 90).should be_true
|
21
27
|
Timecop.travel(10.minutes.from_now)
|
data/spec/rule_spec.rb
CHANGED
@@ -252,6 +252,12 @@ describe DynamoAutoscale::Rule do
|
|
252
252
|
|
253
253
|
subject { rule.test(table) }
|
254
254
|
it { should be_true }
|
255
|
+
|
256
|
+
describe "table" do
|
257
|
+
subject { table }
|
258
|
+
before { rule.test(table) }
|
259
|
+
its(:triggered_rules) { should_not be_empty }
|
260
|
+
end
|
255
261
|
end
|
256
262
|
|
257
263
|
describe "should not match" do
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Last 5 triggered rules:
|
2
|
+
|
3
|
+
<% @table.triggered_rules.reverse_each.take(5).each do |time, rule| %>
|
4
|
+
<%= time.iso8601 %>: <%= rule.to_english %>
|
5
|
+
<% end %>
|
6
|
+
|
7
|
+
Last 20 data points:
|
8
|
+
|
9
|
+
<% @table.data.reverse_each.take(20).each do |time, datum| %>
|
10
|
+
<% time.iso8601 %>: <%= datum %>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
Last 5 scale events:
|
14
|
+
|
15
|
+
<% @table.scale_events.reverse_each.take(5) do |time, scale_event| %>
|
16
|
+
<%= time.iso8601 %>: <%= scale_event %>
|
17
|
+
<% end %>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dynamo-autoscale
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.2'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir:
|
11
11
|
- bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-07-
|
13
|
+
date: 2013-07-04 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws-sdk
|
@@ -92,6 +92,22 @@ dependencies:
|
|
92
92
|
- - ! '>='
|
93
93
|
- !ruby/object:Gem::Version
|
94
94
|
version: '0'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: pony
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
type: :runtime
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
95
111
|
description: Will automatically monitor DynamoDB tables and scale them based on rules.
|
96
112
|
email: developers@getinvisiblehand.com
|
97
113
|
executables:
|
@@ -108,14 +124,16 @@ files:
|
|
108
124
|
- Rakefile
|
109
125
|
- aws.sample.yml
|
110
126
|
- bin/dynamo-autoscale
|
127
|
+
- config/dynamo-autoscale-test.yml
|
111
128
|
- config/environment/common.rb
|
112
129
|
- config/environment/console.rb
|
113
130
|
- config/environment/test.rb
|
114
|
-
- config/logger.yml
|
115
131
|
- config/services/aws.rb
|
116
132
|
- config/services/logger.rb
|
133
|
+
- config/services/signals.rb
|
117
134
|
- data/.gitkeep
|
118
135
|
- dynamo-autoscale.gemspec
|
136
|
+
- dynamo-autoscale.sample.yml
|
119
137
|
- lib/dynamo-autoscale.rb
|
120
138
|
- lib/dynamo-autoscale/actioner.rb
|
121
139
|
- lib/dynamo-autoscale/cw_poller.rb
|
@@ -130,6 +148,7 @@ files:
|
|
130
148
|
- lib/dynamo-autoscale/pretty_formatter.rb
|
131
149
|
- lib/dynamo-autoscale/rule.rb
|
132
150
|
- lib/dynamo-autoscale/rule_set.rb
|
151
|
+
- lib/dynamo-autoscale/scale_report.rb
|
133
152
|
- lib/dynamo-autoscale/table_tracker.rb
|
134
153
|
- lib/dynamo-autoscale/unit_cost.rb
|
135
154
|
- lib/dynamo-autoscale/version.rb
|
@@ -151,6 +170,7 @@ files:
|
|
151
170
|
- spec/rule_spec.rb
|
152
171
|
- spec/spec_helper.rb
|
153
172
|
- spec/table_tracker_spec.rb
|
173
|
+
- templates/scale_report_email.erb
|
154
174
|
homepage: http://github.com/invisiblehand/dynamo-autoscale
|
155
175
|
licenses:
|
156
176
|
- MIT
|