반응형
이전 포스팅에서, cloudwatch에서 알람이 발생할 때마다 SNS, 그리고 lambda를 trigger해서 slack으로 알람을 보냈다.
* 이전 포스팅:
https://countrymouse.tistory.com/entry/awscloudwatchslack
그런데, alarm으로 받는 text의 포맷이 아래와 같이 가독성이 떨어진다. 그래서, 보다 가독성 있게 수정해보기로 한다.
위 가독성 없는 텍스트를 아래 포맷으로 수정한다.
코드는 아래 티스토리 블로거 향로님의 코드를 사용하였고 아래는 한줄한줄 해석을 달아보았다.
(직접 하나씩 만들어보려고 했는데, 반나절의 삽질을 해도 원하는 대로 잘 안돼서 다른 분의 코드를 사용하기로 했다...)
https://jojoldu.tistory.com/586
향로님 코드에 cause부분과 관련된 코드는 삭제하였고(나는 '원인'을 '설명'으로 대체했다), 일부분에 주석을 추가하였다.
// 구성 -> 환경변수로 webhook을 받도록 합니다. const ENV = process.env if (!ENV.webhook) throw new Error('Missing environment variable: webhook') const webhook = ENV.webhook; const https = require('https') const statusColorsAndMessage = { ALARM: {"color": "danger", "message":"위험"}, INSUFFICIENT_DATA: {"color": "warning", "message":"데이터 부족"}, OK: {"color": "good", "message":"정상"} } // 1. 여기서부터 시작 exports.handler = async (event) => { await exports.processEvent(event); } // 2. processEvent로 넘어간다. exports.processEvent = async (event) => { console.log('Event:', JSON.stringify(event)) const snsMessage = event.Records[0].Sns.Message; console.log('SNS Message:', snsMessage); const postData = exports.buildSlackMessage(JSON.parse(snsMessage)) // 3. buildSlackMessage await exports.postSlack(postData, webhook); } // snsMessage는 이전 포스팅 값들이 담겨 있는데, 참고해보자. // 3. buildSlackMessage(위 jane_bot2에서 출력한 snsMessage를 받아와서 각각 처리한다.) exports.buildSlackMessage = (data) => { const newState = statusColorsAndMessage[data.NewStateValue]; // 위 jane_bot2 기준 ALARM const oldState = statusColorsAndMessage[data.OldStateValue]; // 위 jane_bot2 기준 OK const executeTime = exports.toYyyymmddhhmmss(data.StateChangeTime); // 2022-05-23T03:16:02.297+0000 const description = data.NewStateReason; // 기존 코드엔 description, cause가 둘 다 있지만 나는 description에 대체했다. return { attachments: [ { title: `[${data.AlarmName}]`, color: newState.color, fields: [ { title: 'Timestamp', value: executeTime }, { title: 'Alarm', value: description }, { title: 'Previous Status', value: oldState.message, short: true }, { title: 'Current Status', value: `*${newState.message}*`, short: true }, { title: 'Link', value: exports.createLink(data) } ] } ] } } // CloudWatch 알람 바로 가기 링크 exports.createLink = (data) => { return `https://console.aws.amazon.com/cloudwatch/home?region=${exports.exportRegionCode(data.AlarmArn)}#alarm:alarmFilter=ANY;name=${encodeURIComponent(data.AlarmName)}`; } exports.exportRegionCode = (arn) => { return arn.replace("arn:aws:cloudwatch:", "").split(":")[0]; } // 타임존 UTC -> KST (2022-05-23T03:16:02.297+0000 --> 2022-05-23 13:14:48) exports.toYyyymmddhhmmss = (timeString) => { if(!timeString){ return ''; } const kstDate = new Date(new Date(timeString).getTime() + 32400000); function pad2(n) { return n < 10 ? '0' + n : n } return kstDate.getFullYear().toString() + '-'+ pad2(kstDate.getMonth() + 1) + '-'+ pad2(kstDate.getDate()) + ' '+ pad2(kstDate.getHours()) + ':'+ pad2(kstDate.getMinutes()) + ':'+ pad2(kstDate.getSeconds()); } exports.postSlack = async (message, slackUrl) => { return await request(exports.options(slackUrl), message); } exports.options = (slackUrl) => { const {host, pathname} = new URL(slackUrl); return { hostname: host, path: pathname, method: 'POST', headers: { 'Content-Type': 'application/json' }, }; } function request(options, data) { return new Promise((resolve, reject) => { const req = https.request(options, (res) => { res.setEncoding('utf8'); let responseBody = ''; res.on('data', (chunk) => { responseBody += chunk; }); res.on('end', () => { resolve(responseBody); }); }); req.on('error', (err) => { console.error(err); reject(err); }); req.write(JSON.stringify(data)); req.end(); }); } |
완성!
반응형
'직장생활 > AWS, GCP' 카테고리의 다른 글
terraform 0.14.6 mac(m1)에 설치하기, terraform 특정 버전 설치하기 (0) | 2022.05.24 |
---|---|
[AWS] EC2, Fargate, ECS, EKS 개념 (0) | 2022.05.23 |
[AWS] cloudwatch, lambda를 통해 slack으로 알람 보내기 (Nodejs) (0) | 2022.05.23 |
[AWS] Lambda와 slack 연동하기 (Nodejs) (0) | 2022.05.23 |
[AWS] S3에 이벤트가 발생할 때마다 Lambda 호출 (Nodejs) (0) | 2022.05.20 |