로깅

yboy·2022년 9월 14일
1

학습로그

목록 보기
19/30
post-thumbnail

학습동기

우아한테크코스 프로젝트 수행 중 로깅을 도입하였다. 처음 접하는 개념이었어서 시행착오가 많았는데 이를 정리하기 위해 학습을 계획했다.

학습내용

우선 로깅이 뭔지 부터 간략하게 알아보자.

프로그램 동작 시 발생하는 모든 일을 기록하는 행위

로깅을 통해 크게 서비스 동작 상태장애(exception, error) 를 기록할 수 있다.

서비스 동작 상태

  • 시스템 로딩
  • HTTP 통신
  • 트랜잭션
  • DB 요청
  • 의도를 가진 Exception

장애

  • I/O Exception
  • NullPointerException
  • 의도하지 않은 Exception

현재 프로잭트에서는 Exception을 위주로 로깅을 하고 있다. Exception 외에 위에 제시된 많은 동작들을 로깅할 필요성을 아직 까지는 크게 느끼지는 못하고 있다.

그럼 로깅을 왜 해야 하나?

  • 실제 서버가 구동되는 중이라면, 디버깅 하기에는 무리가 있다

현재 프로젝트에서 Exception을 위주로 로깅을 하고 있는데 이는 디버깅으로도 충분히 해결할 수 있지 않을까?

사실 디버깅이 제일 좋긴 하다. 로깅 보다 익숙하고 편하기도 하고 무엇 보다 그 자리에서 디버깅을 찍으면서 내부를 한 눈에 보는 것이 Exception을 확인하는데는 좀 더 적합하다고 생각한다.

하지만 실제 서버가 구동되는 중이라면, 디버깅 하기에는 무리가 있다. 대부분 jar 파일을 실행해 클라우드 환경에서 서버를 구동할 텐데 이러한 환경에서 디버깅은 불가능에 가깝다.

이러한 환경에서 로깅을 도입하는 것은 필수 불가결하다.(실제 운영되는 서버에서의 에러가 발생하는 것은 아주 치명적이기 때문)

로깅 프레임워크

로깅 프레임워크로는 Logback을 사용하였다.

Logback

  • SLF4J의 구현체
  • Spring boot 환경의 경우 기본적으로 logback 구현체가 포함되어 있다. 따라서 로깅 프레임워크를 따로 설정하지 않으면 logback이 기본으로 적용된다.

왜 Logback을 사용했을까?
사실 Log4J는 2015년에 개발팀이 개발 중단 발표를 할 만큼 오래된 로깅 프레임워크라 고려 대상이 되지 않았다. 고려 대상이된 프레임워크는 Logback과 Log4j2였다.

Log4j2는 멀티 스레드 환경에서의 비동기 로거의 경우, logback보다 몇 배나 되는 처리량을 보인다는 큰 장점이 있었다.

이런 Log4j2를 놔두고 logback을 사용한 이유는 생각보다 꽤 간단하다.
1. spring boot의 기본 로깅 프레임워크이다. (Log4j2를 사용하려면 dependecy를 추가하고 로그백의 의존성도 제거해야 한다.)

2. 로깅을 처음 접하는 입장에서 Log4j2보다 참고할 만한 자료들이 더 많았다.

이제 로깅을 하는 방법에는 System.out.println(), System.err.println() 같은 방법도 있는데 왜 로깅 프레임워크를 사용했는지에 대해 알아보자.

로깅 프레임워크를 도입한 이유(vs sout())

  • 출력 형식을 쉽게 지정할 수 있다.
  • 로그 레벨에 따라 남기고 싶은 로그를 별도로 지정할 수 있다.
  • 파일로 저장해 콘솔을 확인할 수 없는 배포 서버 환경에서 서비스를 개선할 수 있고 에러를 해결할 수 있는 용도로 사용할 수 있다.
  • SpringProfile 설정을 통해 개발 환경에 따라 다른 로그 정책을 적용할 수 있다

로그레벨

Fatal: 매우 심각한 에러. 프로그램이 종료되는 경우가 많음

Error: 의도하지 않은 에러가 발생한 경우. 프로그램이 종료되진 않음

Warn: 에러가 될 수 있는 잠재적 가능성이 있는 경우

Info: 명확한 의도가 있는 에러(개발자가 의도한 에러). 요구사항에 따라 시스템 동작을 보여 줄 때

Debug: Info 레벨보다 더 자세한 정보가 필요한 경우. Dev 환경

Trace: Debug 레벨보다 더 자세함. Dev환경에서 버그를 해결하기 위해 사용

로그레벨은 총 위 다섯 가지로 이루어져 있다. 보통 각 레벨이 쓰여진 설명에 따라 적용되는데, 프로젝트의 성격에 따라 달라질 수 있다고 생각한다.

사용한 로깅전략

로그 메시지 포멧
[시간][쓰레드][로그 레벨][로거 이름][메시지]
image

local

  • 모든 것을 INFO 레벨로 찍어 관리
  • 왜 debug 레벨을 안썼나?
    팀에서 로깅 정책을 정할 때 복잡성을 줄이기 위해 info, warn, error 세 가지로 정했다.

dev

  • INFO, WARN 두 레벨 사용
  • WARN
    • handled Exception(400)
    • unhandled Exception(500, 외부 라이브러리 예외)

dev 환경에서 문제가 발생하는 상황을 보니 우리가 의도한 에러에서도 문제가 나는 상황이 많았다. 따라서 handled, unhandled 모두 warn 파일 한 곳에서 관리하는 것이 편했다.

prod

  • INFO, WARN, ERROR 세 개 레벨 사용
  • warn: handling한 에러 400대 에러(dev에서 최대한 버그를 잡았어도... 믿을 수 없다!ㅠ 그래서 warn)
  • error: 외부 라이브러리 예외 등 예상치 못한 예외(아주 치명적)

마무리

로깅 개념에 대해 익혀볼 수 있어서 좋았다. 아직 개션할 사향이 많은 것 같아 약간은 막막하지만 에자일하게 차근차근 로깅 전략을 고도화해 나갈 계획이다.
생각나는 개선점만 살짝 적어보자면...

  • 모니터링 툴 적용(인스턴스가 터지면 로그 파일도 날아간다...)
  • 트랜잭션 ACID 성질 중 Durabiliy(지속성)을 만족 시키기위해 트랜잭션 로깅 처리
  • jpa를 사용하고 있는데 의도하지 않은 쿼리가 나가는 경우가 많아 쿼리도 로그로 찍어보는데 좋을 것 같다...
    ......
    할게 진짜 많다...그래도 홧팅! 하루 하루 발전해 나가는 사람이 되길🙏🏻

0개의 댓글