728x90
스프링 부트에서 파라미터화된 로깅{}과 String.format 사용법
Java의 로깅 시스템에서는 주로 두 가지 방식으로 로그 메시지를 포맷한다: 파라미터화된 로깅과 String.format을 사용하는 방법이다. 이 두 방법은 서로 다른 특징과 사용 케이스를 가지고 있다. 각각의 특징과 차이점을 알아보자!
1. {}를 사용하는 방법
- SLF4J에서 제공하는 로그 메시지 형식화 방법이다.
- 로그 레벨이 활성화되지 않은 경우, 파라미터로 전달된 객체들의 toString() 메소드가 호출되지 않는다. 이는 성능상 이점을 제공한다. 즉, 불필요한 문자열 연산이 발생하지 않는다.
- 그러나 로그 레벨이 변경될 때 로그 출력 내용도 달라질 수 있다는 점을 이해해야 한다.
- 가독성이 좋다. 로그 메시지와 파라미터가 분리되어 있기 때문에 코드를 읽고 이해하기 쉽다.
(예시 코드 - log level이 INFO라고 가정할때)
String username = "user123";
LocalDateTime loginTime = LocalDateTime.now();
// DEBUG 레벨의 로그
log.debug("User {} has logged in at {}", username, loginTime); // INFO 레벨에서는 출력되지 않음
// INFO 레벨의 로그
log.info("User {} has logged in at {}", username, loginTime); // 출력됨
(예시 출력)
INFO: User user123 has logged in at 2023-11-15T12:34:56
2. String.format 사용하는 방법
- Java의 기본 문자열 형식화 방법이다.
- 로그 레벨에 상관없이 String.format()이 호출되며, 항상 문자열 연산이 수행된다. 이는 성능상의 단점이 될 수 있다.
- 복잡한 문자열 형식화가 필요한 경우 유용하다. 예를 들어, 소수점 이하 자릿수를 제한하거나, 특정 형식으로 날짜를 출력해야 할 때 유용하다.
(예시 코드 - log level이 INFO라고 가정할 때)
String username = "user123";
LocalDateTime loginTime = LocalDateTime.now();
// DEBUG 레벨의 로그
log.debug(String.format("User %s has logged in at %s", username, loginTime)); // 이 경우에도 출력됨
// INFO 레벨의 로그
log.info(String.format("User %s has logged in at %s", username, loginTime)); // 출력됨
(예시 출력)
DEBUG: User user123 has logged in at 2023-11-15T12:34:56
INFO: User user123 has logged in at 2023-11-15T12:34:56
3. 성능: 실제 사례 비교
- 로깅은 어플리케이션의 성능에 직접적인 영향을 미칠 수 있다.
- 예를 들어, 대용량 데이터를 처리하는 배치 작업에서 {}와 String.format()을 사용한 로깅의 성능을 비교해 보자.
- {} 방식은 로그 레벨이 비활성화된 경우 문자열 연산을 수행하지 않기 때문에, 100,000건의 데이터를 처리하는 데 소요되는 시간이 String.format() 방식에 비해 현저히 줄어들 수 있다.
- 이는 특히 시스템 리소스가 제한적인 환경에서 중요하다.
4. 코드 가독성 및 유지 보수
- {} 방식은 로그 메시지와 파라미터가 분리되어 있어 코드가 더 간결하고 이해하기 쉽다.
- 반면, String.format()은 복잡한 문자열 포맷을 제공하지만, 코드가 더 길고 복잡해질 수 있다.
- 특히, 여러 개발자가 협업하는 환경에서는 {} 방식이 유지 보수성 면에서 유리하다.
5. 다양한 로깅 라이브러리와의 호환성
- SLF4J는 Logback, Log4j와 같은 다양한 로깅 프레임워크와 호환되며, {} 방식을 사용하면 이러한 프레임워크 간의 전환도 용이하다.
- 반면, String.format()은 Java 표준 API이므로 프레임워크와 무관하게 사용할 수 있다.
6. 보안 측면에서의 고려사항
- 로그 인젝션과 같은 보안 취약점을 방지하기 위해, {} 방식은 입력 데이터를 로그 메시지와 분리하여 처리한다.
- 이는 잠재적인 보안 위험을 줄이는 데 도움이 된다.
- String.format()을 사용할 때는 주의가 필요하다.
7. 총평
Java 로깅 시스템에서 {}와 String.format() 사용 방식은 각각의 상황에 따라 장단점을 가진다.
- {} 사용 방식은 로그 레벨에 따라 효율적으로 동작하며, 로그 레벨이 비활성화된 경우 불필요한 문자열 연산을 방지하여 성능상 이점을 제공한다. 코드의 가독성과 유지 보수 측면에서도 유리하며, 보안적인 면에서 입력 데이터와 로그 메시지를 분리하여 처리하는 장점이 있다. 그러나 로그 레벨 변경 시 로그 출력이 달라질 수 있다는 점을 고려해야 한다.
- String.format() 사용 방식은 로그 레벨에 관계없이 항상 동일한 형식으로 로그를 출력한다. 복잡한 문자열 형식화가 필요한 상황에서 유용하다. 하지만, 이는 성능상 단점으로 작용할 수 있으며, 보안 측면에서도 추가적인 주의가 필요하다.
종합적으로, {} 방식은 성능과 가독성 측면에서 일반적인 경우에 더 적합하나, 복잡한 형식화가 필요한 상황이나 일관된 로그 출력을 원하는 경우 String.format()을 고려할 수 있다. 선택은 개별 어플리케이션의 요구 사항과 상황에 따라 달라질 수 있다.
'Spring > Spring Boot' 카테고리의 다른 글
[Spring Boot]MSA 환경에서 SNS/SQS를 활용한 이벤트 처리: 이벤트 유실 문제 해결 방안 (0) | 2023.11.17 |
---|---|
[Spring Boot] Spring Framework 4.2 이후 버전에서 스프링 이벤트 적용하기 (SpringBoot 3 버전에 spring event 적용하기) (1) | 2023.11.15 |
[Spring Boot] AOP를 활용한 로깅 구현: @EnableAspectJAutoProxy와 사용자 정의 Aspect 클래스 비교 가이드 (1) | 2023.11.13 |
[Spring Boot] Quartz 적용하기 (2) | 2023.11.11 |
[Spring Boot] 스프링 스케줄러 적용하기 (0) | 2023.11.11 |