로그 (Log)

1 분 소요

개발에 있어 Log를 출력하는 것은 반드시 필요한 일이다.
자바에서 Log를 출력할때 모두 System.out.println()으로 출력하는 경우가 있다면 이는 성능상 안좋은 영향을 끼칠 수 있다.

1. System.out.println() 의 문제

System.out.println()을 통해 로그를 출력하도록 하고, 로그를 보기 위한 윈도우 콘솔을 띄어져 있는 상태에서 CPU 사용량을 모니터링 해보자.

확인해보면 로그를 띄우는 콘솔이 띄어져 있을때 커널 CPU 사용량이 많이 올라가는 것을 볼 수 있다.
이 차이는 꽤 커서 실제 운영상에 성능 이슈를 일으킨다.

운영시에는 디버그 로그는 필요하지도 않는데 불필요한 성능 이슈를 발생시킬 수 있기 때문에 모든 로그를 System.out.println()으로 찍는 행위는 절때 삼가해야 한다.

2. 불필요한 메모리 사용의 문제

로그를 남길때 일반적으로 다음과 같이 기록한다.

 logger.log("로깅");
 logger.log("로깅" + value + "!!!");

이때 로그를 남기는 문자열때문에 String 객체를 생성하게 되고, 이후에는 GC가 발생할 것이다.
두번째 예와 같이 문자열을 더하는 내용이 있고, 그러한 부분이 많다면 성능의 문제는 더 커진다.

3. 로그를 처리하는 방법

3.1. 디버그 flag를 준다.

Debug flag를 설정하고, Debug 모드가 아닌 상용모드에서는 로그가 출력되지 않게 운영한다.

특히나 flag를 final로 주게 되면 컴파일 시 해당 내용이 모두 제거되는 장점이 있다.

final로 준다는 것은 값이 절때 변경되지 않는다는 것이기 때문에 컴파일러에 의해 제거된다. 이때 단점은 외부 요건에 의해서 임시로 Debug 모드를 켤 수 있는 기능을 구현할 수 없다는 것이다.

주의점

참고로, flag를 어떻게 설정하느냐에 따라 2번째 단점이었던 “불필요한 메모리 사용의 문제”가 해결될수도 있고 해결되지 않을 수도 있다.

아래와 같이 로그를 남기면 불필요한 String 객체 생성이 없을 것이다.

 if(isDebug) {
 	logger.log("로그");
 }

하지만 일반적으로 많이 사용하는 아래와 같은 방법은 여전히 불필요한 String 객체 생성을 막지 못한다.

Logger.info("로그");

public class Logger {
	private boolean isDebug = true;
	
	public static void info(String log) {
		if(isDebug) {
			print(log);
		}
	}
}

3.2. 외부 로거 Library를 사용한다.

외부 Logger Library를 사용하는 것도 좋은 방법이다.
외부 라이브러리는 불필요한 객체 생성 등 성능 이슈에 대한 기본적인 처리를 했기 때문이다.

  • Java Log library
    Log4j, slf4j, LogBack 등…

카테고리:

업데이트:

댓글남기기