반응형
1. 구성
구성은 정말 간단하다.
CloudWatch 로그 그룹에 애플리케이션 로그들이 쌓이고 있다. →
구독 필터로 특정 패턴을 감지하여 AWS Lambda로 보내준다. →
AWS Lambda에서는 메시지를 전달받은 뒤 가공하여 Slack으로 메시지를 보내준다.
serverless 프레임워크를 활용한다.
serverless.yml
service: SLACK-NOTIFICATION
frameworkVersion: "3"
plugins:
- serverless-dotenv-plugin
provider:
name: aws
profile: XXXXXXX
timeout: 30
memorySize: 256
runtime: nodejs18.x
stage: prod
region: ap-northeast-2
iam:
role: arn:aws:iam:XXXX:role/XXXXXXXX
functions:
main:
handler: handler.main
.env 파일에는 Slack token , alert을 보낼 slack channel id가 있다.
handler.js
'use strict';
import zlib from 'zlib';
import { sendSlackMessage } from "./libs/slack.js"
export async function main(event) {
// event.awslogs가 있을 경우
if (event.awslogs && event.awslogs.data) {
// 1. event로 들어오는 압축된 데이터를 풀어주자.
const payload = Buffer.from(event.awslogs.data, 'base64');
const decodedData = JSON.parse(zlib.unzipSync(payload).toString())
console.log(decodedData);
const logGroup = decodedData.logGroup;
const indexes = decodedData.logEvents.keys();
// 2. 여러개의 log가 들어오기 때문에 반복문을 수행해준다.
for await (const index of indexes) {
// slack으로 message를 보낸다.
const result = await sendSlackMessage(process.env.SLACK_CHANNEL, logGroup, decodedData.logEvents[index].message);
console.log(result.ok);
}
}
return { statusCode: 200, body: "ok"};
};
1. cloudwatch 구독 필터를 lambda로 보낼 경우 인코딩되어 들어오기에 디코딩을 해줘야 한다.
2. logEvents이기 때문에 이걸 각 logEvent로 반복문을 수행해줘야 한다.
3. slack으로 메시지를 보낸다.
libs/slack.js
import { WebClient } from '@slack/web-api';
// Initializing
const webClient = new WebClient(process.env.TOKEN);
async function sendSlackMessage(SLACK_CHANNEL, logGroup, logMessage) {
try {
const template = {
"channel": SLACK_CHANNEL,
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": '*Error 로그 발생*\\n\\nCloudWatch Log Group : *'+ logGroup + '*\\n'
}
},
{
"type": "divider"
}
],
"attachments": [
{
"fallback": "Fallback 입니다.",
"color": "#eb4034",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": logMessage
}
}
]
}
]
};
// Call the chat.postMessage method using the WebClient
const result = await webClient.chat.postMessage(template);
return result
} catch (error) {
console.error(`Error sanding message ! : ${error}`);
return "error";
}
}
export { sendSlackMessage };
로컬 테스트
로컬에서 테스트를 하기 위해서는 sample event data를 가지고 invoke 해줘야 한다.
sls invoke local --function main --path data/event.json
배포
sls deploy
배포한 뒤에 Cloudwatch log 에 들어가 구독 필터를 적용하여 해당 배포한 lambda와 연결해준다.
아래는 예시이다.
소스는 제공해드렸으니 필요하다면 slack message template은 보기좋은대로 수정하여 사용하면 된다.
반응형
'DevOps' 카테고리의 다른 글
[Ansible] 반복문, 조건문, 핸들러, 블록, Recsue 등 개념 정리 (0) | 2024.01.20 |
---|---|
[Ansible] 기본 개념 정리 (0) | 2024.01.09 |
[Github Action] Self hosted runner에서 Gradle, Docker image cache #2 - EFS 활용 (8) | 2022.12.19 |
[Github Action] Self hosted runner에서 Gradle, Docker image cache #1 - EBS, PVC로 캐시하기 (2) | 2022.12.17 |
[Istio] EKS에서 Okta와 AWS ALB, Istio를 활용하여 인증, 인가 처리하기 (0) | 2022.11.06 |