본문 바로가기

Java

[JAVA] Logging (로깅)

1. 로깅? - 모든 일 (개발자가 가져야 할 최소한의 목적)

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

  2) 서비스 동작 상태 (시스템이 동작되기 위해 필요한 부분들)

     - 시스템 로딩

     - HTTP 통신

     - 트랜젝션

     - DB 요청

     - 의도를 가진 Exception

   3) 장애(exception, error)

       - I/O Exception

       - NullPointException

       - 의도하지 않은 Exception

 

2. 로깅은 언제할까?

  - 로깅 시점은 때에 따라 다르다. 그 이유는 똑같은 서비스라도 요구사항이 전혀 다를 수 있기 때문이다.

 

3. 로깅 VS System.out.println()

   - 출력 형식을 지정할 수 있음

   - 로그 레벨에따라 남기고 싶은 로그를 별도로 지정할 수 있음

   - 콘솔 뿐만아니라 파일이나, 네트워크등 로그를 별도 위치에 남길 수 있음

   - 성능도 System.out.println() 보다 좋다.

   - 실제 서비스에서는 로깅 프레임워크를 사용하는 것이 좋다.

 

4. 로그를 어떻게 기록할까? - 로그레벨

Level 설명
Fatal 매우 심각한 에러. 프로그램이 종료되는 경우가 많음
Error 의도하지 않은 에러가 발생한 경우. 프로그램이 종료되진 않음
Warn 에러가 될 수 있는 잠재적 가능성이 있는 경우
Info 명확한 의도가 있는 에러, 요구사항에 따라 시스템 동작을 보여줄 때
Debug Info 레벨보다 더 자세한 정보가 필요한 경우. Dev 환경
Trace Debug 레벨보다 더 자세함. Dev 환경에서 버그를 해결하기 위해 사용

- 시스템상에서 개발자가 의도하지 않은 예외를 나타낼 때 사용 : Fatal, Error

- 시스템상에서 개발자가 의도한 예외를 나타낼 때 사용 : Warn, Info, Debug, Trace

 

5. 로깅 VS 디버깅

  - 프로그래밍 절반은 디버깅한다.

  - 디버깅은 예외상황을 가장 잘 파악할 수 있다. breakPoint 시점으로 확인 가능

  - 하지만 실제로 서버가 구동 중일 때는 디버깅으로 한계가 있다.

  - 디버깅으로 활용할 수 있는 건 최대한 활용을 하고 무리가 되면 로깅을 한다.

 

6. SLF4J 

  - Simple Logging Facade for Java : 다양한 로깅 프레임워크에 대한 추상화(인터페이스) 역할

  - 추상 로깅 프레임워크이기 때문에 단독으로 사용하지 않는다.

  - 최종 사용자가 배포 시 원하는 구현체를 선택 (SLF4J가 인터페이스화 되어있기 때문에, SLF4J를 의존하는 클라이언트 코드에서는 실제 구현을 몰라도 된다.)

 

  1) SLF4J 동작 과정

      - 개발할 때, SLF4J API를 사용하여 로깅 코드를 작성하고, 배포할 때는 바인딩된 Logging Framework가 실제 로깅 코드를 수행하는 과정을 거친다.

      - 이러한 과정은 SLF4J에서 제공하는 3가지 모듈은 Bridge, API, Binding 모듈을 통해 수행된다.

      - Bridge 모듈 : SLF4J 이외의 다른 로깅 API로의 Logger 호출을 SLF4J 인터페이스로 연결하여 SLF4J API가 대신 처리할 수 있도록 하는 일종의 어댑터 역할을 하는 라이브러리에요.라이브러리예요. 아직 변경되지 않은 이전의 레거시 로깅 프레임워크를 위한 라이브러리에요. 여러 개를 사용해도  상관없지만 Bridge와 Binding 모듈에 같은 종류의 프레임워크를 사용하면 안 된다.

      - API 모듈 : 로깅에 대한 추상 레이어(인터페이스) 제공, 결론적으로 로깅 동작에 대한 역할을 수행할 추상 메서드를 제공한다. 추상 클래스이기 때문에 이 모듈만 단독적으로 쓰일 순 없다. 사용 시 주의점은 '하나의 API에 하나의 Binding을 둬야한다'는 점이에요.

      - Binding 모듈 : SLF4J API를 '로깅 구현제와 연결하는 어댑터 역할'을 하는 모듈이다. SLF4J API를 구현한 클래스에서 Binding으로 연결된 Logger의 API를 호출한다. 앞서 API의 주의점과 같이 '하나의 API에 하나의 Binding을 둬야 한다'