우아한테크코스 프로젝트 수행 중 로깅을 도입하였다. 처음 접하는 개념이었어서 시행착오가 많았는데 이를 정리하기 위해 학습을 계획했다.
우선 로깅
이 뭔지 부터 간략하게 알아보자.
프로그램 동작 시 발생하는 모든 일을 기록하는 행위
로깅을 통해 크게 서비스 동작 상태와 장애(exception, error) 를 기록할 수 있다.
서비스 동작 상태
장애
현재 프로잭트에서는 Exception을 위주로 로깅을 하고 있다. Exception 외에 위에 제시된 많은 동작들을 로깅할 필요성을 아직 까지는 크게 느끼지는 못하고 있다.
현재 프로젝트에서 Exception을 위주로 로깅을 하고 있는데 이는 디버깅으로도 충분히 해결할 수 있지 않을까?
사실 디버깅이 제일 좋긴 하다. 로깅 보다 익숙하고 편하기도 하고 무엇 보다 그 자리에서 디버깅을 찍으면서 내부를 한 눈에 보는 것이 Exception을 확인하는데는 좀 더 적합하다고 생각한다.
하지만 실제 서버가 구동되는 중이라면, 디버깅 하기에는 무리가 있다. 대부분 jar 파일을 실행해 클라우드 환경에서 서버를 구동할 텐데 이러한 환경에서 디버깅은 불가능에 가깝다.
이러한 환경에서 로깅을 도입하는 것은 필수 불가결하다.(실제 운영되는 서버에서의 에러가 발생하는 것은 아주 치명적이기 때문)
로깅 프레임워크로는 Logback
을 사용하였다.
왜 Logback을 사용했을까?
사실 Log4J는 2015년에 개발팀이 개발 중단 발표를 할 만큼 오래된 로깅 프레임워크라 고려 대상이 되지 않았다. 고려 대상이된 프레임워크는 Logback과 Log4j2였다.
Log4j2는 멀티 스레드 환경에서의 비동기 로거의 경우, logback보다 몇 배나 되는 처리량을 보인다는 큰 장점이 있었다.
이런 Log4j2를 놔두고 logback을 사용한 이유는 생각보다 꽤 간단하다.
1. spring boot의 기본 로깅 프레임워크이다. (Log4j2를 사용하려면 dependecy를 추가하고 로그백의 의존성도 제거해야 한다.)
2. 로깅을 처음 접하는 입장에서 Log4j2보다 참고할 만한 자료들이 더 많았다.
이제 로깅을 하는 방법에는 System.out.println(), System.err.println() 같은 방법도 있는데 왜 로깅 프레임워크를 사용했는지에 대해 알아보자.
Fatal: 매우 심각한 에러. 프로그램이 종료되는 경우가 많음
Error: 의도하지 않은 에러가 발생한 경우. 프로그램이 종료되진 않음
Warn: 에러가 될 수 있는 잠재적 가능성이 있는 경우
Info: 명확한 의도가 있는 에러(개발자가 의도한 에러). 요구사항에 따라 시스템 동작을 보여 줄 때
Debug: Info 레벨보다 더 자세한 정보가 필요한 경우. Dev 환경
Trace: Debug 레벨보다 더 자세함. Dev환경에서 버그를 해결하기 위해 사용
로그레벨은 총 위 다섯 가지로 이루어져 있다. 보통 각 레벨이 쓰여진 설명에 따라 적용되는데, 프로젝트의 성격에 따라 달라질 수 있다고 생각한다.
로그 메시지 포멧
[시간][쓰레드][로그 레벨][로거 이름][메시지]
dev 환경에서 문제가 발생하는 상황을 보니 우리가 의도한 에러에서도 문제가 나는 상황이 많았다. 따라서 handled, unhandled 모두 warn 파일 한 곳에서 관리하는 것이 편했다.
로깅 개념에 대해 익혀볼 수 있어서 좋았다. 아직 개션할 사향이 많은 것 같아 약간은 막막하지만 에자일하게 차근차근 로깅 전략을 고도화해 나갈 계획이다.
생각나는 개선점만 살짝 적어보자면...