System.out.println 보단 Log를 사용해야하는 이유

 

프로그래밍 입문자들이라면 Hello World!라는 문자를 System.out.println으로 찍어본경험 다들한번씩 있을것이다.

또한 개인 프로젝트나 팀 프로젝트를 처음 만드는 사람들은 데이터의 흐름을 파악하기위해 println을 통해서 문자를 찍고

제대로 값이 출력되나 확인하는 사람들이 많은텐데 어디선가 표준출력대신에 로깅을 하는것이 더 좋다고 들었던것같다

하지만 간편하게 println으로 그냥 출력하고 확인하면 되는데 굳이 왜 로깅을 하라고하는것일까?

 

SLF4J나 Logback같은 로깅 프레임워크를 통해서 왜 로깅하는게 더좋은 차근차근 알아보자

그리고 그 과정을통해서 println의 한계점(단점)과 로깅에 장점에 대해서 비교해보록 하겠다

 

 

 

 

 

 

먼저 System.out.println()의 특징에 대해서 하나씩 알아보도록 하자.

첫번째 특징으로는  로그가 표준출력으로 콘솔에 출력되게된다 이게무슨말이냐면 파일로 저장되지않고 사라진다는 뜻이다

사실 우리가 로그를 남기는 이유는 사용자들의 발자취들을 남겨 어디에서 오류가났는지 파악과더불어 여러 정보들을 수집하고 그 결과를 통해서 분석할수있다

하지만 표준출력으로 한번 출력됨과 동시에 저장이 되지않고 사라지기때문에 히스토리가 남지않아 발생한 오류에대해서 기록하거나 분석할수없다

이게 첫번째 특징이다

 

그다음은 에러 발생시에 분석할수있는 상세한 정보가 부족하다는것이다

System.out.println()은 인자로 전달된 값만을 문자열로 출력한다. 이는 곧 문제가 발생한 날짜나 시간, 어디에서 발생한지 알수없다는 뜻이다

물론 인자로 날짜와 시간, 위치, 정보 등을 남기면 좋지만 일일히 번거롭게 남기기에는 코드도 지저분해지고 효율적이지않다

 

그다음은 출력레벨을 지정할수 없다는것이 단점이된다

이게무슨말일까

우리가 보통 자신의 컴퓨터에서 개발할때는 자세한 정보를 남기고 출력해서 확인할수 있어야한다

하지만 직접 서비스를 시작하게되고, 오류가 발생하게되면 많은 정보들이 로그에 남게된다면 문제해결을 위한 정보를 얻기힘들과 동시에 보안적으로 중요한 정보들까지 로그에 남길수도있기 때문에 로그에 레벨을 정해서 관리한다

 

한마디로 개발단계에서 오류레벨을 자세하게 보여주고 직접 서비스되는 환경에서는 문제해결을 위한 최소한의 정보만 남기는 레벨로 설정한다

이런식으로 유연한 개발이 가능하게 만들어주는게 로깅 라이브러리들이다

하지만 System.out.println()은 이런기능을 제공하질않고, 계속해서 설정한 로그설정값들을 출력하게된다

굳이 서비스에서 안보여도될 정보까지도 전부 로그에 남기는 사태가 벌어지고 만다

 

 

 

그다음으론 System.out.println() 이 애플리케이션의 성능을 저하시킬수있는 원인이 될수도있다

이게 무슨말인지는 println()이 구현되어있는 방식을 까보면 알수있다

 

 

 

println() 메서드를 보면 newLine() 이라는 메서드를 호출하는것을 확인할수있다.

이것이 무엇인지 한번 더 들어가보도록 하자

 

 

 

 

 

newLine() 메서드의 구현내용이다 우리가 볼부분은 synchronized(동기화) 부분이다

동기화가 걸리게되면 해당 newLine() 이라는 메서드는 임계영역이 되며 다른 쓰레드가 모두사용되고 Lock을 풀어줄때

다른 쓰레드가 newLine() 메소드를 실행할수 있다는 뜻이다

 

이게 어떤 문제를 발생시킬수있을까?

만약 우리가 만든서비스에 만명의 사용자가 요청하고 처리하는 과정에서 로그를 System.out.println() 으로 남겼다고 가정을해보자

스프링에서는 쓰레드풀에서 쓰레드들이 요청을 처리하게되는데 println() 메서드는 다른쓰레드가 쓰고있으면 접근하지 못하게된다

이는즉 쓸데없는 성능저하가 발생할수 있다는것이다

위에 정보를 종합해보면 System.out.println() 보다는 로깅을 사용하는것이 무조건 좋고 만약 내가직접 서비스를 해야하고 사용자들에게 평가를 받아야하는 프로젝트라면 System.out.println()의 사용은 절때 하지말아야 하는것이다

 

 

하지만 간편하게 값을 찍어볼때는 사용해도 괜찮을꺼같기도 하다..?