로그 레벨에 대해서 알아보자

인턴일지

목록 보기
3/7
post-thumbnail

로그 레벨

  • 로그 레벨은 로그 메세지의 중요도를 나타내는 수준을 의미한다. ]
  • 로깅 시스템에서 사용되며, 로그 메세지의 중요도에 따라 기록 여부를 결정하는데 사용된다.

단계는…. 아래와 같이 이뤄진다.

DEBUG → INFO → WARN → ERROR → CRITICAL(FATAL)

DEBUG

  • 개발 혹은 테스트 단계에서 상세한 정보를 기록하는 용도
    • 운영 환경에서는 남기고 싶지 않은 로그 메세지를 위한 레벨
  • 애플리케이션의 내부 동작 이해 및 문제 분석 시 유용하다.
    • 무식하게 console.log 혹은 print() 로 로컬에서 문제를 확인한다면, 디버깅 방식을 익히던가 log.debug 로 로그를 남기는 게 좋다.

INFO

  • 애플리케이션에서 정상적으로 작동했을 시에 대한 정보에 대한 표준 로그 레벨
    • 상태, 설정, 외부 리소스와 상호 작용과 같은 상태 확인을 위한 이벤트를 나타낸다.
    • 운영 환경에서 사용할 수 있다.
  • 시스템을 파악하는데 유용한 정보를 남기는 용도

WARN

  • 경고성 메세지로 애플리케이션이 정상적으로 동작하지만, 문제가 될 수 있는 상황일 때 남기는 로그 레벨
    • 운영 환경에서도 사용할 수 있다.

ERROR

  • 애플리케이션에서 발생한 심각한 오류나 예외 상황을 나타내는 로그 레벨
    • 운영 환경에서도 사용할 수 있다.
  • 기능이 제대로 작동하지 못하는 문제가 생겼을 때 즉시 조치가 필요한 경우를 뜻한다.

FATAL

  • 애플리케이션의 동작을 중단시킬 수 있는 치명적인 오류를 나타내는 로그 레벨
    • 복구가 불가능한 상황

WARN vs. ERROR

사례를 통해 이해해보자

1. 외부 API 연동

예를 들어 다음과 같이 API 연동을 할 때..

function get(url): string {
    try {
        return api.getCompanyInfo (url);
    } catch (e) {
        log.error("Error occurred", e);
        return "response";
    }
}

분당 1만건의 트래픽이 발생하는 API라면 대략 외부 API의 실패율이 0.1% (성공율 99.9%) 만 되어도 분당 10개의 ERROR 로그가 발생한다.

분당 10개의 ERROR 로그는 일반적인 시스템에서는 모니터링 알람이 발생할 수 있는 수치이다.

(물론 외부 API의 SLA가 0.1%보다 높을 수도 있다.)

1분마다 에러 알람이 발생한다면 종국에는 알람이 와도 제대로 확인하지 않게 된다.

이럴 경우 다음과 같이 WARN 레벨로 수정한다.

function get(url): string {
    try {
        return api.getCompanyInfo (url);
    } catch (e) {
        log.warn("Error occurred", e);
        return "response";
    }
}

외부 API 의 에러 발생율을 우리가 어떻게 할 수는 없다.

한 두번의 실패가 큰 영향을 끼치는 상황이 아니라면 외부 API는 WARN으로 레벨을 두자.

물론 다음과 같은 경우에는 ERROR 레벨로 둬야한다.

  • 결제 등 비즈니스상 치명적인 API의 경우
    • 단, 잔고 부족, 인증 실패 등 고객의 실수인 경우는 WARN으로 둔다.
    • 그 외 외부 결제사의 문제라면 이는 ERROR로 로그를 남겨 빠르게 인지후, 해당 결제사가 정상이 될때까지는 미노출시키는 등의 작업을 해야만 한다.
  • 재시도 전략이 없는 상태에서 하루 1번, 한달에 1번 정도로 요청 자체가 주기적으로 적은 횟수만 수행하는 경우
    • Retry 호출, 메세지큐 등 재시도 전략이 있는게 아니면서 딱 1번씩만 호출하는 경우 재시도를 해야하기 때문에 ERROR로 로그를 남긴다.

2. 사용자의 입력

사용자의 입력으로 인한 오류 역시 개발자가 제어할 수 없으면서 빈번하게 발생할 수 있는 예외 상황이다.

예를 들어 다음과 같이 id,pw가 일치하지 않는 경우를 검증하는 함수가 있다고 해보자.

export async function validateSignIn(id: string, password: string) {
  const matchResult = await userRepository.validateSignIn(id, password);

  if(!matchResult.isMatch) {
    log.error(`id=${id} 의 로그인 정보가 정확하지 않습니다.`);
    throw new Error('로그인 정보가 정확하지 않습니다.');
  }

  if(matchResult.failCount > 5) {
    log.error(`id=${id} 의 로그인 실패 횟수가 5회를 초과했습니다.`);
    throw new Error('로그인 실패 횟수 초과로 30분간 로그인을 시도할 수 없습니다.');
  }
}

로그인 실패와 5회이상 연속된 로그인 실패 둘 다 ERROR 레벨이라서 사용자가 조금만 입력 실수를 하면 수많은 에러 알람들을 마주치게 된다.

이런 경우 역시 WARNERROR 를 구분하면 좋다.

export async function validateSignIn(id: string, password: string) {
  const matchResult = await userRepository.validateSignIn(id, password);

  if(!matchResult.isMatch) {
// ERROR -> WARN
    log.warn(`id=${id} 의 로그인 정보가 정확하지 않습니다.`);
    throw new Error('로그인 정보가 정확하지 않습니다.');
  }

  if(matchResult.failCount > 5) {
    log.error(`id=${id} 의 로그인 실패 횟수가 5회를 초과했습니다.`);
    throw new Error('로그인 실패 횟수 초과로 30분간 로그인을 시도할 수 없습니다.');
  }
}

이 외에도 다양한 경우가 포함된다.

  • 입력 항목에서 필수 항목을 누락하고 요청한 경우
  • 형식에 맞지 않는 (Email, 전화번호 등) 값으로 요청한 경우

이런 상황은 서비스에서 빈번하게 발생한다.

이들 역시 모두 ERROR 잡을 수는 없으며, WARN 로 로그를 남기고, WARN 로그들은 좀 더 낮은 기준으로 알람을 발송하도록 한다.


출처: https://jojoldu.tistory.com/712

profile
밝은 미래 FE 개발자의 기록

0개의 댓글