오늘은 마지막으로 로깅 개선에 대한 부분을 작성 해보려고 합니다.
Serverless 구조에서는 보통 AWS Lambda에서 바로 연결된 CloudWatch를 통해 로깅과 모니터링을 처리합니다.
하지만 기본 로그만으로는 운영/디버깅에 어려움이 많기 때문에 좀 더 고도화된 로깅 전략을 구성해볼 수 있습니다.
그 몇가지에 대해서 정리해보겠습니다.
▶️ 일반적인 로깅 형태
기존에는 보통 이런 로그를 찍었을 겁니다
System.out.println("User login success: userId=abc123");
그래서 구조화된 로그(ex. JSON)를 사용하면 로그를 정제된 데이터로 다룰 수 있어, 아래와 같은 장점이 있습니다:
- 검색이 쉬움 ($.userId = "abc123")
- 수준별 로그 구분 가능 (INFO, ERROR)
- 추후 Athena, OpenSearch 등으로 확장 가능
▶️ 구조화된 로깅 형태
그럼 어떻게 해야 할까요? 내장된 Map을 통해 구조를 만들어내면 됩니다.
뭔가 말만 들으면 어려움이 느껴질 수 도 있지만, 코드만 보면 매우 간단하다고 생각하실 수 있습니다.
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;
public class LoggerUtil {
private static final ObjectMapper objectMapper = new ObjectMapper();
public static void logInfo(String message, String userId, String path) {
Map<String, Object> log = new HashMap<>();
log.put("level", "INFO");
log.put("timestamp", System.currentTimeMillis());
log.put("message", message);
log.put("userId", userId);
log.put("path", path);
try {
System.out.println(objectMapper.writeValueAsString(log));
} catch (Exception e) {
System.out.println("{\"level\":\"ERROR\",\"message\":\"Log serialization failed\"}");
}
}
}
출력 예시는 다음과 같습니다.
{
"level": "INFO",
"timestamp": 1719734567890,
"message": "User login success",
"userId": "abc123",
"path": "/login"
}
이렇게 구현한다면, 한 가지 궁금증을 가질 수 있는데요.
'왜 기존 Log 관련 라이브러리를 활용하지 않을까요?'
Logback, SLF4J, Log4j 등을 사용하면 쉽게 로그를 쌓을 수 있습니다. 그럼에도 이렇게 직접 구현하는 이유는 크게 2가지라 생각됩니다.
- CloudWatch의 필터링을 위해
- 일반적인 로그 형태는 아래와 같은 문자열 형태라 필터링에 어려움이 있을 수 있습니다.
- 2025-06-29 16:25:42.123 INFO com.example.MyService - 로그인 성공: userId=abc123
- Lambda의 성능 향상을 위해
- Logback, SLF4J, Log4j 같은 로깅 프레임워크는 종속성도 많고 초기화 비용이 상대적으로 큽니다.
- 특히 Lambda(Java)는 콜드 스타트에 민감하기 때문에...
- 가볍게 System.out.println() 처럼 직접 찍는 게 성능상 유리하고 구조화도 가능합니다.
하지만 이것이 꼭 정답은 아닙니다!
▶️ Filter Pattern으로 원하는 로그만 찾기
그럼 이 Filter에 대해서도 정리해보겠습니다. CloudWatch에서 JSON 로그는 Filter Pattern을 통해 쉽게 찾을 수 있습니다.
예를 들어, 특정 유저의 요청 로그만 보고 싶다면, { $.userId = "abc123" }
오류 로그만 확인하고 싶다면, { $.level = "ERROR" }
▶️ Metric Filter & Alarm으로 실시간 감시하기
구조화 로그를 잘 찍었다면 이제 알림을 받을 수도 있습니다. (ex) ERROR 로그가 1분 안에 2번 이상 발생하면 알림 발송.
설정 방법:
- CloudWatch Logs → 로그 그룹 -> 선택
- 작업 -> 지표 필터 생성
- 필터 패턴: { $.level = "ERROR" }
- 이름/메트릭 설정
- CloudWatch Alarm으로 연결해 이메일, Slack 등으로 경고 전송
이렇게 하면 운영 중 문제가 생겼을 때, 로그를 일일이 보지 않아도 실시간으로 감지 가능합니다.
간단하게 서버리스로 비용 없이 알람 시스템까지 만들어 볼 수 있는 형태라고 볼 수 있습니다.
이번 글에서는 서버리스 환경에서 로그를 더 잘 활용하기 위한 방법들을 소개했습니다.
구조화 로그 + 필터 + 경보로 이어지는 서비스 운영에 도움이 되는 로깅시스템으로 개선해보았습니다.
이번 Serverless 서비스 개발 시리즈를 통해 전체적으로 서버리스 서비스를 만들고 성능 개선과 운영 개선까지 해보았습니다.
비용없이 빠른시간 내 서버를 만들고자 할 때 적용해보시면 좋을 것 같습니다.
그럼 글을 마치겠습니다. 감사합니다.
'Backend Engineering' 카테고리의 다른 글
Undertow란? Tomcat, Netty와 비교해 언제 쓰면 좋을까 (1) | 2025.07.03 |
---|---|
[Serverless 서비스 개발] #6. Lambda 성능 올리기 (0) | 2025.06.26 |
[Serverless 서비스 개발] #5. Token Refresh (4) | 2025.06.23 |
[Serverless 서비스 개발] #4. 로그인/로그아웃 기능 구현 (2) | 2025.06.22 |
[Serverless 서비스 개발] #3. 회원가입 기능 구현 (2) | 2025.06.20 |