Alarmをメールで受けるのイヤなんじゃ・・・
slack だと、Lambdaで便利なブループリントが提供されてるんですけどね・・・
chatwork使わざるをえない環境なんで・・・
Cloudwatch Alarm
SNS
Lambda
Chatwork
って良くあるパータンの。
手順
1. Lambda Function作成
python3で。
import boto3
import json
import logging
import os
import pprint
from base64 import b64decode
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
from urllib.parse import urlencode
APIKEY = os.environ['APIToken']
ROOMID = os.environ['RoomID']
ENDPOINT = 'https://api.chatwork.com/v2/'
post_message_url = '{}/rooms/{}/messages'.format(ENDPOINT, ROOMID)
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.info("post_message_url: " + str(post_message_url))
def lambda_handler(event, context):
logger.info("Event: " + str(event))
message = json.loads(event['Records'][0]['Sns']['Message'])
logger.info("Message: " + str(message))
alarm_name = message['AlarmName']
#old_state = message['OldStateValue']
new_state = message['NewStateValue']
reason = message['NewStateReason']
chatwork_message = {
'body': "[info][title]{0} state is now {1}[/title][code]{2}[/code][/info]" .format(alarm_name, new_state, reason)
}
chatwork_message = urlencode(chatwork_message).encode("utf-8")
try:
headers = {"X-ChatWorkToken": APIKEY}
request = Request(post_message_url, data=chatwork_message, method="POST", headers=headers)
with urlopen(request) as response:
result = json.loads(response.read().decode("utf-8"))
logger.info("TEST %s", result)
info = dict(response.info())
logger.info("TEST2 %s", info)
logger.info("Message posted to %s", ROOMID)
#logger.info("Message: %s", resp.content)
except HTTPError as e:
logger.error("Request failed: %d %s", e.code, e.reason)
except URLError as e:
テストケース
どこぞで拾ったテストケース、使わせて頂きました。
他にも探したけど、良さそうなの見つからなかった。
{
"Records": [
{
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
"EventSource": "aws:sns",
"Sns": {
"SignatureVersion": "1",
"Timestamp": "1970-01-01T00:00:00.000Z",
"Signature": "EXAMPLE",
"SigningCertUrl": "EXAMPLE",
"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
"Message": "{\"AlarmName\":\"awsrds-app-High-DB-Connections\",\"AlarmDescription\":\"Alarm when CPU exceeds 50 percent\",\"AWSAccountId\":\"123456789123\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 datapoint (10.0) was greater than or equal to the threshold (10.0).\",\"StateChangeTime\":\"2016-07-24T22:05:19.737+0000\",\"Region\":\"US West - Oregon\",\"OldStateValue\":\"OK\",\"Trigger\":{\"MetricName\":\"DatabaseConnections\",\"Namespace\":\"AWS/RDS\",\"Statistic\":\"AVERAGE\",\"Unit\":null,\"Dimensions\":[{\"name\":\"DBInstanceIdentifier\",\"value\":\"app\"}],\"Period\":300,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanOrEqualToThreshold\",\"Threshold\":10.0}}",
"MessageAttributes": {
"Test": {
"Type": "String",
"Value": "TestString"
},
"TestBinary": {
"Type": "Binary",
"Value": "TestBinary"
}
},
"Type": "Notification",
"UnsubscribeUrl": "EXAMPLE",
"TopicArn": "arn:aws:sns:EXAMPLE",
"Subject": "TestInvoke"
}
}
]
}
この後の手順
SNSトピックを作って、サブスクリプションを定義して
Cloudwatch Alarmのアクションで指定して、
って感じになると思うけど、探せば色々資料出てくるので割愛。
課題
- RDSのAlarmとか、多分適宜捕まえてもうちょっと見やすく改変する必要がある。
- 厳密にテストしてない。alarm頻発してる場合とか。