amonitor 0.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +72 -0
- data/README.rdoc +6 -0
- data/Rakefile +44 -0
- data/amonitor.gemspec +26 -0
- data/amonitor.rdoc +5 -0
- data/aws_monitor/AwsCredentialConfiguration.rb +41 -0
- data/aws_monitor/AwsTresholdManager.rb +186 -0
- data/bin/amonitor +198 -0
- data/features/amonitor.feature +8 -0
- data/features/step_definitions/amonitor_steps.rb +6 -0
- data/features/support/env.rb +15 -0
- data/lib/amonitor.rb +4 -0
- data/lib/amonitor/version.rb +3 -0
- data/test/default_test.rb +14 -0
- data/test/test_helper.rb +9 -0
- metadata +180 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b7d2a56f7bb1db34f7cd8586741f64319096249f
|
4
|
+
data.tar.gz: 53271f3d4db89d684bce0716a1c52477b5aa80ee
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bc28ae35a5cc8cc575d5af0ca002515d23f80247706b3a9caa8e3c74b6267251232bb50197ae623f610ce90beec220c1e970ea5ee37a0c2d3bf378efa6bd384e
|
7
|
+
data.tar.gz: 2baa2a37d9cca12b59e47fa2ea6b9edee6f3e82c8da22df63c82550b431e00c8a6079ca419e86efb6f30a1966056674d1918f765b2ec4053e5f17c8658ac59df
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.idea/*
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
amonitor (0.0.1)
|
5
|
+
gli (= 2.14.0)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
aruba (0.14.2)
|
11
|
+
childprocess (~> 0.5.6)
|
12
|
+
contracts (~> 0.9)
|
13
|
+
cucumber (>= 1.3.19)
|
14
|
+
ffi (~> 1.9.10)
|
15
|
+
rspec-expectations (>= 2.99)
|
16
|
+
thor (~> 0.19)
|
17
|
+
awesome_print (1.7.0)
|
18
|
+
aws-sdk (2.5.11)
|
19
|
+
aws-sdk-resources (= 2.5.11)
|
20
|
+
aws-sdk-core (2.5.11)
|
21
|
+
jmespath (~> 1.0)
|
22
|
+
aws-sdk-resources (2.5.11)
|
23
|
+
aws-sdk-core (= 2.5.11)
|
24
|
+
builder (3.2.2)
|
25
|
+
childprocess (0.5.9)
|
26
|
+
ffi (~> 1.0, >= 1.0.11)
|
27
|
+
contracts (0.14.0)
|
28
|
+
cucumber (2.4.0)
|
29
|
+
builder (>= 2.1.2)
|
30
|
+
cucumber-core (~> 1.5.0)
|
31
|
+
cucumber-wire (~> 0.0.1)
|
32
|
+
diff-lcs (>= 1.1.3)
|
33
|
+
gherkin (~> 4.0)
|
34
|
+
multi_json (>= 1.7.5, < 2.0)
|
35
|
+
multi_test (>= 0.1.2)
|
36
|
+
cucumber-core (1.5.0)
|
37
|
+
gherkin (~> 4.0)
|
38
|
+
cucumber-wire (0.0.1)
|
39
|
+
diff-lcs (1.2.5)
|
40
|
+
ffi (1.9.14)
|
41
|
+
gherkin (4.0.0)
|
42
|
+
gli (2.14.0)
|
43
|
+
highline (1.7.8)
|
44
|
+
jmespath (1.3.1)
|
45
|
+
json (1.8.3)
|
46
|
+
multi_json (1.12.1)
|
47
|
+
multi_test (0.1.2)
|
48
|
+
rainbow (2.1.0)
|
49
|
+
rake (11.2.2)
|
50
|
+
rdoc (4.2.2)
|
51
|
+
json (~> 1.4)
|
52
|
+
rspec-expectations (3.5.0)
|
53
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
54
|
+
rspec-support (~> 3.5.0)
|
55
|
+
rspec-support (3.5.0)
|
56
|
+
thor (0.19.1)
|
57
|
+
|
58
|
+
PLATFORMS
|
59
|
+
ruby
|
60
|
+
|
61
|
+
DEPENDENCIES
|
62
|
+
amonitor!
|
63
|
+
aruba
|
64
|
+
awesome_print
|
65
|
+
aws-sdk
|
66
|
+
highline
|
67
|
+
rainbow
|
68
|
+
rake
|
69
|
+
rdoc
|
70
|
+
|
71
|
+
BUNDLED WITH
|
72
|
+
1.13.0
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rubygems/package_task'
|
4
|
+
require 'rdoc/task'
|
5
|
+
require 'cucumber'
|
6
|
+
require 'cucumber/rake/task'
|
7
|
+
Rake::RDocTask.new do |rd|
|
8
|
+
rd.main = "README.rdoc"
|
9
|
+
rd.rdoc_files.include("README.rdoc","lib/**/*.rb","bin/**/*")
|
10
|
+
rd.title = 'Your application title'
|
11
|
+
end
|
12
|
+
|
13
|
+
spec = eval(File.read('amonitor.gemspec'))
|
14
|
+
|
15
|
+
Gem::PackageTask.new(spec) do |pkg|
|
16
|
+
end
|
17
|
+
CUKE_RESULTS = 'results.html'
|
18
|
+
CLEAN << CUKE_RESULTS
|
19
|
+
desc 'Run features'
|
20
|
+
Cucumber::Rake::Task.new(:features) do |t|
|
21
|
+
opts = "features --format html -o #{CUKE_RESULTS} --format progress -x"
|
22
|
+
opts += " --tags #{ENV['TAGS']}" if ENV['TAGS']
|
23
|
+
t.cucumber_opts = opts
|
24
|
+
t.fork = false
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Run features tagged as work-in-progress (@wip)'
|
28
|
+
Cucumber::Rake::Task.new('features:wip') do |t|
|
29
|
+
tag_opts = ' --tags ~@pending'
|
30
|
+
tag_opts = ' --tags @wip'
|
31
|
+
t.cucumber_opts = "features --format html -o #{CUKE_RESULTS} --format pretty -x -s#{tag_opts}"
|
32
|
+
t.fork = false
|
33
|
+
end
|
34
|
+
|
35
|
+
task :cucumber => :features
|
36
|
+
task 'cucumber:wip' => 'features:wip'
|
37
|
+
task :wip => 'features:wip'
|
38
|
+
require 'rake/testtask'
|
39
|
+
Rake::TestTask.new do |t|
|
40
|
+
t.libs << "test"
|
41
|
+
t.test_files = FileList['test/*_test.rb']
|
42
|
+
end
|
43
|
+
|
44
|
+
task :default => [:test,:features]
|
data/amonitor.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Ensure we require the local version and not one we might have installed already
|
2
|
+
require File.join([File.dirname(__FILE__),'lib','amonitor','version.rb'])
|
3
|
+
spec = Gem::Specification.new do |s|
|
4
|
+
s.name = 'amonitor'
|
5
|
+
s.version = Amonitor::VERSION
|
6
|
+
s.author = 'Alex Zalantai'
|
7
|
+
s.email = 'alex.zalantai@bjss.com'
|
8
|
+
s.homepage = 'http://bjss.com'
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.summary = 'BJSS Availability Monitor'
|
11
|
+
s.files = `git ls-files`.split("\n")
|
12
|
+
s.require_paths << 'lib'
|
13
|
+
s.has_rdoc = true
|
14
|
+
s.extra_rdoc_files = ['README.rdoc','amonitor.rdoc']
|
15
|
+
s.rdoc_options << '--title' << 'amonitor' << '--main' << 'README.rdoc' << '-ri'
|
16
|
+
s.bindir = 'bin'
|
17
|
+
s.executables << 'amonitor'
|
18
|
+
s.add_development_dependency('rake')
|
19
|
+
s.add_development_dependency('rdoc')
|
20
|
+
s.add_development_dependency('aruba')
|
21
|
+
s.add_development_dependency('highline')
|
22
|
+
s.add_development_dependency('aws-sdk')
|
23
|
+
s.add_development_dependency('awesome_print')
|
24
|
+
s.add_development_dependency('rainbow')
|
25
|
+
s.add_runtime_dependency('gli','2.14.0')
|
26
|
+
end
|
data/amonitor.rdoc
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'highline/import'
|
2
|
+
|
3
|
+
class AwsCredentialConfiguration
|
4
|
+
def self.reset_credentials
|
5
|
+
ENV['AWS_ACCESS_KEY_ID'] = ask "Please input your AWS_ACCESS_KEY_ID: "
|
6
|
+
ENV['AWS_SECRET_ACCESS_KEY'] = ask "Please input your AWS_SECRET_ACCESS_KEY: "
|
7
|
+
ENV['AWS_REGION'] = ask "Please input your AWS_REGION: "
|
8
|
+
File.open("#{ENV['HOME']}/.aws_secrets", 'w') {|file| file.write("#{ENV['AWS_ACCESS_KEY_ID']},#{ENV['AWS_SECRET_ACCESS_KEY']},#{ENV['AWS_REGION']}") }
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.credentials_creator
|
12
|
+
#check if there is a config file and check if its empty
|
13
|
+
if File.file?("#{ENV['HOME']}/.aws_secrets") or File.zero?("#{ENV['HOME']}/.aws_secrets")
|
14
|
+
secrets = File.open("#{ENV['HOME']}/.aws_secrets", "rb").read.split(",")
|
15
|
+
# if any of the credentials empty in the file try and pull form environment
|
16
|
+
if secrets[0].nil? or secrets[1].nil? or secrets[2].nil?
|
17
|
+
secrets[0] = ENV['AWS_ACCESS_KEY_ID'] if secrets[0].nil?
|
18
|
+
secrets[1] = ENV['AWS_SECRET_ACCESS_KEY'] if secrets[1].nil?
|
19
|
+
secrets[2] = ENV['AWS_REGION'] if secrets[2].nil?
|
20
|
+
end
|
21
|
+
# if they still empty ask for them
|
22
|
+
ask "Please input your AWS_ACCESS_KEY_ID: " if secrets[0].nil?
|
23
|
+
ask "Please input your AWS_SECRET_ACCESS_KEY: " if secrets[1].nil?
|
24
|
+
ask "Please input your AWS_REGION: " if secrets[2].nil?
|
25
|
+
# put them in the environment as well just in case:
|
26
|
+
ENV['AWS_ACCESS_KEY_ID'],ENV['AWS_SECRET_ACCESS_KEY'],ENV['AWS_REGION'] = secrets
|
27
|
+
# write them to file now that all is definitely filled
|
28
|
+
File.open("#{ENV['HOME']}/.aws_secrets", 'w') {|file| file.write("#{ENV['AWS_ACCESS_KEY_ID']},#{ENV['AWS_SECRET_ACCESS_KEY']},#{ENV['AWS_REGION']}") }
|
29
|
+
STDOUT.puts "You set all your credentials already! Reset with: amonitor aws config -r"
|
30
|
+
else
|
31
|
+
# try and take credentials from environment, but if any empty, just reset all.
|
32
|
+
if ENV['AWS_ACCESS_KEY_ID'].nil? or ENV['AWS_SECRET_ACCESS_KEY'].nil? or ENV['AWS_REGION'].nil?
|
33
|
+
STDERR.puts "You will need to configure your AWS credentials..."
|
34
|
+
reset_credentials
|
35
|
+
else
|
36
|
+
File.open("#{ENV['HOME']}/.aws_secrets", 'w') {|file| file.write("#{ENV['AWS_ACCESS_KEY_ID']},#{ENV['AWS_SECRET_ACCESS_KEY']},#{ENV['AWS_REGION']}") }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
require 'yaml'
|
3
|
+
require 'singleton'
|
4
|
+
require 'highline/import'
|
5
|
+
require_relative 'AwsCredentialConfiguration'
|
6
|
+
|
7
|
+
# How to publish custom metrics to AWS with aws cli without Ruby
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# NOTE: Custom metrics cost money.
|
11
|
+
#
|
12
|
+
#
|
13
|
+
# Get available ram in MB
|
14
|
+
# data_point=$(var=$(egrep --color 'Mem|Cache|Swap' /proc/meminfo | sed -n '2p' | awk {'print $2'}) | expr $var / 1024)
|
15
|
+
# time_stamp=$(date --utc +%FT%TZ)
|
16
|
+
# publish to aws cw
|
17
|
+
# aws cloudwatch put-metric-data --metric-name FreeSystemMemory --namespace "CustomMonitoring" --value $data_point --timestamp $timestamp
|
18
|
+
#
|
19
|
+
#
|
20
|
+
|
21
|
+
class AwsTresholdManager
|
22
|
+
|
23
|
+
include Singleton
|
24
|
+
attr_reader :client, :cloud_watch_client, :available_instances, :available_instance_ids, :access_key,
|
25
|
+
:secret_access_key, :region
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
raise "Please run: amonitor aws configure first!" unless File.file?("#{ENV['HOME']}/.aws_secrets")
|
29
|
+
secrets = File.open("#{ENV['HOME']}/.aws_secrets", "rb").read.split(",")
|
30
|
+
@acces_key, @secret_acces_key, @region = secrets
|
31
|
+
ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'], ENV['AWS_REGION'] = secrets
|
32
|
+
@client ||= Aws::EC2::Client.new
|
33
|
+
@cloud_watch_client ||= Aws::CloudWatch::Client.new(region: 'us-west-2')
|
34
|
+
end
|
35
|
+
|
36
|
+
# You only have to call this method if
|
37
|
+
# ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY'], ENV['AWS_REGION']
|
38
|
+
# are not set in your environment.
|
39
|
+
def configure_connection_from_file(credential_file_path)
|
40
|
+
# optional CSV reader
|
41
|
+
# CSV.read(credential_file_path, headers:true, header_converters: :symbol, converters: :all).collect do |row|
|
42
|
+
# Hash[row.collect { |c,r| [c,r] }]
|
43
|
+
# end
|
44
|
+
credential_file = YAML.load(File.open(credential_file_path))
|
45
|
+
@credentials = AwsCredentials.new(credential_file['AWS_ACCESS_KEY_ID'], credential_file['AWS_SECRET_ACCESS_KEY'])
|
46
|
+
Aws.config.update({region: credential_file['AWS_REGION'], credentials: @credentials})
|
47
|
+
end
|
48
|
+
|
49
|
+
def connect_to_ec2_with_creds(acces_key, secret_access_key, region)
|
50
|
+
@client = Aws::EC2::Client.new(access_key_id: acces_key,
|
51
|
+
secret_access_key: secret_access_key,
|
52
|
+
region: region)
|
53
|
+
end
|
54
|
+
|
55
|
+
def connect_to_cw_with_creds(acces_key, secret_access_key, region)
|
56
|
+
@cloud_watch_client = Aws::CloudWatch::Client.new(access_key_id: acces_key,
|
57
|
+
secret_access_key: secret_access_key,
|
58
|
+
region: region)
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_available_instances
|
62
|
+
@available_instances = @client.describe_instances
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_available_instance_ids
|
66
|
+
@available_instance_ids = []
|
67
|
+
@client.describe_instances.reservations[0].instances.each {|instance| @available_instance_ids << instance.instance_id}
|
68
|
+
@available_instance_ids
|
69
|
+
end
|
70
|
+
|
71
|
+
def list_all_metrics
|
72
|
+
arr =[]
|
73
|
+
@cloud_watch_client.list_metrics(namespace: 'AWS/EC2')[0].each {|metric| arr << metric.metric_name}
|
74
|
+
end
|
75
|
+
|
76
|
+
def list_metrics_for_instance_id(instance_id)
|
77
|
+
arr = []
|
78
|
+
metrics = @cloud_watch_client.list_metrics(namespace: "AWS/EC2",
|
79
|
+
dimensions: [{name: 'InstanceId', value: instance_id}]).metrics
|
80
|
+
metrics.each {|metric| arr << metric.metric_name}
|
81
|
+
arr
|
82
|
+
end
|
83
|
+
|
84
|
+
# choice of statistics: SampleCount, Average, Sum, Minimum, Maximum
|
85
|
+
# choice of unit: Seconds, Microseconds, Milliseconds, Bytes, Kilobytes, Megabytes, Gigabytes, Terabytes, Bits,
|
86
|
+
# Kilobits, Megabits, Gigabits, Terabits, Percent, Count, Bytes/Second, Kilobytes/Second,
|
87
|
+
# Megabytes/Second, Gigabytes/Second, Terabytes/Second, Bits/Second, Kilobits/Second, Megabits/Second,
|
88
|
+
# Gigabits/Second, Terabits/Second, Count/Second, None - for default
|
89
|
+
def cpu_average_treshold(instance_id, detect_from = Time.now-3600)
|
90
|
+
data = @cloud_watch_client.get_metric_statistics(
|
91
|
+
namespace: 'AWS/EC2',
|
92
|
+
metric_name: 'CPUUtilization',
|
93
|
+
dimensions: [
|
94
|
+
{name: 'InstanceId',
|
95
|
+
value: instance_id
|
96
|
+
},
|
97
|
+
],
|
98
|
+
start_time: detect_from,
|
99
|
+
end_time: Time.now,
|
100
|
+
period: 60,
|
101
|
+
statistics: ['Average'],
|
102
|
+
# unit: 'Percent'
|
103
|
+
).datapoints
|
104
|
+
data.inject(0) {|sum, datapoint| sum + datapoint.average} / data.size
|
105
|
+
end
|
106
|
+
|
107
|
+
def network_in_max_treshold(instance_id, detect_from = Time.now-600)
|
108
|
+
data = @cloud_watch_client.get_metric_statistics(
|
109
|
+
namespace: 'AWS/EC2',
|
110
|
+
metric_name: 'NetworkPacketsIn',
|
111
|
+
dimensions: [
|
112
|
+
{name: 'InstanceId',
|
113
|
+
value: instance_id
|
114
|
+
},
|
115
|
+
],
|
116
|
+
start_time: detect_from,
|
117
|
+
end_time: Time.now,
|
118
|
+
period: 60,
|
119
|
+
statistics: ['Maximum'],
|
120
|
+
unit: 'Count'
|
121
|
+
).datapoints
|
122
|
+
data.inject(0) {|sum, datapoint| sum + datapoint.maximum} / data.size
|
123
|
+
end
|
124
|
+
|
125
|
+
# Average, Minimum, Maximum for statistics
|
126
|
+
def chosen_treshold(instance_ids, statistics, detect_from = Time.now-600, metric = "CPUUtilization")
|
127
|
+
result = []
|
128
|
+
instance_ids.each do |instance_id|
|
129
|
+
datapoints = @cloud_watch_client.get_metric_statistics(
|
130
|
+
namespace: 'AWS/EC2',
|
131
|
+
metric_name: metric,#'CPUUtilization',
|
132
|
+
dimensions: [
|
133
|
+
{name: 'InstanceId',
|
134
|
+
value: instance_id
|
135
|
+
},
|
136
|
+
],
|
137
|
+
start_time: detect_from,
|
138
|
+
end_time: Time.now,
|
139
|
+
period: 60,
|
140
|
+
statistics: [statistics],
|
141
|
+
).datapoints
|
142
|
+
arr = []
|
143
|
+
datapoints.each {|data| arr << data} #unless datapoints.size 0
|
144
|
+
case statistics
|
145
|
+
when 'Average'
|
146
|
+
result << [instance_id, (arr.inject(0) {|sum, datapoint| sum + datapoint.average} / arr.size)]
|
147
|
+
when 'Maximum'
|
148
|
+
result << [instance_id, (arr.inject(0) {|max, datapoint| max + datapoint.maximum} / arr.size)]
|
149
|
+
when 'Minimum'
|
150
|
+
result << [instance_id, arr.inject(0) {|min, datapoint| min > datapoint.minimum ? min = datapoint.minimum : datapoint.minimum}]
|
151
|
+
else
|
152
|
+
false
|
153
|
+
end
|
154
|
+
end
|
155
|
+
result
|
156
|
+
end
|
157
|
+
|
158
|
+
def result_parser(result, limit)
|
159
|
+
counter = [0, 0, 0]
|
160
|
+
result.each do |res|
|
161
|
+
output = "=> ID: #{res[0]} READ: #{res[1]} <> LIMIT: #{limit}"
|
162
|
+
case
|
163
|
+
when limit.to_i < res[1].to_i
|
164
|
+
counter[0] = counter[0] + 1
|
165
|
+
STDOUT.puts Rainbow("#{output}").red
|
166
|
+
when limit.to_i == res[1].to_i
|
167
|
+
counter[1] = counter[1] + 1
|
168
|
+
STDOUT.puts Rainbow(output).yellow
|
169
|
+
when limit.to_i > res[1].to_i
|
170
|
+
counter[2] = counter[2] + 1
|
171
|
+
STDOUT.puts Rainbow(output).green
|
172
|
+
end
|
173
|
+
end
|
174
|
+
STDOUT.puts "SUMMARY: #{Rainbow("Pass: #{counter[2]}").green} #{Rainbow("OK: #{counter[1]}").yellow} #{Rainbow("Fail: #{counter[0]}").red} "
|
175
|
+
end
|
176
|
+
|
177
|
+
def instance_id_array_builder(id = nil, all = nil, file = nil)
|
178
|
+
instances = []
|
179
|
+
instances << id unless id.nil?
|
180
|
+
instances = File.open("#{file}", "rb").read.gsub("\n" , "").split(",") unless file.nil?
|
181
|
+
instances = get_available_instance_ids if all
|
182
|
+
raise "No instance ID's were provided, see -h" if id.nil? and file.nil? and 'all' == false
|
183
|
+
instances
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
data/bin/amonitor
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative '../aws_monitor/AwsTresholdManager'
|
3
|
+
require_relative '../aws_monitor/AwsCredentialConfiguration'
|
4
|
+
require 'gli'
|
5
|
+
require 'csv'
|
6
|
+
require 'awesome_print'
|
7
|
+
require 'rainbow'
|
8
|
+
begin # XXX: Remove this begin/rescue before distributing your app
|
9
|
+
require 'amonitor'
|
10
|
+
rescue LoadError
|
11
|
+
STDERR.puts "In development, you need to use `bundle exec bin/amonitor` to run your app"
|
12
|
+
STDERR.puts "At install-time, RubyGems will make sure lib, etc. are in the load path"
|
13
|
+
STDERR.puts "Feel free to remove this message from bin/amonitor now"
|
14
|
+
exit 64
|
15
|
+
end
|
16
|
+
|
17
|
+
include GLI::App
|
18
|
+
|
19
|
+
program_desc 'Availability Monitoring Test Suite'
|
20
|
+
|
21
|
+
version Amonitor::VERSION
|
22
|
+
|
23
|
+
subcommand_option_handling :normal
|
24
|
+
arguments :strict
|
25
|
+
|
26
|
+
desc 'Monitor with AWS CloudWatch'
|
27
|
+
command :aws do |c|
|
28
|
+
# flags will be inherited
|
29
|
+
c.desc "Please specify instance ID"
|
30
|
+
c.flag [:i, :id]
|
31
|
+
c.desc "Please specify file with instance IDs in it innit."
|
32
|
+
c.flag [:f, :file]
|
33
|
+
c.desc "Please specify TIME to test FROM in UTC format, default is an hour."
|
34
|
+
c.flag [:t, :time]
|
35
|
+
c.desc "Please specify the limit for the CPUs in %."
|
36
|
+
c.flag [:l, :limit]
|
37
|
+
# switches
|
38
|
+
c.desc "Test all available instances in my account"
|
39
|
+
c.switch [:a, :all], :negatable => false
|
40
|
+
c.desc "Use this switch to get minimum values"
|
41
|
+
c.switch [:m, :min], :negatable => false
|
42
|
+
c.desc "Use this switch to get maximum values"
|
43
|
+
c.switch [:x, :max], :negatable => false
|
44
|
+
c.desc "Use this switch to get average values"
|
45
|
+
c.switch [:v, :average], :negatable => false
|
46
|
+
|
47
|
+
c.desc 'Configure your AWS access credentials'
|
48
|
+
c.command :configure do |configure|
|
49
|
+
configure.desc "This is the reset flag for AWS secrets"
|
50
|
+
configure.switch [:r, :reset]
|
51
|
+
configure.action do |global, switch|
|
52
|
+
if switch['reset']
|
53
|
+
AwsCredentialConfiguration.reset_credentials
|
54
|
+
end
|
55
|
+
AwsCredentialConfiguration.credentials_creator
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
c.desc 'List all instances and their details. Just a big dump of data.'
|
60
|
+
c.command :"instances" do |list_instances|
|
61
|
+
list_instances.action do
|
62
|
+
p @aws.get_available_instances
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
c.desc 'List all metrics. Just a big dump of data.'
|
67
|
+
c.command :"metrics" do |metrics|
|
68
|
+
metrics.action do
|
69
|
+
STDOUT.puts @aws.list_all_metrics
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
c.desc 'List all instances IDs, These are useful to individually query them for metrics.'
|
74
|
+
c.command :"instance-ids" do |list_instance_ids|
|
75
|
+
# could do another flag for writing this to id file?
|
76
|
+
list_instance_ids.desc 'Specify where to write the retrieved instance IDs'
|
77
|
+
list_instance_ids.flag [:o, :out]
|
78
|
+
list_instance_ids.action do |global, flag|
|
79
|
+
instance_ids = @aws.get_available_instance_ids
|
80
|
+
unless flag['o'].nil?
|
81
|
+
File.open("#{flag['o']}", 'w') {|f| f.write(instance_ids.to_csv)}
|
82
|
+
end
|
83
|
+
STDOUT.puts instance_ids
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
c.desc 'List all available metrics on an instance.'
|
88
|
+
c.command :"metrics-for-id" do |list_metrics_for_id|
|
89
|
+
list_metrics_for_id.desc "Please specify instance ID"
|
90
|
+
list_metrics_for_id.flag [:i, :id]
|
91
|
+
# could do another flag for an id file?
|
92
|
+
list_metrics_for_id.action do |global, flag|
|
93
|
+
if flag['id'] == nil
|
94
|
+
raise "No instance ID was provided"
|
95
|
+
end
|
96
|
+
STDOUT.puts @aws.list_metrics_for_instance_id(flag['id'])
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
c.desc 'Test Network'
|
101
|
+
c.arg_name 'Type'
|
102
|
+
c.command :"network" do |network|
|
103
|
+
network.action do |global, flag|
|
104
|
+
flag = flag[GLI::Command::PARENT]
|
105
|
+
if flag['id'].nil? and flag['file'].nil? and flag['all'].nil?
|
106
|
+
raise "No instance ID or file was provided, use -h for help"
|
107
|
+
end
|
108
|
+
detect_from = Time.parse(flag['t']) unless flag['t'].nil?
|
109
|
+
detect_from = Time.now-3600 unless detect_from.instance_of? Time
|
110
|
+
statistics = "Minimum" if flag['m']
|
111
|
+
statistics = "Maximum" if flag['x']
|
112
|
+
statistics = "Average" if flag['v']
|
113
|
+
raise "No metric was chosen, please use -m for minimum, -x for maximum or -v for average" if statistics.nil?
|
114
|
+
instances = @aws.instance_id_array_builder(flag['id'], flag['all'], flag['file'])
|
115
|
+
raise "No limit was provided, do it with -l, --limit=YOURLIMIT, or do -h" if flag['limit'].nil?
|
116
|
+
@aws.result_parser(@aws.chosen_treshold(instances, statistics, detect_from, "NetworkPacketsIn"), flag['l'])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
c.desc 'Test CPU'
|
121
|
+
c.command :"cpu" do |test_cpu|
|
122
|
+
test_cpu.action do |global, flag|
|
123
|
+
flag = flag[GLI::Command::PARENT]
|
124
|
+
if flag['id'].nil? and flag['file'].nil? and flag['all'].nil?
|
125
|
+
raise "No instance ID or file was provided, use -h for help"
|
126
|
+
end
|
127
|
+
detect_from = Time.parse(flag['t']) unless flag['t'].nil?
|
128
|
+
detect_from = Time.now-3600 unless detect_from.instance_of? Time
|
129
|
+
statistics = "Minimum" if flag['m']
|
130
|
+
statistics = "Maximum" if flag['x']
|
131
|
+
statistics = "Average" if flag['v']
|
132
|
+
raise "No metric was chosen, please use -m for minimum, -x for maximum or -v for average" if statistics.nil?
|
133
|
+
instances = @aws.instance_id_array_builder(flag['id'], flag['all'], flag['file'])
|
134
|
+
raise "No limit was provided, do it with -l, --limit=YOURLIMIT, or do -h" if flag['limit'].nil?
|
135
|
+
@aws.result_parser(@aws.chosen_treshold(instances, statistics, detect_from), flag['limit'])
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
c.desc 'Test DiskRead'
|
140
|
+
c.command :"disk-read" do |disk_read|
|
141
|
+
disk_read.action do |global, flag|
|
142
|
+
flag = flag[GLI::Command::PARENT]
|
143
|
+
if flag['id'].nil? and flag['file'].nil? and flag['all'].nil?
|
144
|
+
raise "No instance ID or file was provided, use -h for help"
|
145
|
+
end
|
146
|
+
detect_from = Time.parse(flag['t']) unless flag['t'].nil?
|
147
|
+
detect_from = Time.now-3600 unless detect_from.instance_of? Time
|
148
|
+
statistics = "Minimum" if flag['m']
|
149
|
+
statistics = "Maximum" if flag['x']
|
150
|
+
statistics = "Average" if flag['v']
|
151
|
+
raise "No metric was chosen, please use -m for minimum, -x for maximum or -v for average" if statistics.nil?
|
152
|
+
instances = @aws.instance_id_array_builder(flag['id'], flag['all'], flag['file'])
|
153
|
+
raise "No limit was provided, do it with -l, --limit=YOURLIMIT, or do -h" if flag['limit'].nil?
|
154
|
+
@aws.result_parser(@aws.chosen_treshold(instances, statistics, detect_from, "DiskReadOps"), flag['limit'])
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
c.desc 'Test DiskWrite'
|
159
|
+
c.command :"disk-write" do |disk_write|
|
160
|
+
disk_write.action do |global, flag|
|
161
|
+
flag = flag[GLI::Command::PARENT]
|
162
|
+
if flag['id'].nil? and flag['file'].nil? and flag['all'].nil?
|
163
|
+
raise "No instance ID or file was provided, use -h for help"
|
164
|
+
end
|
165
|
+
detect_from = Time.parse(flag['t']) unless flag['t'].nil?
|
166
|
+
detect_from = Time.now-3600 unless detect_from.instance_of? Time
|
167
|
+
statistics = "Minimum" if flag['m']
|
168
|
+
statistics = "Maximum" if flag['x']
|
169
|
+
statistics = "Average" if flag['v']
|
170
|
+
raise "No metric was chosen, please use -m for minimum, -x for maximum or -v for average" if statistics.nil?
|
171
|
+
instances = @aws.instance_id_array_builder(flag['id'], flag['all'], flag['file'])
|
172
|
+
raise "No limit was provided, do it with -l, --limit=YOURLIMIT, or do -h" if flag['limit'].nil?
|
173
|
+
@aws.result_parser(@aws.chosen_treshold(instances, statistics, detect_from, "DiskWriteOps"), flag['limit'])
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
pre do |global,command,options,args|
|
180
|
+
unless command.name.to_s.include? "configure"
|
181
|
+
@aws = AwsTresholdManager.instance
|
182
|
+
end
|
183
|
+
true
|
184
|
+
end
|
185
|
+
|
186
|
+
post do |global,command,options,args|
|
187
|
+
# Post logic here
|
188
|
+
# Use skips_post before a command to skip this
|
189
|
+
# block on that command only
|
190
|
+
end
|
191
|
+
|
192
|
+
on_error do |exception|
|
193
|
+
# Error logic here
|
194
|
+
# return false to skip default error handling
|
195
|
+
true
|
196
|
+
end
|
197
|
+
|
198
|
+
exit run(ARGV)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'aruba/cucumber'
|
2
|
+
|
3
|
+
ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
4
|
+
LIB_DIR = File.join(File.expand_path(File.dirname(__FILE__)),'..','..','lib')
|
5
|
+
|
6
|
+
Before do
|
7
|
+
# Using "announce" causes massive warnings on 1.9.2
|
8
|
+
@puts = true
|
9
|
+
@original_rubylib = ENV['RUBYLIB']
|
10
|
+
ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
After do
|
14
|
+
ENV['RUBYLIB'] = @original_rubylib
|
15
|
+
end
|
data/lib/amonitor.rb
ADDED
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: amonitor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Alex Zalantai
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rdoc
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: aruba
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: highline
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: aws-sdk
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: awesome_print
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rainbow
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: gli
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.14.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - '='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 2.14.0
|
125
|
+
description:
|
126
|
+
email: alex.zalantai@bjss.com
|
127
|
+
executables:
|
128
|
+
- amonitor
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files:
|
131
|
+
- README.rdoc
|
132
|
+
- amonitor.rdoc
|
133
|
+
files:
|
134
|
+
- ".gitignore"
|
135
|
+
- Gemfile
|
136
|
+
- Gemfile.lock
|
137
|
+
- README.rdoc
|
138
|
+
- Rakefile
|
139
|
+
- amonitor.gemspec
|
140
|
+
- amonitor.rdoc
|
141
|
+
- aws_monitor/AwsCredentialConfiguration.rb
|
142
|
+
- aws_monitor/AwsTresholdManager.rb
|
143
|
+
- bin/amonitor
|
144
|
+
- features/amonitor.feature
|
145
|
+
- features/step_definitions/amonitor_steps.rb
|
146
|
+
- features/support/env.rb
|
147
|
+
- lib/amonitor.rb
|
148
|
+
- lib/amonitor/version.rb
|
149
|
+
- test/default_test.rb
|
150
|
+
- test/test_helper.rb
|
151
|
+
homepage: http://bjss.com
|
152
|
+
licenses: []
|
153
|
+
metadata: {}
|
154
|
+
post_install_message:
|
155
|
+
rdoc_options:
|
156
|
+
- "--title"
|
157
|
+
- amonitor
|
158
|
+
- "--main"
|
159
|
+
- README.rdoc
|
160
|
+
- "-ri"
|
161
|
+
require_paths:
|
162
|
+
- lib
|
163
|
+
- lib
|
164
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
165
|
+
requirements:
|
166
|
+
- - ">="
|
167
|
+
- !ruby/object:Gem::Version
|
168
|
+
version: '0'
|
169
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
requirements: []
|
175
|
+
rubyforge_project:
|
176
|
+
rubygems_version: 2.5.1
|
177
|
+
signing_key:
|
178
|
+
specification_version: 4
|
179
|
+
summary: BJSS Availability Monitor
|
180
|
+
test_files: []
|