sensu-plugins-aws 0.0.1.alpha.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
- checksums.yaml.gz.sig +2 -0
- data/CHANGELOG.md +15 -0
- data/LICENSE +22 -0
- data/README.md +125 -0
- data/bin/autoscaling-instance-count-metrics.rb +87 -0
- data/bin/check-dynamodb-capacity.rb +183 -0
- data/bin/check-dynamodb-throttle.rb +177 -0
- data/bin/check-ec2-network.rb +131 -0
- data/bin/check-elb-certs.rb +149 -0
- data/bin/check-elb-health-fog.rb +121 -0
- data/bin/check-elb-health-sdk.rb +124 -0
- data/bin/check-elb-health.rb +122 -0
- data/bin/check-elb-latency.rb +175 -0
- data/bin/check-elb-nodes.rb +145 -0
- data/bin/check-elb-sum-requests.rb +168 -0
- data/bin/check-instance-events.rb +130 -0
- data/bin/check-rds-events.rb +84 -0
- data/bin/check-rds.rb +251 -0
- data/bin/check-redshift-events.rb +120 -0
- data/bin/check-ses-limit.rb +91 -0
- data/bin/check-sqs-messages.rb +107 -0
- data/bin/check_vpc_vpn.py +42 -0
- data/bin/ec2-count-metrics.rb +144 -0
- data/bin/ec2-node.rb +157 -0
- data/bin/elasticache-metrics.rb +200 -0
- data/bin/elb-full-metrics.rb +144 -0
- data/bin/elb-latency-metrics.rb +150 -0
- data/bin/elb-metrics.rb +150 -0
- data/bin/sqs-metrics.rb +84 -0
- data/lib/sensu-plugins-AWS.rb +7 -0
- data.tar.gz.sig +0 -0
- metadata +330 -0
- metadata.gz.sig +0 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: dab7adef4e04f7bc487ae96de657558e16cd94e5
|
|
4
|
+
data.tar.gz: d80911aa488f0ff85b48d4a4be995824af92b262
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 4ee5d2b5f5a54f359f868030fea933111d3cb403e85ace06719259893c658e6d7c973b3bef29e9d75b98df4566d99a627ad873bb994420d14f89d00e88853cc9
|
|
7
|
+
data.tar.gz: 802d9264b64bc401da0606273e34c15423ef56b9d81c18f28283be11d489c0cdbbf9f9bda77f4f61916dd8ef10ea5ac505f3f299ce4586937095ddac4a688905
|
checksums.yaml.gz.sig
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#### 0.1.0.alpha.1
|
|
2
|
+
|
|
3
|
+
* baseline release identical to **sensu-community-plugins** repo
|
|
4
|
+
* removed check-vpc-vpn.py
|
|
5
|
+
* built against 1.9.3, 2.0, 2.1
|
|
6
|
+
* change the ec2_node.rb to ec2-node.rb
|
|
7
|
+
|
|
8
|
+
#### 0.0.1.alpha.2
|
|
9
|
+
|
|
10
|
+
* add pry as a development dependency
|
|
11
|
+
* add new badge for dependencies
|
|
12
|
+
* add irc integration
|
|
13
|
+
* updated install instructions
|
|
14
|
+
* added check-vpc-vpn.py (may be removed before first stable release)
|
|
15
|
+
* pulled latest script version from community repo
|
data/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2015 devops@yieldbot.com
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
## Sensu-Plugins-aws
|
|
2
|
+
|
|
3
|
+
[](https://travis-ci.org/sensu-plugins/sensu-plugins-aws)
|
|
4
|
+
[](http://badge.fury.io/rb/sensu-plugins-aws)
|
|
5
|
+
[](https://codeclimate.com/github/sensu-plugins/sensu-plugins-aws)
|
|
6
|
+
[](https://codeclimate.com/github/sensu-plugins/sensu-plugins-aws)
|
|
7
|
+
[](https://gemnasium.com/sensu-plugins/sensu-plugins-aws)
|
|
8
|
+
|
|
9
|
+
## Functionality
|
|
10
|
+
|
|
11
|
+
**check_vpc_vpn**
|
|
12
|
+
|
|
13
|
+
**autoscaling-instance-count-metrics.rb**
|
|
14
|
+
|
|
15
|
+
**check-dynamodb-capacity.rb**
|
|
16
|
+
|
|
17
|
+
**check-dynamodb-throttle.rb**
|
|
18
|
+
|
|
19
|
+
**check-ec2-network.rb**
|
|
20
|
+
|
|
21
|
+
**check-elb-certs.rb**
|
|
22
|
+
|
|
23
|
+
**check-elb-health-fog.rb**
|
|
24
|
+
|
|
25
|
+
**check-elb-health-sdk.rb**
|
|
26
|
+
|
|
27
|
+
**check-elb-latency.rb**
|
|
28
|
+
|
|
29
|
+
**check-elb-nodes.rb**
|
|
30
|
+
|
|
31
|
+
**check-elb-sum-requests.rb**
|
|
32
|
+
|
|
33
|
+
**check-instance-events.rb**
|
|
34
|
+
|
|
35
|
+
**check-rds-events.rb**
|
|
36
|
+
|
|
37
|
+
**check-rds.rb**
|
|
38
|
+
|
|
39
|
+
**check-redshift-events.rb**
|
|
40
|
+
|
|
41
|
+
**check-ses-limit.rb**
|
|
42
|
+
|
|
43
|
+
**check-sqs-messages.rb**
|
|
44
|
+
|
|
45
|
+
**ec2-count-metrics.rb**
|
|
46
|
+
|
|
47
|
+
**ec2-node.rb**
|
|
48
|
+
|
|
49
|
+
**elasticache-metrics.rb**
|
|
50
|
+
|
|
51
|
+
**elb-full-metrics.rb**
|
|
52
|
+
|
|
53
|
+
**elb-latency-metrics.rb**
|
|
54
|
+
|
|
55
|
+
**elb-metrics.rb**
|
|
56
|
+
|
|
57
|
+
**sqs-metrics.rb**
|
|
58
|
+
|
|
59
|
+
## Files
|
|
60
|
+
|
|
61
|
+
* /bin/check_vpc_vpn
|
|
62
|
+
* /bin/autoscaling-instance-count-metrics.rb
|
|
63
|
+
* /bin/check-dynamodb-capacity.rb
|
|
64
|
+
* /bin/check-dynamodb-throttle.rb
|
|
65
|
+
* /bin/check-ec2-network.rb
|
|
66
|
+
* /bin/check-elb-certs.rb
|
|
67
|
+
* /bin/check-elb-health-fog.rb
|
|
68
|
+
* /bin/check-elb-health-sdk.rb
|
|
69
|
+
* /bin/check-elb-latency.rb
|
|
70
|
+
* /bin/check-elb-nodes.rb
|
|
71
|
+
* /bin/check-elb-sum-requests.rb
|
|
72
|
+
* /bin/check-instance-events.rb
|
|
73
|
+
* /bin/check-rds-events.rb
|
|
74
|
+
* /bin/check-rds.rb
|
|
75
|
+
* /bin/check-redshift-events.rb
|
|
76
|
+
* /bin/check-ses-limit.rb
|
|
77
|
+
* /bin/check-sqs-messages.rb
|
|
78
|
+
* /bin/ec2-count-metrics.rb
|
|
79
|
+
* /bin/ec2-node.rb
|
|
80
|
+
* /bin/elasticache-metrics.rb
|
|
81
|
+
* /bin/elb-full-metrics.rb
|
|
82
|
+
* /bin/elb-latency-metrics.rb
|
|
83
|
+
* /bin/elb-metrics.rb
|
|
84
|
+
* /bin/sqs-metrics.rb
|
|
85
|
+
|
|
86
|
+
## Usage
|
|
87
|
+
|
|
88
|
+
## Installation
|
|
89
|
+
|
|
90
|
+
Add the public key (if you haven’t already) as a trusted certificate
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
gem cert --add <(curl -Ls https://raw.githubusercontent.com/sensu-plugins/sensu-plugins.github.io/master/certs/sensu-plugins.pem)
|
|
94
|
+
gem install <gem> -P MediumSecurity
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
You can also download the key from /certs/ within each repository.
|
|
98
|
+
|
|
99
|
+
#### Rubygems
|
|
100
|
+
|
|
101
|
+
`gem install sensu-plugins-aws`
|
|
102
|
+
|
|
103
|
+
#### Bundler
|
|
104
|
+
|
|
105
|
+
Add *sensu-plugins-aws* to your Gemfile and run `bundle install` or `bundle update`
|
|
106
|
+
|
|
107
|
+
#### Chef
|
|
108
|
+
|
|
109
|
+
Using the Sensu **sensu_gem** LWRP
|
|
110
|
+
```
|
|
111
|
+
sensu_gem 'sensu-plugins-aws' do
|
|
112
|
+
options('--prerelease')
|
|
113
|
+
version '0.0.1.alpha.2'
|
|
114
|
+
end
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Using the Chef **gem_package** resource
|
|
118
|
+
```
|
|
119
|
+
gem_package 'sensu-plugins-process-checks' do
|
|
120
|
+
options('--prerelease')
|
|
121
|
+
version '0.0.1.alpha.2'
|
|
122
|
+
end
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Notes
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# autoscaling-instance-count-metrics
|
|
4
|
+
#
|
|
5
|
+
# DESCRIPTION:
|
|
6
|
+
# Get a count of instances in a given AutoScaling group
|
|
7
|
+
#
|
|
8
|
+
# OUTPUT:
|
|
9
|
+
# metric-data
|
|
10
|
+
#
|
|
11
|
+
# PLATFORMS:
|
|
12
|
+
# Linux
|
|
13
|
+
#
|
|
14
|
+
# DEPENDENCIES:
|
|
15
|
+
# gem: aws-sdk
|
|
16
|
+
# gem: sensu-plugin
|
|
17
|
+
#
|
|
18
|
+
# USAGE:
|
|
19
|
+
#
|
|
20
|
+
# NOTES:
|
|
21
|
+
#
|
|
22
|
+
# LICENSE:
|
|
23
|
+
# Copyright 2013 Bashton Ltd http://www.bashton.com/
|
|
24
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
|
25
|
+
# for details.
|
|
26
|
+
#
|
|
27
|
+
|
|
28
|
+
require 'rubygems' if RUBY_VERSION < '1.9.0'
|
|
29
|
+
require 'sensu-plugin/metric/cli'
|
|
30
|
+
require 'aws-sdk'
|
|
31
|
+
|
|
32
|
+
class AutoScalingInstanceCountMetrics < Sensu::Plugin::Metric::CLI::Graphite
|
|
33
|
+
option :groupname,
|
|
34
|
+
description: 'Name of the AutoScaling group',
|
|
35
|
+
short: '-g GROUP_NAME',
|
|
36
|
+
long: '--autoscaling-group GROUP_NAME',
|
|
37
|
+
required: true
|
|
38
|
+
|
|
39
|
+
option :scheme,
|
|
40
|
+
description: 'Metric naming scheme, text to prepend to metric',
|
|
41
|
+
short: '-s SCHEME',
|
|
42
|
+
long: '--scheme SCHEME',
|
|
43
|
+
default: ''
|
|
44
|
+
|
|
45
|
+
option :aws_access_key,
|
|
46
|
+
short: '-a AWS_ACCESS_KEY',
|
|
47
|
+
long: '--aws-access-key AWS_ACCESS_KEY',
|
|
48
|
+
description: "AWS Access Key. Either set ENV['AWS_ACCESS_KEY_ID'] or provide it as an option",
|
|
49
|
+
default: ENV['AWS_ACCESS_KEY']
|
|
50
|
+
|
|
51
|
+
option :aws_secret_access_key,
|
|
52
|
+
short: '-k AWS_SECRET_ACCESS_KEY',
|
|
53
|
+
long: '--aws-secret-access-key AWS_SECRET_ACCESS_KEY',
|
|
54
|
+
description: "AWS Secret Access Key. Either set ENV['AWS_SECRET_ACCESS_KEY'] or provide it as an option",
|
|
55
|
+
default: ENV['AWS_SECRET_KEY']
|
|
56
|
+
|
|
57
|
+
option :aws_region,
|
|
58
|
+
short: '-r AWS_REGION',
|
|
59
|
+
long: '--aws-region REGION',
|
|
60
|
+
description: 'AWS Region (such as eu-west-1).',
|
|
61
|
+
default: 'us-east-1'
|
|
62
|
+
|
|
63
|
+
def aws_config
|
|
64
|
+
hash = {}
|
|
65
|
+
hash.update aws_access_key_id: config[:aws_access_key], aws_secret_access_key: config[:aws_secret_access_key]\
|
|
66
|
+
if config[:aws_access_key] && config[:aws_secret_access_key]
|
|
67
|
+
hash.update region: config[:aws_region]
|
|
68
|
+
hash
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def run
|
|
72
|
+
if config[:scheme] == ''
|
|
73
|
+
graphitepath = "#{config[:groupname]}.autoscaling.instance_count"
|
|
74
|
+
else
|
|
75
|
+
graphitepath = config[:scheme]
|
|
76
|
+
end
|
|
77
|
+
begin
|
|
78
|
+
as = AWS::AutoScaling.new aws_config
|
|
79
|
+
count = as.groups[config[:groupname]].auto_scaling_instances.map(&:lifecycle_state).count('InService')
|
|
80
|
+
output graphitepath, count
|
|
81
|
+
rescue => e
|
|
82
|
+
puts "Error: exception: #{e}"
|
|
83
|
+
critical
|
|
84
|
+
end
|
|
85
|
+
ok
|
|
86
|
+
end
|
|
87
|
+
end
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# check-dynamodb-capacity
|
|
4
|
+
#
|
|
5
|
+
# DESCRIPTION:
|
|
6
|
+
# Check DynamoDB statuses by CloudWatch and DynamoDB API.
|
|
7
|
+
#
|
|
8
|
+
# OUTPUT:
|
|
9
|
+
# plain-text
|
|
10
|
+
#
|
|
11
|
+
# PLATFORMS:
|
|
12
|
+
# Linux
|
|
13
|
+
#
|
|
14
|
+
# DEPENDENCIES:
|
|
15
|
+
# gem: aws-sdk
|
|
16
|
+
# gem: time
|
|
17
|
+
# gem: sensu-plugin
|
|
18
|
+
#
|
|
19
|
+
# USAGE:
|
|
20
|
+
# Warning if any table's consumed read/write capacity is over 80%, critical if over 90%
|
|
21
|
+
# check-dynamodb-capacity --warning-over 80 --critical-over 90
|
|
22
|
+
#
|
|
23
|
+
# Critical if session table's consumed read capacity is over 90%, maximum of last one hour
|
|
24
|
+
# check-dynamodb-capacity --table_names session --capacity-for read --critical-over 90 --statistics maximum --period 3600
|
|
25
|
+
#
|
|
26
|
+
# NOTES:
|
|
27
|
+
#
|
|
28
|
+
# LICENSE:
|
|
29
|
+
# Copyright 2014 github.com/y13i
|
|
30
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
|
31
|
+
# for details.
|
|
32
|
+
#
|
|
33
|
+
|
|
34
|
+
require 'rubygems' if RUBY_VERSION < '1.9.0'
|
|
35
|
+
require 'sensu-plugin/check/cli'
|
|
36
|
+
require 'aws-sdk'
|
|
37
|
+
require 'time'
|
|
38
|
+
|
|
39
|
+
class CheckDynamoDB < Sensu::Plugin::Check::CLI
|
|
40
|
+
option :access_key_id,
|
|
41
|
+
short: '-k N',
|
|
42
|
+
long: '--access-key-id ID',
|
|
43
|
+
description: 'AWS access key ID'
|
|
44
|
+
|
|
45
|
+
option :secret_access_key,
|
|
46
|
+
short: '-s N',
|
|
47
|
+
long: '--secret-access-key KEY',
|
|
48
|
+
description: 'AWS secret access key'
|
|
49
|
+
|
|
50
|
+
option :region,
|
|
51
|
+
short: '-r R',
|
|
52
|
+
long: '--region REGION',
|
|
53
|
+
description: 'AWS region'
|
|
54
|
+
|
|
55
|
+
option :table_names,
|
|
56
|
+
short: '-t N',
|
|
57
|
+
long: '--table-names NAMES',
|
|
58
|
+
proc: proc { |a| a.split(/[,;]\s*/) },
|
|
59
|
+
description: 'Table names to check. Separated by , or ;. If not specified, check all tables'
|
|
60
|
+
|
|
61
|
+
option :end_time,
|
|
62
|
+
short: '-t T',
|
|
63
|
+
long: '--end-time TIME',
|
|
64
|
+
default: Time.now,
|
|
65
|
+
proc: proc { |a| Time.parse a },
|
|
66
|
+
description: 'CloudWatch metric statistics end time'
|
|
67
|
+
|
|
68
|
+
option :period,
|
|
69
|
+
short: '-p N',
|
|
70
|
+
long: '--period SECONDS',
|
|
71
|
+
default: 60,
|
|
72
|
+
# #YELLOW
|
|
73
|
+
proc: proc(&:to_i),
|
|
74
|
+
description: 'CloudWatch metric statistics period'
|
|
75
|
+
|
|
76
|
+
option :statistics,
|
|
77
|
+
short: '-S N',
|
|
78
|
+
long: '--statistics NAME',
|
|
79
|
+
default: :average,
|
|
80
|
+
proc: proc { |a| a.downcase.intern },
|
|
81
|
+
description: 'CloudWatch statistics method'
|
|
82
|
+
|
|
83
|
+
option :capacity_for,
|
|
84
|
+
short: '-c N',
|
|
85
|
+
long: '--capacity-for NAME',
|
|
86
|
+
default: [:read, :write],
|
|
87
|
+
proc: proc { |a| a.split(/[,;]\s*/).map { |n| n.downcase.intern } },
|
|
88
|
+
description: 'Read/Write (or both) capacity to check.'
|
|
89
|
+
|
|
90
|
+
%w(warning critical).each do |severity|
|
|
91
|
+
option :"#{severity}_over",
|
|
92
|
+
long: "--#{severity}-over N",
|
|
93
|
+
# #YELLOW
|
|
94
|
+
proc: proc(&:to_f),
|
|
95
|
+
description: "Trigger a #{severity} if consumed capacity is over a percentage"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def aws_config
|
|
99
|
+
hash = {}
|
|
100
|
+
hash.update access_key_id: config[:access_key_id], secret_access_key: config[:secret_access_key] if config[:access_key_id] && config[:secret_access_key]
|
|
101
|
+
hash.update region: config[:region] if config[:region]
|
|
102
|
+
hash
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def dynamo_db
|
|
106
|
+
@dynamo_db ||= AWS::DynamoDB.new aws_config
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def cloud_watch
|
|
110
|
+
@cloud_watch ||= AWS::CloudWatch.new aws_config
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def tables
|
|
114
|
+
return @tables if @tables
|
|
115
|
+
@tables = dynamo_db.tables.to_a
|
|
116
|
+
@tables.select! { |table| config[:table_names].include? table.name } if config[:table_names]
|
|
117
|
+
@tables
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def cloud_watch_metric(metric_name, table_name)
|
|
121
|
+
cloud_watch.metrics.with_namespace('AWS/DynamoDB').with_metric_name(metric_name).with_dimensions(name: 'TableName', value: table_name).first
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def statistics_options
|
|
125
|
+
{
|
|
126
|
+
start_time: config[:end_time] - config[:period],
|
|
127
|
+
end_time: config[:end_time],
|
|
128
|
+
statistics: [config[:statistics].to_s.capitalize],
|
|
129
|
+
period: config[:period]
|
|
130
|
+
}
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def latest_value(metric)
|
|
134
|
+
metric.statistics(statistics_options.merge unit: 'Count').datapoints.sort_by { |datapoint| datapoint[:timestamp] }.last[config[:statistics]]
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def flag_alert(severity, message)
|
|
138
|
+
@severities[severity] = true
|
|
139
|
+
@message += message
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def check_capacity(table)
|
|
143
|
+
config[:capacity_for].each do |r_or_w|
|
|
144
|
+
metric_name = "Consumed#{r_or_w.to_s.capitalize}CapacityUnits"
|
|
145
|
+
metric = cloud_watch_metric metric_name, table.name
|
|
146
|
+
metric_value = begin
|
|
147
|
+
latest_value(metric)
|
|
148
|
+
rescue
|
|
149
|
+
0
|
|
150
|
+
end
|
|
151
|
+
percentage = metric_value / table.send("#{r_or_w}_capacity_units").to_f * 100
|
|
152
|
+
|
|
153
|
+
@severities.keys.each do |severity|
|
|
154
|
+
threshold = config[:"#{severity}_over"]
|
|
155
|
+
next unless threshold
|
|
156
|
+
next if percentage < threshold
|
|
157
|
+
flag_alert severity, "; On table #{table.name} consumed #{r_or_w} capacity is #{sprintf '%.2f', percentage}% (expected_lower_than #{threshold})"
|
|
158
|
+
break
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def run
|
|
164
|
+
@message = "#{tables.size} tables total"
|
|
165
|
+
@severities = {
|
|
166
|
+
critical: false,
|
|
167
|
+
warning: false
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
tables.each { |table| check_capacity table }
|
|
171
|
+
|
|
172
|
+
@message += "; (#{config[:statistics].to_s.capitalize} within #{config[:period]} seconds "
|
|
173
|
+
@message += "between #{config[:end_time] - config[:period]} to #{config[:end_time]})"
|
|
174
|
+
|
|
175
|
+
if @severities[:critical]
|
|
176
|
+
critical @message
|
|
177
|
+
elsif @severities[:warning]
|
|
178
|
+
warning @message
|
|
179
|
+
else
|
|
180
|
+
ok @message
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
#
|
|
3
|
+
# check-dynamodb-throttle
|
|
4
|
+
#
|
|
5
|
+
# DESCRIPTION:
|
|
6
|
+
# Check DynamoDB throttle by CloudWatch and DynamoDB API.
|
|
7
|
+
#
|
|
8
|
+
# OUTPUT:
|
|
9
|
+
# plain-text
|
|
10
|
+
#
|
|
11
|
+
# PLATFORMS:
|
|
12
|
+
# Linux
|
|
13
|
+
#
|
|
14
|
+
# DEPENDENCIES:
|
|
15
|
+
# gem: aws-sdk
|
|
16
|
+
# gem: time
|
|
17
|
+
# gem: sensu-plugin
|
|
18
|
+
#
|
|
19
|
+
# USAGE:
|
|
20
|
+
# Critical if session table's read throttle is over 50 for the last 5 minutes
|
|
21
|
+
# check-dynamodb-throttle --table_names session --throttle-for read --critical-over 50 --statistics sum --period 300
|
|
22
|
+
#
|
|
23
|
+
# NOTES:
|
|
24
|
+
#
|
|
25
|
+
# LICENSE:
|
|
26
|
+
# Copyright 2014 Sonian, Inc. and contributors. <support@sensuapp.org>
|
|
27
|
+
# Released under the same terms as Sensu (the MIT license); see LICENSE
|
|
28
|
+
# for details.
|
|
29
|
+
#
|
|
30
|
+
|
|
31
|
+
require 'rubygems' if RUBY_VERSION < '1.9.0'
|
|
32
|
+
require 'sensu-plugin/check/cli'
|
|
33
|
+
require 'aws-sdk'
|
|
34
|
+
require 'time'
|
|
35
|
+
|
|
36
|
+
class CheckDynamoDB < Sensu::Plugin::Check::CLI
|
|
37
|
+
option :access_key_id,
|
|
38
|
+
short: '-k N',
|
|
39
|
+
long: '--access-key-id ID',
|
|
40
|
+
description: 'AWS access key ID'
|
|
41
|
+
|
|
42
|
+
option :secret_access_key,
|
|
43
|
+
short: '-s N',
|
|
44
|
+
long: '--secret-access-key KEY',
|
|
45
|
+
description: 'AWS secret access key'
|
|
46
|
+
|
|
47
|
+
option :region,
|
|
48
|
+
short: '-r R',
|
|
49
|
+
long: '--region REGION',
|
|
50
|
+
description: 'AWS region'
|
|
51
|
+
|
|
52
|
+
option :table_names,
|
|
53
|
+
short: '-t N',
|
|
54
|
+
long: '--table-names NAMES',
|
|
55
|
+
proc: proc { |a| a.split(/[,;]\s*/) },
|
|
56
|
+
description: 'Table names to check. Separated by , or ;. If not specified, check all tables'
|
|
57
|
+
|
|
58
|
+
option :end_time,
|
|
59
|
+
short: '-t T',
|
|
60
|
+
long: '--end-time TIME',
|
|
61
|
+
default: Time.now,
|
|
62
|
+
proc: proc { |a| Time.parse a },
|
|
63
|
+
description: 'CloudWatch metric statistics end time'
|
|
64
|
+
|
|
65
|
+
option :period,
|
|
66
|
+
short: '-p N',
|
|
67
|
+
long: '--period SECONDS',
|
|
68
|
+
default: 60,
|
|
69
|
+
proc: proc(&:to_i),
|
|
70
|
+
description: 'CloudWatch metric statistics period'
|
|
71
|
+
|
|
72
|
+
option :statistics,
|
|
73
|
+
short: '-S N',
|
|
74
|
+
long: '--statistics NAME',
|
|
75
|
+
default: :average,
|
|
76
|
+
proc: proc { |a| a.downcase.intern },
|
|
77
|
+
description: 'CloudWatch statistics method'
|
|
78
|
+
|
|
79
|
+
option :throttle_for,
|
|
80
|
+
short: '-c N',
|
|
81
|
+
long: '--throttle-for NAME',
|
|
82
|
+
default: [:read, :write],
|
|
83
|
+
proc: proc { |a| a.split(/[,;]\s*/).map { |n| n.downcase.intern } },
|
|
84
|
+
description: 'Read/Write (or both) throttle to check.'
|
|
85
|
+
|
|
86
|
+
%w(warning critical).each do |severity|
|
|
87
|
+
option :"#{severity}_over",
|
|
88
|
+
long: "--#{severity}-over N",
|
|
89
|
+
proc: proc(&:to_f),
|
|
90
|
+
description: "Trigger a #{severity} if throttle is over the given number"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def aws_config
|
|
94
|
+
hash = {}
|
|
95
|
+
hash.update access_key_id: config[:access_key_id], secret_access_key: config[:secret_access_key] if config[:access_key_id] && config[:secret_access_key]
|
|
96
|
+
hash.update region: config[:region] if config[:region]
|
|
97
|
+
hash
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def dynamo_db
|
|
101
|
+
@dynamo_db ||= AWS::DynamoDB.new aws_config
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def cloud_watch
|
|
105
|
+
@cloud_watch ||= AWS::CloudWatch.new aws_config
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def tables
|
|
109
|
+
return @tables if @tables
|
|
110
|
+
@tables = dynamo_db.tables.to_a
|
|
111
|
+
@tables.select! { |table| config[:table_names].include? table.name } if config[:table_names]
|
|
112
|
+
@tables
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def cloud_watch_metric(metric_name, table_name)
|
|
116
|
+
cloud_watch.metrics.with_namespace('AWS/DynamoDB').with_metric_name(metric_name).with_dimensions(name: 'TableName', value: table_name).first
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def statistics_options
|
|
120
|
+
{
|
|
121
|
+
start_time: config[:end_time] - config[:period],
|
|
122
|
+
end_time: config[:end_time],
|
|
123
|
+
statistics: [config[:statistics].to_s.capitalize],
|
|
124
|
+
period: config[:period]
|
|
125
|
+
}
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def latest_value(metric)
|
|
129
|
+
metric.statistics(statistics_options.merge unit: 'Count').datapoints.sort_by { |datapoint| datapoint[:timestamp] }.last[config[:statistics]]
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def flag_alert(severity, message)
|
|
133
|
+
@severities[severity] = true
|
|
134
|
+
@message += message
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def check_throttle(table)
|
|
138
|
+
config[:throttle_for].each do |r_or_w|
|
|
139
|
+
metric_name = "#{r_or_w.to_s.capitalize}ThrottleEvents"
|
|
140
|
+
metric = cloud_watch_metric metric_name, table.name
|
|
141
|
+
metric_value = begin
|
|
142
|
+
latest_value(metric)
|
|
143
|
+
rescue
|
|
144
|
+
0
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
@severities.keys.each do |severity|
|
|
148
|
+
threshold = config[:"#{severity}_over"]
|
|
149
|
+
next unless threshold
|
|
150
|
+
next if metric_value < threshold
|
|
151
|
+
flag_alert severity, "; On table #{table.name} #{r_or_w.to_s.capitalize}ThrottleEvents is #{metric_value} (higher_than #{threshold})"
|
|
152
|
+
break
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def run
|
|
158
|
+
@message = "#{tables.size} tables total"
|
|
159
|
+
@severities = {
|
|
160
|
+
critical: false,
|
|
161
|
+
warning: false
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
tables.each { |table| check_throttle table }
|
|
165
|
+
|
|
166
|
+
@message += "; (#{config[:statistics].to_s.capitalize} within #{config[:period]} seconds "
|
|
167
|
+
@message += "between #{config[:end_time] - config[:period]} to #{config[:end_time]})"
|
|
168
|
+
|
|
169
|
+
if @severities[:critical]
|
|
170
|
+
critical @message
|
|
171
|
+
elsif @severities[:warning]
|
|
172
|
+
warning @message
|
|
173
|
+
else
|
|
174
|
+
ok @message
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|