aws-alert-monitor 0.0.4 → 0.0.5
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/CHANGELOG +5 -0
- data/README.md +30 -1
- data/lib/aws-alert-monitor.rb +7 -0
- data/lib/aws-alert-monitor/alert.rb +19 -23
- data/lib/aws-alert-monitor/emailer.rb +33 -0
- data/lib/aws-alert-monitor/event.rb +32 -0
- data/lib/aws-alert-monitor/event_classifier.rb +35 -0
- data/lib/aws-alert-monitor/events.rb +3 -0
- data/lib/aws-alert-monitor/events/auto_scaling_notification.rb +23 -0
- data/lib/aws-alert-monitor/events/cloud_watch_alarm.rb +48 -0
- data/lib/aws-alert-monitor/events/unknown.rb +21 -0
- data/lib/aws-alert-monitor/version.rb +1 -1
- data/spec/alert_spec.rb +42 -13
- data/spec/emailer_spec.rb +29 -0
- data/spec/event_classifier_spec.rb +36 -0
- data/spec/event_spec.rb +29 -0
- data/spec/events/auto_scaling_notification_spec.rb +33 -0
- data/spec/events/cloud_watch_alarm_spec.rb +30 -0
- data/spec/events/unknown_spec.rb +28 -0
- data/spec/fixtures/asg_instance_launch.json +12 -0
- data/spec/fixtures/cloud_watch_alarm.json +12 -0
- data/spec/helpers/fixtures.rb +8 -0
- data/spec/spec_helper.rb +4 -0
- metadata +35 -10
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -5,8 +5,9 @@
|
|
5
5
|
AWS Alert Monitor listenting to an SQS queue for alarms and sends email via SES based on rules applied in ~/.aws-alert-monitor.yml to those alerts.
|
6
6
|
|
7
7
|
## Installation
|
8
|
-
|
8
|
+
```
|
9
9
|
gem install aws-alert-monitor
|
10
|
+
```
|
10
11
|
|
11
12
|
## Usage
|
12
13
|
|
@@ -37,6 +38,34 @@ app2:
|
|
37
38
|
destination: user@escalation.com
|
38
39
|
```
|
39
40
|
|
41
|
+
### Supported Event Types
|
42
|
+
Currently, this gem supports the following event types:
|
43
|
+
|
44
|
+
#### Auto Scaling
|
45
|
+
* autoscaling:EC2_INSTANCE_LAUNCH
|
46
|
+
* autoscaling:EC2_INSTANCE_LAUNCH_ERROR
|
47
|
+
* autoscaling:EC2_INSTANCE_TERMINATE
|
48
|
+
* autoscaling:EC2_INSTANCE_TERMINATE_ERROR
|
49
|
+
|
50
|
+
#### CloudWatch
|
51
|
+
Cloud watch support is somewhat generic. The event pattern is:
|
52
|
+
```
|
53
|
+
cloudwatch:$metric_namespace-$metric_name
|
54
|
+
```
|
55
|
+
|
56
|
+
For example:
|
57
|
+
```
|
58
|
+
cloudwatch:AWS/SQS-ApproximateNumberOfMessagesVisible
|
59
|
+
```
|
60
|
+
|
61
|
+
#### Unknown
|
62
|
+
If a message does not match one of the above types, then it will be classified as unknown.
|
63
|
+
|
64
|
+
You can control the notification of these messages with:
|
65
|
+
```
|
66
|
+
unknown
|
67
|
+
```
|
68
|
+
|
40
69
|
## Contributing
|
41
70
|
|
42
71
|
1. Fork it
|
data/lib/aws-alert-monitor.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
require "aws-alert-monitor/alert"
|
2
2
|
require "aws-alert-monitor/aws"
|
3
3
|
require "aws-alert-monitor/config"
|
4
|
+
require "aws-alert-monitor/emailer"
|
5
|
+
require "aws-alert-monitor/event"
|
6
|
+
require "aws-alert-monitor/event_classifier"
|
7
|
+
require "aws-alert-monitor/events"
|
8
|
+
require "aws-alert-monitor/events/auto_scaling_notification"
|
9
|
+
require "aws-alert-monitor/events/cloud_watch_alarm"
|
10
|
+
require "aws-alert-monitor/events/unknown"
|
4
11
|
require "aws-alert-monitor/logger"
|
5
12
|
require "aws-alert-monitor/parser"
|
6
13
|
require "aws-alert-monitor/version"
|
@@ -13,7 +13,7 @@ module AwsAlertMonitor
|
|
13
13
|
@events = args[:events]
|
14
14
|
@message = args[:message]
|
15
15
|
|
16
|
-
unless process_message
|
16
|
+
unless process_message
|
17
17
|
@logger.error "Unable to process message."
|
18
18
|
return false
|
19
19
|
end
|
@@ -32,47 +32,43 @@ module AwsAlertMonitor
|
|
32
32
|
|
33
33
|
if @message_destination
|
34
34
|
@logger.info "Sending alert to #{@message_destination}."
|
35
|
-
|
35
|
+
send_email
|
36
36
|
else
|
37
37
|
@logger.info "Destination not set, no message sent."
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def email_options
|
42
|
-
{
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
:body => {
|
48
|
-
:text => {
|
49
|
-
:data => @message_data
|
50
|
-
}
|
51
|
-
}
|
52
|
-
}
|
42
|
+
{
|
43
|
+
'body' => @message_data,
|
44
|
+
'from' => @message_source,
|
45
|
+
'subject' => @message_subject,
|
46
|
+
'to' => Array(@message_destination)
|
53
47
|
}
|
54
48
|
end
|
55
49
|
|
56
|
-
def
|
50
|
+
def event_classifier
|
51
|
+
AwsAlertMonitor::EventClassifier.new @message
|
52
|
+
end
|
53
|
+
|
54
|
+
def process_message
|
57
55
|
begin
|
58
|
-
|
59
|
-
message_details = JSON.parse message_body['Message']
|
56
|
+
event = event_classifier.event
|
60
57
|
rescue JSON::ParserError => e
|
61
58
|
@logger.error e.message
|
62
59
|
return false
|
63
60
|
end
|
64
61
|
|
65
|
-
@
|
66
|
-
@
|
67
|
-
@
|
68
|
-
@message_subject = message_body['Subject']
|
69
|
-
@message_data = "#{@name} received alert: \n\n #{@message_description} \n\n #{@message_cause}"
|
62
|
+
@message_event = event.type
|
63
|
+
@message_subject = event.subject
|
64
|
+
@message_data = "#{@name} #{event.body}"
|
70
65
|
|
71
66
|
true
|
72
67
|
end
|
73
68
|
|
74
|
-
def
|
75
|
-
|
69
|
+
def send_email
|
70
|
+
AwsAlertMonitor::Emailer.new(email_options).send_email
|
76
71
|
end
|
72
|
+
|
77
73
|
end
|
78
74
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module AwsAlertMonitor
|
2
|
+
|
3
|
+
class Emailer
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
@body = args['body']
|
7
|
+
@emailer = args['emailer']
|
8
|
+
@from = args['from']
|
9
|
+
@subject = args['subject']
|
10
|
+
@to = Array(args['to'])
|
11
|
+
end
|
12
|
+
|
13
|
+
def send_email
|
14
|
+
emailer.send_email email_options
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def email_options
|
19
|
+
{
|
20
|
+
:source => @from,
|
21
|
+
:destination => { :to_addresses => @to },
|
22
|
+
:message => { :subject => { :data => @subject },
|
23
|
+
:body => { :text => { :data => @body } } }
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def emailer
|
28
|
+
@emailer ||= AwsAlertMonitor::AWS::SES.new
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module AwsAlertMonitor
|
2
|
+
|
3
|
+
class Event
|
4
|
+
|
5
|
+
attr_reader :message_data
|
6
|
+
attr_reader :raw_data
|
7
|
+
|
8
|
+
def initialize(message)
|
9
|
+
@raw_data = JSON.parse(message)
|
10
|
+
@message_data = determine_message_data
|
11
|
+
end
|
12
|
+
|
13
|
+
def body
|
14
|
+
raise NotImplementedError
|
15
|
+
end
|
16
|
+
|
17
|
+
def subject
|
18
|
+
@raw_data['Subject']
|
19
|
+
end
|
20
|
+
|
21
|
+
def type
|
22
|
+
raise NotImplementedError
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def determine_message_data
|
27
|
+
JSON.parse(@raw_data.fetch('Message', '{}'))
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module AwsAlertMonitor
|
2
|
+
|
3
|
+
class EventClassifier
|
4
|
+
|
5
|
+
def initialize(message)
|
6
|
+
@message = message
|
7
|
+
end
|
8
|
+
|
9
|
+
def event
|
10
|
+
event_subjects_classes.each do |subject, klass|
|
11
|
+
return klass.new(@message) if generic_event_subject =~ subject
|
12
|
+
end
|
13
|
+
|
14
|
+
unknown_event_class.new @message
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def event_subjects_classes
|
19
|
+
{
|
20
|
+
/\AAuto Scaling: / => AwsAlertMonitor::Events::AutoScalingNotification,
|
21
|
+
/\AALARM: / => AwsAlertMonitor::Events::CloudWatchAlarm
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def generic_event_subject
|
26
|
+
AwsAlertMonitor::Event.new(@message).subject
|
27
|
+
end
|
28
|
+
|
29
|
+
def unknown_event_class
|
30
|
+
AwsAlertMonitor::Events::Unknown
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module AwsAlertMonitor
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class AutoScalingNotification < Event
|
5
|
+
|
6
|
+
def body
|
7
|
+
cause = message_data['Cause']
|
8
|
+
description = message_data['Description']
|
9
|
+
"received an alert: \n\n #{description} \n\n #{cause}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def subject
|
13
|
+
"Alert: #{raw_data['Subject']}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def type
|
17
|
+
message_data['Event']
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module AwsAlertMonitor
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class CloudWatchAlarm < Event
|
5
|
+
|
6
|
+
def body
|
7
|
+
message = "received an alert: \n\n #{alarm_description} \n\n"
|
8
|
+
message << " #{alarm_new_state_reason} \n\n"
|
9
|
+
message << " At #{alarm_state_change_time}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def subject
|
13
|
+
"Alert: #{alarm_name}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def type
|
17
|
+
"cloudwatch:#{metric_namespace}-#{metric_name}"
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def alarm_description
|
22
|
+
message_data['AlarmDescription']
|
23
|
+
end
|
24
|
+
|
25
|
+
def alarm_name
|
26
|
+
message_data['AlarmName']
|
27
|
+
end
|
28
|
+
|
29
|
+
def alarm_new_state_reason
|
30
|
+
message_data['NewStateReason']
|
31
|
+
end
|
32
|
+
|
33
|
+
def alarm_state_change_time
|
34
|
+
message_data['StateChangeTime']
|
35
|
+
end
|
36
|
+
|
37
|
+
def metric_name
|
38
|
+
message_data['Trigger']['MetricName']
|
39
|
+
end
|
40
|
+
|
41
|
+
def metric_namespace
|
42
|
+
message_data['Trigger']['Namespace']
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module AwsAlertMonitor
|
2
|
+
module Events
|
3
|
+
|
4
|
+
class Unknown < Event
|
5
|
+
|
6
|
+
def body
|
7
|
+
"received an alert: \n\n #{raw_data.to_s}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def subject
|
11
|
+
"Alert: unknown type"
|
12
|
+
end
|
13
|
+
|
14
|
+
def type
|
15
|
+
'unknown'
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/spec/alert_spec.rb
CHANGED
@@ -2,33 +2,62 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe AwsAlertMonitor::Alert do
|
4
4
|
before do
|
5
|
-
@message =
|
6
|
-
@options = {:name
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
@message = fixture_file 'asg_instance_launch.json'
|
6
|
+
@options = { :name => 'test app',
|
7
|
+
:message => @message,
|
8
|
+
:events => {
|
9
|
+
'autoscaling:EC2_INSTANCE_LAUNCH' => {
|
10
|
+
'email' => {
|
11
|
+
'source' => 'bob_weaver@intuit.com',
|
12
|
+
'destination' => 'brett_weaver@intuit.com'
|
13
|
+
} } }
|
14
|
+
}
|
15
|
+
|
16
|
+
@logger_stub = stub 'logger', :debug => true,
|
17
|
+
:info => true,
|
18
|
+
:error => true
|
19
|
+
@config_stub = stub 'config', :logger => @logger_stub
|
20
|
+
@emailer_mock = mock 'emailer'
|
21
|
+
|
22
|
+
@data = { 'body' => "test app received alert: foo",
|
23
|
+
'from' => 'bob_weaver@intuit.com',
|
24
|
+
'subject' => "Alert: Auto Scaling: launch for bar",
|
25
|
+
'to' => ['brett_weaver@intuit.com'] }
|
13
26
|
AwsAlertMonitor::Config.stub :new => @config_stub
|
14
27
|
@alert = AwsAlertMonitor::Alert.new :config => @config_stub
|
15
28
|
end
|
16
29
|
|
17
30
|
it "should process the given message against known events" do
|
18
|
-
@
|
19
|
-
|
31
|
+
@event_stub = stub 'event', :body => "received alert: foo",
|
32
|
+
:subject => "Alert: Auto Scaling: launch for bar",
|
33
|
+
:type => 'autoscaling:EC2_INSTANCE_LAUNCH'
|
34
|
+
@classifier_stub = stub 'classifier', :event => @event_stub
|
35
|
+
AwsAlertMonitor::EventClassifier.should_receive(:new).
|
36
|
+
with(@message).
|
37
|
+
and_return(@classifier_stub)
|
38
|
+
AwsAlertMonitor::Emailer.should_receive(:new).
|
39
|
+
with(@data).
|
40
|
+
and_return(@emailer_mock)
|
41
|
+
@emailer_mock.should_receive :send_email
|
20
42
|
@alert.process @options
|
21
43
|
end
|
22
44
|
|
23
45
|
it "should return false if the given message is invalid JSON" do
|
24
|
-
@
|
46
|
+
@emailer_mock.should_not_receive(:send_email)
|
25
47
|
@options[:message] = 'invalid stuff'
|
26
48
|
@alert.process(@options).should be_false
|
27
49
|
end
|
28
50
|
|
29
51
|
it "should not send the message if the destination is nil" do
|
30
|
-
@
|
31
|
-
@options = {:name
|
52
|
+
@emailer_mock.should_not_receive(:send_email)
|
53
|
+
@options = { :name => 'test app',
|
54
|
+
:message => @message,
|
55
|
+
:events => {
|
56
|
+
'autoscaling:EC2_INSTANCE_LAUNCH' => {
|
57
|
+
'email' => { 'source' => 'brett_weaver@intuit.com' }
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
32
61
|
@alert.process(@options).should be_true
|
33
62
|
end
|
34
63
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AwsAlertMonitor::Emailer do
|
4
|
+
|
5
|
+
describe 'send_email' do
|
6
|
+
let(:ses_mock) { mock 'ses' }
|
7
|
+
let(:args) do
|
8
|
+
{ 'body' => 'foo bar',
|
9
|
+
'emailer' => ses_mock,
|
10
|
+
'from' => 'root@example.com',
|
11
|
+
'subject' => 'my subject',
|
12
|
+
'to' => ['bob@example.com', 'joe@example.com'] }
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'sends the email with the correct info' do
|
16
|
+
data = { :source => args['from'],
|
17
|
+
:destination => { :to_addresses => args['to'] },
|
18
|
+
:message => {
|
19
|
+
:subject => { :data => args['subject'] },
|
20
|
+
:body => { :text => { :data => args['body']}} }
|
21
|
+
}
|
22
|
+
ses_mock.should_receive(:send_email).with(data)
|
23
|
+
|
24
|
+
AwsAlertMonitor::Emailer.new(args).send_email
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AwsAlertMonitor::EventClassifier do
|
4
|
+
|
5
|
+
describe 'event' do
|
6
|
+
|
7
|
+
context 'auto scaling notification' do
|
8
|
+
let(:message) { fixture_file('asg_instance_launch.json') }
|
9
|
+
let(:classifier) { AwsAlertMonitor::EventClassifier.new message }
|
10
|
+
|
11
|
+
it 'returns the appropriate event object' do
|
12
|
+
classifier.event.type.should == 'autoscaling:EC2_INSTANCE_LAUNCH'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'cloud watch alarm' do
|
17
|
+
let(:message) { fixture_file('cloud_watch_alarm.json') }
|
18
|
+
let(:classifier) { AwsAlertMonitor::EventClassifier.new message }
|
19
|
+
|
20
|
+
it 'returns the appropriate event object' do
|
21
|
+
classifier.event.type.should == 'cloudwatch:AWS/SQS-ApproximateNumberOfMessagesVisible'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'unknown' do
|
26
|
+
let(:message) { '{ "foo": "bar" }'}
|
27
|
+
let(:classifier) { AwsAlertMonitor::EventClassifier.new message }
|
28
|
+
|
29
|
+
it 'returns the appropriate event object' do
|
30
|
+
classifier.event.type.should == 'unknown'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
data/spec/event_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AwsAlertMonitor::Event do
|
4
|
+
let(:event) do
|
5
|
+
data = '{ "foo": "bar", "Message": "{ \"a\": \"b\" }", "Subject": "foo subject"}'
|
6
|
+
AwsAlertMonitor::Event.new data
|
7
|
+
end
|
8
|
+
|
9
|
+
describe 'raw_data' do
|
10
|
+
it 'provides the raw parsed data' do
|
11
|
+
event.raw_data.should == { 'foo' => 'bar',
|
12
|
+
'Message' => '{ "a": "b" }',
|
13
|
+
'Subject' => 'foo subject' }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'subject' do
|
18
|
+
it 'provides the subject' do
|
19
|
+
event.subject.should == 'foo subject'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'message_data' do
|
24
|
+
it 'provides the message data' do
|
25
|
+
event.message_data.should == { 'a' => 'b' }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AwsAlertMonitor::Events::AutoScalingNotification do
|
4
|
+
|
5
|
+
let(:message) { fixture_file('asg_instance_launch.json') }
|
6
|
+
let(:event) { AwsAlertMonitor::Events::AutoScalingNotification.new message }
|
7
|
+
|
8
|
+
describe 'body' do
|
9
|
+
it 'returns the body' do
|
10
|
+
data = "received an alert: \n\n "
|
11
|
+
data << "Launching a new EC2 instance: i-d6a2cb8f \n\n "
|
12
|
+
data << "At 2012-11-29T16:39:05Z an instance was started in response to a"
|
13
|
+
data << " difference between desired and actual capacity,"
|
14
|
+
data << " increasing the capacity from 0 to 1."
|
15
|
+
event.body.should == data
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'subject' do
|
20
|
+
it 'returns the subject' do
|
21
|
+
data = 'Alert: Auto Scaling: launch for group '
|
22
|
+
data << '"lc-pod-2-qa-1-app-1-Instances-XCYGCEQC0H02"'
|
23
|
+
event.subject.should == data
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'type' do
|
28
|
+
it 'returns the type' do
|
29
|
+
event.type.should == 'autoscaling:EC2_INSTANCE_LAUNCH'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AwsAlertMonitor::Events::CloudWatchAlarm do
|
4
|
+
|
5
|
+
let(:message) { fixture_file('cloud_watch_alarm.json') }
|
6
|
+
let(:event) { AwsAlertMonitor::Events::CloudWatchAlarm.new message }
|
7
|
+
|
8
|
+
describe 'body' do
|
9
|
+
it 'returns the body' do
|
10
|
+
data = "received an alert: \n\n "
|
11
|
+
data << "Queue depth alarm for LC notification queue \n\n "
|
12
|
+
data << "Threshold Crossed: 1 datapoint (3.0) was greater than the threshold (2.0). \n\n "
|
13
|
+
data << "At 2013-01-30T22:00:50.630+0000"
|
14
|
+
event.body.should == data
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'subject' do
|
19
|
+
it 'returns the subject' do
|
20
|
+
event.subject.should == 'Alert: lc-pod-2-dev-1-alarm-1-QueueDepthAlarm-706AQ69BSSN1'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'type' do
|
25
|
+
it 'returns the type' do
|
26
|
+
event.type.should == 'cloudwatch:AWS/SQS-ApproximateNumberOfMessagesVisible'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AwsAlertMonitor::Events::Unknown do
|
4
|
+
|
5
|
+
let(:message) { '{"foo": "bar"}' }
|
6
|
+
let(:event) { AwsAlertMonitor::Events::Unknown.new message }
|
7
|
+
|
8
|
+
describe 'body' do
|
9
|
+
it 'returns the body' do
|
10
|
+
data = "received an alert: \n\n "
|
11
|
+
data << JSON.parse(message).to_s
|
12
|
+
event.body.should == data
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe 'subject' do
|
17
|
+
it 'returns the subject' do
|
18
|
+
event.subject.should == 'Alert: unknown type'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe 'type' do
|
23
|
+
it 'returns the type' do
|
24
|
+
event.type.should == 'unknown'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"Type": "Notification",
|
3
|
+
"MessageId": "3c784ce1-22ec-5eec-9040-05d0b0c63fb8",
|
4
|
+
"TopicArn": "arn:aws:sns:us-west-1:187130254137:lc-pod-2-qa-1-app-1-SnsTopic-A2LI3FXD37V1",
|
5
|
+
"Subject": "Auto Scaling: launch for group \"lc-pod-2-qa-1-app-1-Instances-XCYGCEQC0H02\"",
|
6
|
+
"Message": "{\"StatusCode\":\"InProgress\",\"Service\":\"AWS Auto Scaling\",\"AutoScalingGroupName\":\"lc-pod-2-qa-1-app-1-Instances-XCYGCEQC0H02\",\"Description\":\"Launching a new EC2 instance: i-d6a2cb8f\",\"ActivityId\":\"840ac52b-36a7-419f-8378-f29bc8d477e8\",\"Event\":\"autoscaling:EC2_INSTANCE_LAUNCH\",\"Details\":{},\"AutoScalingGroupARN\":\"arn:aws:autoscaling:us-west-1:187130254137:autoScalingGroup:c96912e4-0633-4e9b-8060-f0a92b1f4fb1:autoScalingGroupName/lc-pod-2-qa-1-app-1-Instances-XCYGCEQC0H02\",\"Progress\":50,\"Time\":\"2012-11-29T16:40:10.204Z\",\"AccountId\":\"187130254137\",\"RequestId\":\"840ac52b-36a7-419f-8378-f29bc8d477e8\",\"StatusMessage\":\"\",\"EndTime\":\"2012-11-29T16:40:10.204Z\",\"EC2InstanceId\":\"i-d6a2cb8f\",\"StartTime\":\"2012-11-29T16:39:05.602Z\",\"Cause\":\"At 2012-11-29T16:39:05Z an instance was started in response to a difference between desired and actual capacity, increasing the capacity from 0 to 1.\"}",
|
7
|
+
"Timestamp": "2012-11-29T16:40:10.246Z",
|
8
|
+
"SignatureVersion": "1",
|
9
|
+
"Signature": "vVWFMUbWyfBSfo8vPCBDdrdXB1ocGZz+n4cO4FEIoczOTHgrcNY8tqYLojlTQuQZCdk7f5qPI1XJxfGS1NIs2LmsBq6oEow2qXrBQlvUXxUDMIvoWoqj6a+yjM4ICbmStdlcFVREW/0u/YO7l/se5q6KUqol4q6Vb+c+xohwR78=",
|
10
|
+
"SigningCertURL": "https://sns.us-west-1.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
|
11
|
+
"UnsubscribeURL": "https://sns.us-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-1:187130254137:lc-pod-2-qa-1-app-1-SnsTopic-A2LI3FXD37V1:1e723d7a-abf4-46a7-b73e-d6d3d3a90959"
|
12
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{
|
2
|
+
"Type" : "Notification",
|
3
|
+
"MessageId" : "0d03bb25-7963-586d-a3f8-f2a6e3313939",
|
4
|
+
"TopicArn" : "arn:aws:sns:us-west-1:187130254137:lc-pod-2-dev-1-sns-1-SnsTopic-DGIM8J5SCVDG",
|
5
|
+
"Subject" : "ALARM: \"lc-pod-2-dev-1-alarm-1-QueueDepthAlarm-706AQ69BSSN1\" in US - N.California",
|
6
|
+
"Message" : "{\"AlarmName\":\"lc-pod-2-dev-1-alarm-1-QueueDepthAlarm-706AQ69BSSN1\",\"AlarmDescription\":\"Queue depth alarm for LC notification queue\",\"AWSAccountId\":\"187130254137\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 datapoint (3.0) was greater than the threshold (2.0).\",\"StateChangeTime\":\"2013-01-30T22:00:50.630+0000\",\"Region\":\"US - N.California\",\"OldStateValue\":\"OK\",\"Trigger\":{\"MetricName\":\"ApproximateNumberOfMessagesVisible\",\"Namespace\":\"AWS/SQS\",\"Statistic\":\"SUM\",\"Unit\":null,\"Dimensions\":[{\"name\":\"QueueName\",\"value\":\"lc-pod-2-dev-1-queue-1-Queue-C32KYYWGN6DB\"}],\"Period\":300,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanThreshold\",\"Threshold\":2.0}}",
|
7
|
+
"Timestamp" : "2013-01-30T22:00:50.696Z",
|
8
|
+
"SignatureVersion" : "1",
|
9
|
+
"Signature" : "o/vsl17zKfS66pxv8r01L1uTdEcJucoE5IOIm/p+PlevVx9DY9QoBr8Yg0JQy9H3LRNHqM+Lp8z9L91H5Fw5FHn0lRS3n1m0i6C7pjqXWvmXl8SFHka2xyL72oTolKuCI5yzW3n4KC0gVyZgJj2nKO3CBR0uGoFGbqLX2tleoaI=",
|
10
|
+
"SigningCertURL" : "https://sns.us-west-1.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem",
|
11
|
+
"UnsubscribeURL" : "https://sns.us-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-1:187130254137:lc-pod-2-dev-1-sns-1-SnsTopic-DGIM8J5SCVDG:01eb3494-4be6-4b06-b3b2-a59a0d19d1ad"
|
12
|
+
}
|
data/spec/spec_helper.rb
CHANGED
@@ -2,7 +2,11 @@ require 'rubygems'
|
|
2
2
|
require 'bundler/setup'
|
3
3
|
|
4
4
|
require 'aws-alert-monitor'
|
5
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__),'helpers', '*.rb'))].each do |f|
|
6
|
+
require f
|
7
|
+
end
|
5
8
|
|
6
9
|
RSpec.configure do |config|
|
7
10
|
#spec config
|
11
|
+
config.include Fixtures
|
8
12
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-alert-monitor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-02-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
|
-
requirement: &
|
16
|
+
requirement: &70342338349940 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70342338349940
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &70342338349440 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 2.11.0
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70342338349440
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: aws-sdk
|
38
|
-
requirement: &
|
38
|
+
requirement: &70342338348420 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 1.7.1
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70342338348420
|
47
47
|
description: I watch an SQS queue and escalate alert messages.
|
48
48
|
email:
|
49
49
|
- brett@weav.net
|
@@ -69,6 +69,13 @@ files:
|
|
69
69
|
- lib/aws-alert-monitor/aws/sqs.rb
|
70
70
|
- lib/aws-alert-monitor/cli.rb
|
71
71
|
- lib/aws-alert-monitor/config.rb
|
72
|
+
- lib/aws-alert-monitor/emailer.rb
|
73
|
+
- lib/aws-alert-monitor/event.rb
|
74
|
+
- lib/aws-alert-monitor/event_classifier.rb
|
75
|
+
- lib/aws-alert-monitor/events.rb
|
76
|
+
- lib/aws-alert-monitor/events/auto_scaling_notification.rb
|
77
|
+
- lib/aws-alert-monitor/events/cloud_watch_alarm.rb
|
78
|
+
- lib/aws-alert-monitor/events/unknown.rb
|
72
79
|
- lib/aws-alert-monitor/logger.rb
|
73
80
|
- lib/aws-alert-monitor/parser.rb
|
74
81
|
- lib/aws-alert-monitor/version.rb
|
@@ -76,6 +83,15 @@ files:
|
|
76
83
|
- spec/aws/ses_spec.rb
|
77
84
|
- spec/aws/sqs_spec.rb
|
78
85
|
- spec/config_spec.rb
|
86
|
+
- spec/emailer_spec.rb
|
87
|
+
- spec/event_classifier_spec.rb
|
88
|
+
- spec/event_spec.rb
|
89
|
+
- spec/events/auto_scaling_notification_spec.rb
|
90
|
+
- spec/events/cloud_watch_alarm_spec.rb
|
91
|
+
- spec/events/unknown_spec.rb
|
92
|
+
- spec/fixtures/asg_instance_launch.json
|
93
|
+
- spec/fixtures/cloud_watch_alarm.json
|
94
|
+
- spec/helpers/fixtures.rb
|
79
95
|
- spec/parser_spec.rb
|
80
96
|
- spec/spec_helper.rb
|
81
97
|
homepage: ''
|
@@ -92,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
92
108
|
version: '0'
|
93
109
|
segments:
|
94
110
|
- 0
|
95
|
-
hash:
|
111
|
+
hash: 2565205929421564978
|
96
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
113
|
none: false
|
98
114
|
requirements:
|
@@ -101,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
117
|
version: '0'
|
102
118
|
segments:
|
103
119
|
- 0
|
104
|
-
hash:
|
120
|
+
hash: 2565205929421564978
|
105
121
|
requirements: []
|
106
122
|
rubyforge_project:
|
107
123
|
rubygems_version: 1.8.16
|
@@ -113,5 +129,14 @@ test_files:
|
|
113
129
|
- spec/aws/ses_spec.rb
|
114
130
|
- spec/aws/sqs_spec.rb
|
115
131
|
- spec/config_spec.rb
|
132
|
+
- spec/emailer_spec.rb
|
133
|
+
- spec/event_classifier_spec.rb
|
134
|
+
- spec/event_spec.rb
|
135
|
+
- spec/events/auto_scaling_notification_spec.rb
|
136
|
+
- spec/events/cloud_watch_alarm_spec.rb
|
137
|
+
- spec/events/unknown_spec.rb
|
138
|
+
- spec/fixtures/asg_instance_launch.json
|
139
|
+
- spec/fixtures/cloud_watch_alarm.json
|
140
|
+
- spec/helpers/fixtures.rb
|
116
141
|
- spec/parser_spec.rb
|
117
142
|
- spec/spec_helper.rb
|