응답 & 로깅
API 응답 규격
Section titled “API 응답 규격”모든 API 응답은 ApiResponse<T> 제네릭 DTO로 감싸서 반환합니다. HTTP 상태 코드는 항상 200이며, 실제 상태는 응답 바디의 status 필드에 담깁니다.
{ "status": 200, "code": null, "message": "성공 메시지", "data": { ... }}| 필드 | 타입 | 설명 |
|---|---|---|
status | int | 실제 HTTP 상태 코드 (200, 201, 400, 401, 404, 500 등) |
code | String | 에러 코드 식별자 (성공 시 null) |
message | String | 사람이 읽을 수 있는 메시지 |
data | T | 응답 데이터 (에러 시 null 가능) |
팩토리 메서드
Section titled “팩토리 메서드”ApiResponse.success(message, data) // status: 200ApiResponse.created(message, data) // status: 201ApiResponse.error(status, code, message) // 에러 (data 없음)ApiResponse.errorWithData(status, code, message, data) // 에러 + 추가 데이터컨트롤러는 ResponseEntity<ApiResponse<T>>를 반환합니다.
글로벌 핸들러
Section titled “글로벌 핸들러”GlobalExceptionHandler (@RestControllerAdvice)가 모든 예외를 잡아서 ApiResponse 형태로 변환합니다.
| 예외 타입 | 로깅 레벨 |
|---|---|
MethodArgumentNotValidException (유효성 검증) | INFO |
IllegalArgumentException | WARN |
CustomException (비즈니스 로직) | 조건부 |
ImwebOAuthException | WARN |
DataAccessException (DB 에러) | ERROR |
NoResourceFoundException (404) | DEBUG |
Exception (기타) | ERROR |
CustomException
Section titled “CustomException”비즈니스 로직 예외의 기본 타입입니다. 도메인별 예외 Enum과 함께 사용합니다.
throw new CustomException(CrawlingExceptionEnum.INVALID_BUSINESS_USER);예외 Enum
Section titled “예외 Enum”| Enum | 용도 |
|---|---|
ApiExceptionEnum | 인증/보안 에러 |
CrawlingExceptionEnum | 크롤링/데이터 에러 |
PayExceptionEnum | 결제 에러 |
CandyPaymentsExceptionEnum | CandyPay 에러 |
BudgetExceptionEnum | 캠페인 예산 에러 |
FileExceptionEnum | 파일 업로드 에러 |
AppiliateExceptionEnum | 제휴 상품 에러 |
ImwebExceptionEnum | Imweb OAuth 에러 |
로깅 아키텍처
Section titled “로깅 아키텍처”SLF4J + Logback 조합을 사용합니다.
MDC(Mapped Diagnostic Context) 기반의 구조화된 로그를 출력합니다.
2025-01-15 14:30:00.123 [http-nio-8081-exec-1] INFO c.a.g.controller.CollabController - traceId=abc123 spanId=def456 userId=user01 userRole=ROLE_BUSINESS clientIp=192.168.1.1 - [API_REQUEST] GET /ai/collabMDC 필드
Section titled “MDC 필드”| 필드 | 설명 | 설정 주체 |
|---|---|---|
traceId | OpenTelemetry 트레이스 ID (32자리 hex) | OTel 자동 |
spanId | OpenTelemetry 스팬 ID (16자리 hex) | OTel 자동 |
userId | 인증된 사용자 ID | MdcLoggingFilter |
userRole | 사용자 역할 | MdcLoggingFilter |
clientIp | 클라이언트 IP (프록시 고려) | MdcLoggingFilter |
JwtAuthFilter (인증) ↓MdcLoggingFilter (MDC 세팅: userId, userRole, clientIp) ↓Spring Security Filters ↓ControllerMdcLoggingFilter는 JwtAuthFilter 이후에 실행되어, 인증된 사용자 정보를 MDC에 넣습니다. 요청 완료 후 MDC를 정리하여 스레드풀 메모리 누수를 방지합니다.
AOP 기반 로깅
Section titled “AOP 기반 로깅”비즈니스 코드에 로깅 코드를 넣지 않고, AOP Aspect로 분리합니다.
ApiLoggingAspect
Section titled “ApiLoggingAspect”@RestController, @Controller 메서드를 대상으로 요청/응답을 로깅합니다.
| 로그 태그 | 설명 |
|---|---|
[API_REQUEST] | 요청 수신 (메서드, URI, 파라미터) |
[API_RESPONSE] | 정상 응답 (소요 시간, 상태) |
[API_RESPONSE] [SLOW] | 느린 응답 (500ms 초과) |
[API_RESPONSE] [ERROR] | 에러 응답 |
주요 기능:
- 민감 데이터 마스킹: 비밀번호, 토큰, 카드번호, 주민번호, 전화번호 자동 마스킹
- 요청 바디 로깅: 2000자 제한으로 truncate
- 느린 요청 감지: 500ms 임계값
- 트래픽 샘플링: 설정 가능한 비율 (기본: 비활성화, 활성화 시 50%)
- 항상 로깅 경로: 결제(
/payments), 인증(/auth), 주문(/order) 관련 - 스킵 경로:
/health,/actuator,/ai/token,/ai/refresh - Micrometer 메트릭:
api.request.duration,api.errors.total
ServiceLoggingAspect
Section titled “ServiceLoggingAspect”@LogExecutionTime 어노테이션이 붙은 메서드와 Repository 메서드의 실행 시간을 로깅합니다.
| 레벨 | 조건 |
|---|---|
| DEBUG | 정상 실행 |
| WARN | 느린 실행 (기본 200ms 초과, 어노테이션으로 커스텀 가능) |
| ERROR | 실행 실패 |
ExceptionLoggingAspect
Section titled “ExceptionLoggingAspect”Service/Controller 레이어에서 발생하는 CustomException의 컨텍스트를 로깅합니다.
- 파라미터 로깅 (100자 제한)
- 민감 파라미터 마스킹 (password, token, secret, key, credential)
- 스택 트레이스 (DEBUG 레벨, 20줄 제한)
커스텀 어노테이션
Section titled “커스텀 어노테이션”| 어노테이션 | 용도 |
|---|---|
@LogExecutionTime | 메서드 실행 시간 로깅 (slowThresholdMs, operation 설정 가능) |
@NoLogging | 로깅 제외 (헬스체크, 유틸리티 등) |
로그 Appender
Section titled “로그 Appender”| Appender | 설명 |
|---|---|
| CONSOLE | 실시간 콘솔 출력 |
| ASYNC_FILE | 비동기 롤링 파일 (100MB/파일, 30일 보존, 최대 10GB) |
| ASYNC_OTLP | OpenTelemetry OTLP HTTP (Grafana LGTM 스택 연동) |
환경별 설정
Section titled “환경별 설정”| 환경 | Appender |
|---|---|
| local | CONSOLE |
| dev | CONSOLE + ASYNC_FILE + ASYNC_OTLP |
| staging-saas | CONSOLE + ASYNC_FILE + ASYNC_OTLP |
| prod | CONSOLE + ASYNC_FILE + ASYNC_OTLP |
모니터링 연동
Section titled “모니터링 연동”- OpenTelemetry:
http://localhost:4318(Grafana LGTM 스택)으로 트레이스/로그 내보내기 Sentry: 레거시, 현재 미사용- Micrometer: API 요청 시간, 에러 수 메트릭 수집