본문 바로가기
IT 정보

RDS,MySQL] slow query 알림 봇 만들기

by 완기 2022. 11. 10.
728x90
반응형

신규 프로젝트를 진행하면서 백엔드와 DB설계를 맡아서 진행했다.

 

프로젝트 특성상 많은 DB Select가 일어나고 조인 관계가 복잡해지면서

쿼리 병목현상이 일어나는 지점이 생기면 알림을 쏴서 해결하려 했다.

 

물론 백엔드 코드를 작성하기 이전에 explain으로 지켜보면서 인덱싱을 적절하게 거는 것도 좋지만,

갈수록 콘텐츠가 많아질 것을 감안하여 슬로 쿼리에 대한 알림 봇을 만들 생각이 났다.

 

인프런 채용공고에서 봤다.. 사실...

 

우선 aws콘솔에서 rds 탭에 들어간 후, 알림 봇을 지정할 인스턴스로 들어간다.

 

인스턴스 -> 구성 -> 제일 아래에 파라미터 그룹을 선택한다.

 

검색창에 slow라고 검색 후, slow_query_log를 1로 바꿔준다.

300x250

우측 상단에 파라미터 편집이 있다.

 

 

그다음 long를 검색해주고, 

long_query_time을 원하는 시간으로 바꿔준다.

 

나는 3초로 하기 위해 3을 입력했다.

 

그다음 Rds 인스턴스로 다시 돌아와 우측 상단에 수정을 눌러준다.

320x100

 

 

쭉 내리다 보면 

로그 내보내기 항목에서 느린 쿼리 로그를 체크 후, 저장한다.

 

(참고 : 일부 파라미터 그룹은 데이터 베이스를 재부팅해야 반영됩니다.! 잘 반영되지 않는다면 데이터 베이스를 재부팅해보시기 바랍니다.)

 

 

 

그다음 Cloud Watch 로그 그룹으로 이동하여 

나의 Rds 인스턴스명을 검색한다.

 

그럼 아래와 같이 slowquery에 대한 로그 그룹이 생성되어있다.

 

그다음 우측 상단에서 작업 -> 구독 필터 -> Lambda 구독 필터 생성을 누른다.

 

 


람다가 생성이 안되어 있다면?

(이미 람다 함수를 생성하신 분은 건너뛰어도 좋습니다.)

 

const zlib = require('zlib');
const axios = require('axios');

const send = (data) => {
    return new Promise((resolve, reject) => {
        axios.post({슬랙 웹훅 URL}, {text: data.logEvents[0].message}).then(r => {
            resolve(r);
        }).catch(e => {
            console.error(e.message)
            reject(e);
        });
    })
}

exports.handler = function (input, context) {
    const payload = Buffer.from(input.awslogs.data, 'base64');
    zlib.gunzip(payload, function (e, result) {
        if (e) {
            context.fail(e);
        } else {
            result = JSON.parse(result.toString());
            console.log("Event Data:", JSON.stringify(result, null, 2));
            send(JSON.parse(JSON.stringify(result, null, 2))).then(r => context.succeed());
        }
    });
};

람다에 node로 함수를 새로 생성하고 위 코드를 복사 붙여 넣기 한다.

코드는 공식 문서를 참고했다.

 

참고:

 

 

CloudWatch Logs 구독 필터 사용 - Amazon CloudWatch Logs

CloudWatch Logs 구독 필터 사용 Kinesis, Lambda 또는 Kinesis Data Firehose에서 구독 필터를 사용할 수 있습니다. 구독 필터를 통해 수신 서비스로 전송되는 로그는 base64로 인코딩되고 gzip 형식으로 압축됩니

docs.aws.amazon.com

 

 

(마지막에 슬랙 웹 훅 구성 방법을 알려드리겠습니다.)

 


람다를 생성했다면

 

 

구독 필터에서 내가 작성한 람다 함수의 이름을 지정한다.

 

 

로그 형식을 기타로 지정하고 

테스트할 로그 데이터 선택하고 패턴 테스트를 통해 어떤 형태로 받을지 지정한다.

 

나는 패턴에 대한 부분은 지식이 없어 기본 값으로 설정했다.

 

그다음 우측 하단에

스트리밍 시작을 눌러준다.

 

그런 다음에 람다로 다시 돌아오면 

 

 

트리거에 CloudWatch Log가 추가되었다.

 

앞으로 조건이 만족되는 CloudWatch Log가 발생하면 이 람다를 실행하겠다는 의미다.

 

 


슬랙 웹 훅 구성 방법

 

슬랙 하단에 앱 추가 버튼을 누르고

 

Incoming WebHooks를 추가한다.

 

알람을 보낼 채널을 선택하고 수신 웹 훅 통합 앱 추가 버튼을 누른다.

 

그럼 이런 식으로 웹 훅 URL이 생성되는데, 아까 람다에서 생성한 axios post의 요청 URL로 

 

방금 생성한 슬랙의 웹 훅 URL을 입력하고

요청 바디에 메시지 전송 예시처럼 보내면 된다.

 

클라우드 워치에서 로그를 쏘는 형태는 이러하다.

 

이 JSON 데이터를 람다에서 받아서 슬랙에 전송하는 흐름인 것이다.

 


테스트를 해보자.

 

 

병목 현상의 시간으로 지정했던 3초보다 크게 sleep을 줬다.

 

쿼리가 5초 동안 병목이 발생했고,

 

알림이 슬랙 채널에 잘 도착했다.

 

모자이크 친 부분은 보안상 가렸지만

가린 부분에 해당 쿼리를 실행한 MySQL 유저와 쿼리를 요청한 IP

어떤 스키마에 실행된 것인지,

 

그리고 마지막에 실행한 쿼리가 등장한다.

728x90
728x90

댓글