aws-alert-monitor 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.0.5:
2
+
3
+ * Internal refactor
4
+ * Added support for generic cloud watch alarms
5
+
1
6
  ## 0.0.4:
2
7
 
3
8
  * Updated email message format and content
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
@@ -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 @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
- ses.send_email email_options
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
- { :source => @message_source,
43
- :destination => { :to_addresses => [ @message_destination ] },
44
- :message => { :subject => {
45
- :data => "Alert: #{@message_subject}"
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 process_message(message)
50
+ def event_classifier
51
+ AwsAlertMonitor::EventClassifier.new @message
52
+ end
53
+
54
+ def process_message
57
55
  begin
58
- message_body = JSON.parse message
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
- @message_cause = message_details['Cause']
66
- @message_event = message_details['Event']
67
- @message_description = message_details['Description']
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 ses
75
- @ses ||= AwsAlertMonitor::AWS::SES.new
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,3 @@
1
+ module AwsAlertMonitor
2
+ module Events; end
3
+ 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
@@ -1,3 +1,3 @@
1
1
  module AwsAlertMonitor
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -2,33 +2,62 @@ require 'spec_helper'
2
2
 
3
3
  describe AwsAlertMonitor::Alert do
4
4
  before do
5
- @message = "{\n \"Type\" : \"Notification\",\n \"MessageId\" : \"3c784ce1-22ec-5eec-9040-05d0b0c63fb8\",\n \"TopicArn\" : \"arn:aws:sns:us-west-1:187130254137:lc-pod-2-qa-1-app-1-SnsTopic-A2LI3FXD37V1\",\n \"Subject\" : \"Auto Scaling: launch for group \\\"lc-pod-2-qa-1-app-1-Instances-XCYGCEQC0H02\\\"\",\n \"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.\\\"}\",\n \"Timestamp\" : \"2012-11-29T16:40:10.246Z\",\n \"SignatureVersion\" : \"1\",\n \"Signature\" : \"vVWFMUbWyfBSfo8vPCBDdrdXB1ocGZz+n4cO4FEIoczOTHgrcNY8tqYLojlTQuQZCdk7f5qPI1XJxfGS1NIs2LmsBq6oEow2qXrBQlvUXxUDMIvoWoqj6a+yjM4ICbmStdlcFVREW/0u/YO7l/se5q6KUqol4q6Vb+c+xohwR78=\",\n \"SigningCertURL\" : \"https://sns.us-west-1.amazonaws.com/SimpleNotificationService-f3ecfb7224c7233fe7bb5f59f96de52f.pem\",\n \"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\"\n}"
6
- @options = {:name => 'test app', :message=>@message, :events=>{"autoscaling:EC2_INSTANCE_LAUNCH"=>{"email"=>{"source"=>"brett_weaver@intuit.com", "destination"=>"brett_weaver@intuit.com"}}}}
7
- @logger_stub = stub 'logger', :debug => true,
8
- :info => true,
9
- :error => true
10
- @config_stub = stub 'config', :logger => @logger_stub
11
- @ses_mock = mock 'ses'
12
- AwsAlertMonitor::AWS::SES.stub :new => @ses_mock
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
- @ses_mock.should_receive(:send_email)
19
- .with({:source=>"brett_weaver@intuit.com", :destination=>{:to_addresses=>["brett_weaver@intuit.com"]}, :message=>{:subject=>{:data=>"Alert: Auto Scaling: launch for group \"lc-pod-2-qa-1-app-1-Instances-XCYGCEQC0H02\""}, :body=>{:text=>{:data=>"test app received alert: \n\n Launching a new EC2 instance: i-d6a2cb8f \n\n 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."}}}})
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
- @ses_mock.should_receive(:send_email).never
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
- @ses_mock.should_receive(:send_email).never
31
- @options = {:name => 'test app', :message=>@message, :events=>{"autoscaling:EC2_INSTANCE_LAUNCH"=>{"email"=>{"source"=>"brett_weaver@intuit.com"}}}}
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
@@ -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
+ }
@@ -0,0 +1,8 @@
1
+ module Fixtures
2
+
3
+ def fixture_file(file)
4
+ path = File.expand_path(File.join(__FILE__, '..', '..', 'fixtures', file))
5
+ IO.read path
6
+ end
7
+
8
+ end
@@ -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
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-01-07 00:00:00.000000000 Z
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: &70314215544440 !ruby/object:Gem::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: *70314215544440
24
+ version_requirements: *70342338349940
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70314215543440 !ruby/object:Gem::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: *70314215543440
35
+ version_requirements: *70342338349440
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: aws-sdk
38
- requirement: &70314215542860 !ruby/object:Gem::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: *70314215542860
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: -3329563464597490015
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: -3329563464597490015
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