«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
Archives
Today
Total
09-21 13:21
관리 메뉴

DevTzu

[Architecture] 효율적인 로그 모니터링 방법 | 로그 레벨로 구분 Log Level | Java Spring Boot 본문

study

[Architecture] 효율적인 로그 모니터링 방법 | 로그 레벨로 구분 Log Level | Java Spring Boot

DevTzu 2023. 4. 26. 09:00
반응형

Spring boot log file

365일 운영되는 서버 시스템에서 로그는 굉장히 중요하다.
그렇지만 로그가 중요하다고 생각되어 무분별하게 남기는 것은 나쁜 습관이다.
대표적인 예로 습관적으로 예외 상황이 발생하면 ERROR 레벨로 로그를 남기는 것이다.
정상적이지 않은 모든 상황에서 전부 ERROR 레벨로 처리하게 되면 불필요하게 많은 알람들로 인해 정작 봐야할 심각한 에러 로그들도 놓칠 수 있다.
효율적인 모니터링을 위해 적정 수준에서 로그 레벨을 구분하는것이 중요하다.

 

 

 

Spring Boot 로그 레벨 종류

TRACE

가장 상세한 로그 레벨이며, 애플리케이션의 실행 과정에서 발생하는 모든 이벤트를 로깅합니다.

 

DEBUG

  • 애플리케이션의 디버깅을 위한 로그 레벨로, TRACE보다는 자세하지 않지만 상세한 정보를 로깅
  • 개발 혹은 테스트 단계에서 해당 기능들이 정상 작동 하는지 확인하기 위한 로그 레벨
  • 다른 로그 레벨과 다르게 운영 환경에서는 남기고 싶지 않은 로그 내용을 위한 레벨

 

INFO

  • 애플리케이션의 중요한 이벤트를 로깅하는 데 사용되며, 실행 상태나 요청 정보 등을 로깅
  • 프로그램이 정상 작동할 때 나타내는 표준 로그 레벨
  • 상태, 설정 또는 외부 리소스와의 상호 작용과 같은 상태 확인을 위한 이벤트를 기록
  • 시스템을 파악하는데 유익한 정보일때만 사용
  • 운영환경에서 사용 가능


WARN

  • 애플리케이션에서 예상치 못한 상황이나 경고 메시지를 로깅하는 데 사용
  • 경고 메시지가 발생했을 때 개발자나 관리자가 조치를 취해야 함을 알림
  • 잠재적으로 문제가 될 수 있는 상황일 때 남기는 로그 레벨
  • 개발자가 조치를 취할 수 있도록 주의를 기울일 필요가 있는 상황에 사용
  • 운영환경에서 사용 가능


ERROR

  • 애플리케이션에서 발생한 오류를 로깅하는 데 사용
  • 애플리케이션의 실행이 중단될 가능성이 있는 오류를 로깅
  • 프로그램에서 발생한 심각한 오류나 예외 상황을 나타낼 때 사용
  • 기능 자체가 작동하지 못하는 문제일 때 남겨야 하고 즉시 조치가 필요할 때를 의미
  • 운영환경에서 사용 가능

 

 

Spring boot logging level

 

 

 

WARN 레벨이 어울리는 상황

프로그램 개발을 하다 보면 예외 상황, 오류 상황이 모두 ERROR 오류 일 수는 없다.

일반적이지 않은 예외 상황이 발생하더라도, 개발자가 제어할 수 없는 상황이라면 WARN으로 두는 것이 좋다.

 

- 외부 API 연동

자체 서비스가 아닌 외부 API 서비스의 호출을 100% 성공하도록 관리하는 것은 불가능할 것이다.
따라서 외부 API 호출의 일정 비율이 실패하는 것이 어느 정도 전제해야 한다.
예를 들어 다음과 같이 API 연동이 있다.

public String get(String url) {
    try {
        return api.getBookInfo(url);
    } catch (e) {
        log.error("Error occurred", e);
        return "Error";
    }
}

분당 1만 건의 트래픽이 발생하는 API라고 가정해 보자.

대략 외부 API의 실패율이 0.1%만 되어도 분당 10개의 ERROR 로그가 발생한다.
분당 10개의 ERROR 로그는 일반적인 시스템에서는 모니터링 알람이 발생할 수 있는 수치이다.
1분마다 에러 알람이 발생한다면 운영 개발자에는 알람이 와도 제대로 확인하지 않게 된다.
이럴 경우 다음과 같이 WARN 레벨로 수정한다.

public String get(String url) {
    try {
        return api.getBookInfo(url);
    } catch (e) {
        log.warn("Error occurred", e);
        return "Error";
    }
}

외부 API의 오류 발생은 우리 시스템에서는 어떻게 할 수는 없다.
한 두 번의 실패가 큰 영향을 끼치는 상황이 아니라면 외부 API는 WARN으로 레벨을 두자.
- 물론 다음과 같은 경우에는 ERROR 레벨로 둬야 한다.

  • 결제 등 비즈니스상 치명적인 API의 경우
  • 하루 1번, 한 달에 1번 정도로 요청 자체가 주기적으로 적은 횟수만 수행하는 경우

 

 

- 사용자의 입력

사용자의 입력으로 인한 오류 역시 개발자가 제어할 수 없는 예외 상황이다.
예를 들어 다음과 같이 아이디, 패스워드가 일치하지 않는 경우를 검증하는 부분이다.

public void validateLogIn(String id, String password) {
  LoginResult matchResult = this.checkValidateSignIn(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 레벨로 처리하고 있다.

이렇게 되면 사용자가 조금만 입력 실수를 하면 수많은 에러 알람들을 마주치게 된다.
이런 경우 다음과 같이 WARN, ERROR로 구분하면 좋다.

 

public void validateLogIn(String id, String password) {
  LoginResult matchResult = this.checkValidateSignIn(id, password);

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

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

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

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

이런 상황은 서비스에서 빈번하게 발생한다.
이들 역시 모두 ERROR 잡을 수는 없으며, WARN로 로그를 남기고, WARN 로그들은 좀 더 낮은 기준으로 알람을 발송하도록 한다.

 

 

 

Apache Log4j

 

 

 

효율적인 로그 모니터링

로그 레벨 중 WARN과 ERROR을 구분하면 운영 이슈 중 정말 중요한 오류를 놓치지 않고 확인할 수 있다.
시스템 모니터링 시 다음과 같이 각 레벨에 대한 기준을 정해보자.

  • INFO: 기존대비 +-50% 이상 차이 날 경우 알람
  • WARN: 분당 20개 이상일 경우 알람
  • ERROR: 분당 5개 이상일 경우 알람

개발자들에게 모니터링 알람에 대한 경각심을 유지시켜 주기 위한 로그레벨 작성 시 고민을 해보자

너무 빈번한 에러 알람은 더 이상 개발자들이 에러 알람의 중요성을 가지지 못하게 할 수도 있다.

봐야 할 에러들에만 집중하기 위해서는 적절하게 로그 레벨을 구분할 수 있어야 한다.

 

 

 

 

 

Spring Slf4j logback - DBAppender

https://devtzu.tistory.com/55

 

Spring Slf4j logback - DBAppender

Spring boot 에서는 logback-spring.xml 파일에 설정해야함 ${driverClass} ${url} ${user} ${password} DBAppender는 로그정보를 DB에 insert하는 역할을 한다. Log4j의 JDBCAppender와는 달리 Logback의 DBAppender는 디폴트로 LOGGING

devtzu.tistory.com

 

 

 

 

 

 

 

#java #spring #boot #로그 #모니터링 #로깅 #Logger #SLF4J #logback #log4j #스프링

반응형
Comments