Hola! 서비스를 운영하면서 에러 로깅 + 모니터링 시스템을 적용한 내용을 공유하려고 합니다.
서비스를 운영하면서 가장 불안한 점은 언제 오류가 발생할지 모른다는 거죠.🥲
실제로 아래와 같은 불편함을 겪고있다면 Sentry 도입을 추천드립니다. (저는 모두 해당됐었..)
- 서비스에 접속이 안될까봐 수시로 접속해서 확인한다.
- 주기적으로 서버에 접속하여 에러 로그를 확인한다.
- 접속해서 모든 기능을 테스트 해볼 수 없다.
- 에러가 발생하더라도 팀원에게 공유하기 힘들다.
Sentry란?
Sentry란 Application 에러 트래킹, 성능 모니터링을 제공해주는 서비스입니다.
에러가 발생하면 알림을 받을 수 있고 에러에 대한 상세 정보를 트래킹 해줍니다.
성능 모니터링을 이용해 각 지표들을 쉽게 확인할 수 있습니다.
다양한 언어를 지원하며 이 글에서는 Express를 기준으로 설명합니다!
제 Github에서 사용한 코드를 확인하실 수 있습니다 :)
Sentry 가입 및 설정
Sentry 설정 방법은 공식 문서가 아주 잘되어있고 간단하기 때문에 쉽게 세팅할 수 있습니다. 👍👍
- Sentry에서 회원 가입 후 프로젝트 생성
- DSN 저장 후 .env에 저장
- Setting → Client Keys(DSN) → 프로젝트 선택하여 확인가능
- sentry module install
npm install --save @sentry/node - 코드에서 Sentry 세팅
import express from "express";
import * as Sentry from "@sentry/node";
const app = express();
Sentry.init({ dsn: "your dsn" });
// 첫번째 미들웨어로 설정
app.use(Sentry.Handlers.requestHandler());
// 예시) 컨트롤러 설정
app.get("/", function rootHandler(req, res) {
res.end("Hello world!");
});
// Sentry 오류 핸들러는 모든 컨트롤러의 뒤와 다른 오류 미들웨어의 앞에 있어야 합니다.
app.use(Sentry.Handlers.errorHandler());
app.listen(3000);
저는 enabled 옵션을 이용해 production 환경에서만 에러를 로깅하도록 했습니다.
Sentry.init({
dsn: config.SentryDsn,
tracesSampleRate: 0.2,
enabled: process.env.NODE_ENV === 'production',
});
직접 error의 상태에 따라 에러 여부를 판단하고 싶을 경우 아래와 같이 사용하면 됩니다.
app.use(
Sentry.Handlers.errorHandler({
shouldHandleError(error) {
// error status 404, 500 번만 error로 판단
if (error.status === 404 || error.status === 500) {
return true;
}
return false;
},
})
);
에러 로깅 테스트
설정이 완료되었습니다! Sentry가 에러를 잘 캐치하는지 확인해볼까요??
특정 end point로 요청이 왔을때 무조건 에러가 발생하도록 구성해놓은 후
route.get(
'/error',
asyncErrorWrapper(async (req: Request, res: Response, next: NextFunction) => {
throw new Error('에러 상황 테스트!');
}),
);
postman을 이용해 에러를 발생시키고 Sentry - Issues 탭을 보면 에러를 정상적으로 캐치한 것을 확인하실 수 있습니다.
참고로 Events는 해당 에러가 발생한 횟수고 Users는 에러가 전달된 사용자 수입니다.
저는 Postman을 이용해 테스트 했기 때문에 Users는 0으로 나오게 됩니다.
에러를 클릭해보면 해당 에러에 대한 상세 정보를 보여줍니다.
어떤 코드에서 에러가 발생했는지, 사용자의 환경은 무엇인지, 에러가 발생한 request의 정보 등을 보여줍니다.
모니터링
Sentry는 에러 로깅 뿐만 아니라 Performace 모니터링을 지원합니다.
Performance 탭을 클릭하면 성능 지표들을 보여줍니다.
각 지표는 아래와 같은 의미입니다.
Apdex가 왜 이렇게 낮게 나오는지 확인을 해봐야겠네요! 🤔
- Apdex
- 사용자의 만족도를 수치적인 지표로 잡을 수 있도록 하기 위한 것
- 0(불만족) ~ 1(만족)
- 즉 요청에 대해 측정된 반응 속도(Response Time)을 0~1사이의 값으로 수치화.
- Transactions Per Minute
- 보통 1분에 시스템이 처리할 수 있는 트랜잭션의 수로 표현되며 여기에서는 처리한 트랜잭션 수
- Failure Rate
- 고장률이라는 의미로 성공한 상태와 실패한 상태를 백분율로 기록한 것
- Slow DB Ops
- 느린 DB 작업을 보여준다.
Slack과 연동하여 실시간 알림받기
Sentry를 이용해서 에러가 발생했을 경우 쉽게 파악 할 수 있게 되었지만 여전히 언제 에러가 발생할지 모른다는 불안감이 있습니다.
Slack과 연동하면 에러가 발생했을때 메시지를 받을 수 있기 때문에 이제 매번 확인하지 않아도 됩니다 😆
Sentry는 Slack과의 연동을 지원하지만 Team plan 이상의 요금제를 사용해야만 이용할 수 있습니다.
직접 연동은 아니지만 Slack Web hooks를 이용하여 에러가 발생했을때 slack 메시지를 받을 수 있습니다.
Webhooks URL 발급
- Slack 홈페이지에 접속하여 incoming hooks를 검색합니다.
- Slack에 추가 버튼을 클릭한 후 연동할 채널을 선택합니다.
- Add Incoming WebHooks integration를 클릭하면 Webhook URL이 발급됩니다.
- Webhook URL을 복사한 후 .env에 입력합니다.
@slack/client module install
Express에서 메시지를 보내기 위해 @slack/client 모듈을 install 합니다.
npm i @slack/client
에러 발생 시 메시지 보내기
Sentry의 shouldHandleError 에러 핸들러에 다음 부분을 추가합니다.
상태에 따라 에러 여부를 판단하는 부분이 있다면 에러일 경우에만 메시지를 보내야 합니다.
import { IncomingWebhook } from '@slack/client';
const webhook = new IncomingWebhook(config.SlackWebhook);
webhook
.send({
attachments: [
{
color: 'danger',
text: '백엔드 에러 발생',
fields: [
{
title: error.message,
value: error.stack! as string,
short: false,
},
],
ts: Math.floor(new Date().getTime() / 1000).toString(),
},
],
})
.catch((err: Error) => {
if (err) Sentry.captureException(err);
});
Slack 연동 테스트
아까 만들어놓은 API를 이용해 postman으로 다시 에러를 발생시켜보면
바로 메시지를 보내주는 것을 확인할 수 있습니다!
Conclusion
드디어 Sentry를 이용해 안전하게 서비스를 운영할 수 있게 되었습니다!
에러가 발생하면 Slack으로 알림이 발생하고, 쉽게 에러를 추적할 수 있죠 :)
더 좋은 툴이 있거나 잘못된 내용이 있다면 댓글로 알려주시기 바랍니다. 🙏
참고글
'기타' 카테고리의 다른 글
[Word] 워드 표 페이지마다 머리글 행 반복 안될때 해결방법 (1) | 2023.02.14 |
---|---|
[Github] Fork해온 저장소에 잔디 심는 방법(커밋해도 잔디가 안심어질때) (0) | 2022.12.07 |
[Docker] Docker 환경 Nginx에 SSL 인증서 적용하기(Let’s Encrypt) (1) | 2022.01.17 |
[Macbook] 맥북 외장모니터 연결 문제 임시 해결(모니터 깜빡임) (2) | 2022.01.09 |
[Docker] Docker, Nginx, Node.js 환경에서 서비스 무중단 배포하기 (0) | 2021.12.19 |