260507 로그분석
404 WARN 분석 정리
현상
Datadog에 아래 WARN 로그가 반복적으로 찍힘.
http not found. msg=No static resource .발생 서비스는 xxx-MP.xxx-card, 환경은 xxx-stage임.
원인 분석
처음엔 애플리케이션 로그에 요청 URI, User-Agent, client IP가 안 남아서 어떤 요청이 404를 만든 건지 파악이 어려웠음.
Datadog APM trace 까보니 실제 요청은 이랬음.
GET http://xxx.xxx.xxx.xxx:8080/
User-Agent: ELB-HealthChecker/2.0
Status: 404
Handler: ResourceHttpRequestHandler.handleRequest
Error: NoResourceFoundException: No static resource .즉 해당 서비스 내부 API가 터진 게 아니라, ELB Health Check가 / 경로로 때리고 있었고 현재 서비스엔 / 매핑이나 정적 index.html이 없어서 Spring 정적 리소스 핸들러에서 404가 떨어진 것임.
결론
이번 WARN은 비즈니스 장애가 아니라 ELB Health Check path 설정이랑 애플리케이션 라우팅이 안 맞아서 반복적으로 찍히는 404 로그임.
ELB HealthChecker
→ GET /
→ 서비스에 / 매핑 없음
→ Spring ResourceHttpRequestHandler에서 정적 리소스 조회
→ NoResourceFoundException
→ DefaultExceptionHandler에서 WARN 출력조치 방향
현재 프로젝트에 spring-boot-starter-actuator가 들어가 있으니까, ELB Health Check path는 아래 경로로 바꾸는 게 맞음.
/actuator/health권장 설정:
Health check path: /actuator/health
Port: 8080
Success codes: 200추가로 인터셉터 예외 경로에 /actuator/**도 넣어두는 게 좋음.
/actuator
/actuator/**로그 보강
재발했을 때 Datadog APM trace 안 까봐도 원인을 바로 알 수 있게 404 로그에 요청 정보를 추가해둠.
추가한 필드:
request_method
request_uri
query_string
user_agent
client_ip변경 후 로그 예시:
http not found. request_method=GET, request_uri=/, query_string=null, user_agent=ELB-HealthChecker/2.0, client_ip=..., msg=No static resource .몰랐던 것
- Spring Boot 3/Spring 6에선 매핑 안 된 요청이 정적 리소스 핸들러로 넘어가서
NoResourceFoundException으로 처리될 수 있음. No static resource .처럼 경로가 비어 보이는 메시지는/루트 요청일 가능성이 큼.- 애플리케이션 로그에 URI가 없어도 Datadog APM trace span엔
http.url,http.method,user-agent정보가 남아있을 수 있음. ELB-HealthChecker/2.0User-Agent 보면 ALB/ELB Health Check 요청인 거 식별 가능함.- 헬스체크도 애플리케이션 입장에선 그냥 HTTP 요청이라 path 잘못 부르면 정상적으로 404 떨어짐.
배운 점
- 로그 메시지만 보고 애플리케이션 장애라고 단정하면 안 되고, trace/span까지 같이 봐야 정확한 원인이 보임.
- 404 로그 분석엔 최소한
method,uri,user-agent,client_ip는 있어야 함. - Health Check path는 단순히 "응답 오는 URL"이 아니라 서비스 상태를 표현할 수 있는 경로여야 함.
/는 화면 서비스나 루트 매핑 없는 API/BFF 서비스에선 헬스체크 경로로 안 맞을 수 있음.- Actuator 들어간 Spring Boot 서비스라면
/actuator/health가 제일 표준적인 후보임.
향후 해봐야 할 것
- ELB Target Group Health Check path를
/에서/actuator/health로 변경 - 변경 전후로
/actuator/health가 200 떨어지는지 확인 - 인터셉터 예외 경로에
/actuator/**추가 검토 - 운영/스테이지 환경의 readinessProbe, livenessProbe, ALB health check path를 서비스별로 점검
- 404, 405 같은 공통 예외 로그에 요청 식별 정보 기본 포함되게 다른 서비스에도 같은 패턴 적용 검토
- Datadog dashboard에서
user_agent=ELB-HealthChecker/2.0이면서status_code=404인 서비스들 찾아서 비슷한 설정 오류 있는지 확인
확장적으로 생각해볼 점
- 헬스체크를 "서버 프로세스 떠 있음"만 볼지, "서비스가 실제로 처리 가능한 상태"까지 볼지 기준을 정해야 함.
/actuator/health에 Redis, 외부 API, DB 같은 dependency 상태를 넣으면 일시적인 외부 장애가 바로 ELB unhealthy로 이어질 수 있음. 어떤 dependency를 readiness에 포함할지 정책이 필요함.- 모든 서비스의 Health Check path를 표준화하면 운영 중 쓸데없는 404 로그랑 헬스체크 오탐을 줄일 수 있음.
- 로그 보강은 그냥 디버깅 편하자고 하는 게 아니라 장애 대응 시간을 줄이는 운영 품질 개선임.
- APM trace, access log, application log가 서로 연결돼야 "누가, 어떤 경로로, 왜 실패했는지"를 빠르게 설명할 수 있음.
댓글
첫 번째 댓글을 남겨보세요.