
1. 서론
Spring boot에서 어떠한 정보를 출력하고 싶을 때 필요한 정보를 출력하거나 디버깅하지 않고, logging을 이용하여 로그를 남기는 경우가 있습니다.
저처럼 제대로 이해하지 않고 로그를 사용하면 원하는 정보가 나오지 않고 불필요한 연산이 일어나기 때문에 로그의 사용법을 정리하고자 합니다.
로그를 사용하기 전 로그가 무엇인지 알아보자.
Log 란?
서버 컴퓨터의 운영 단계에서 사용자에게 시스템이 돌아가는 상황, 행위, 정보, 이벤트를 알려주는 기록이며, 기록된 데이터를 출력한 후 별도로 저장하기 위해 사용합니다.
즉 로그는 기록입니다. 로그를 통해서 프로그램의 상태를 볼 수 잇고, 오류가 발생한 부분에 대해서 쉽게 인지를 할 수있습니다.
따라서 프로그램의 흐름, 예외, 에러 등을 쉽게 인지할 수 있고 로그를 통해서 서비스의 품질을 관리할 수 있습니다.
try{
}catch (Exception e){
log.error("userId={}, method = {}, parameter={}, time={}, errorMsg={}",
userId,method,parameter,time,e.getMessage());
}
log.error는 밑에서 알아보도록 하고, 예를 들면 catch문에 로그를 남길 때 위 코드처럼 사용한다면 누가, 언제, 어디서 어떠한 에러를 등 에러의 정보를 보다 쉽게 파악하고 찾을 수 있습니다.
logging의 장점
그렇다면 왜 굳이 println문으로 찍지 않고, 굳이 logging을 사용해야 하는 것인가?
- 스레드 정보, 클래스 이름 등의 정보를 함께 볼 수 있고, 출력 모양을 원하는 데로 조정할 수 있습니다.
- 로그 레벨에 따라 개발서버에서는 모든 로그를 출력하고, 운영서버에서는 출력하지 않는 등 로그를 상황에 맞게 조절할 수 있습니다.
- console 창에만 출력하는 것이 아니라, 파일이나 네트워크 등, 로그를 별도의 위치에 남길 수 있습니다.
- println을 썼을 때보다 내부 버퍼링, 멀티 스레드 등의 환경에서 훨씬 좋다
개발 서버는 디버깅에 필요한 상세한 정보를 봐야 하기 때문에
➡ debug
운영 서버는 의미 없는 로그와 디버깅이 필요 없고, 기본정보나, 에러가 발생한 경우에만 로그가 필요하기 때문에
➡ info
2. logging
@Controller
public class LogTestController {
private final Logger log = LoggerFactory.getLogger(getClass());//내 클래스를 지정
@RequestMapping("/log_test")
private String logTest() {
log.info("@@@ hello logTest @@@");
return null;
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogTestController {
private final Logger log = LoggerFactory.getLogger(getClass());
@GetMapping("log_test")
public String logTest() {
String name = "Spring";
log.trace("trace log = {}", name);
log.debug("debug log = {}", name);
log.info("info log = {}", name);
log.warn("warn log = {}", name);
log.error("error log = {}", name);
return null;
}
}
로그를 남기고 싶을 때 logging 라이브러리를 사용하여 로그를 남길 수 있습니다.
대표적인 logging 라이브러리는 SLF4 J 인터페이스가 있으며, Logback, log4 j, log4 j2 구현체가 있습니다.
"/log_test"로 요청이 들어오면 "@@@ hello logTest @@@"라는 문자를 가지고 있는 로그가 출력됩니다.
Level | Color | Mean |
1. error | Red | 사용자 요청을 처리하는 중 발생한 문제 |
2. warn | Yellow | 처리 가능한 문제이지만, 향후 시스템 에러의 원인이 될 수 있는 문제 |
3. info | Green | 로그인이나 상태 변경과 같은 정보성 메시지 |
4. debug | Green | 개발시 디버깅 목적으로 출력하는 메시지 |
5. trace | Green | debug 보다 좀 더 상세한 메세지 |
주의점 ❗
2. logging의 코드를 보면 log.trace("trace log = {}", name), log.debug("debug log = {}", name)와 같이 코드의 형식이 "로그 = {} ", log와 같이 되어있습니다.
log.trace("name = " + name)처럼 사용하면 안 되는 것일까?
네. 위처럼 사용하면 안 됩니다. 왜냐하면 ("name = " + name) 코드를 자세히 보면 +가 있습니다. 즉 의미 문자열 출력의 의미를 갖게 되므로, 의미 없는 문자열 연산이 일어나기 때문입니다. 반면에 log.trace("trace log = {}", name)처럼 사용하게 된다면 파라미터로 넘기기 때문에 연산이 일어나지 않습니다.
로그 레벨에 따라서 출력되지 않는 로그 레벨의 문자열 연산이 일어난 뒤 로그 레벨을 검사합니다.
만약에 로그 레벨을 debug로 설정하면 상위 레벨인 TRACE는 검사만 하고 출력하지 않고, 하위 로그 레벨들을 출력하는데, ("name = " + name) 형식으로 사용하면 문자열 연산이 있으므로 문자열 연산을 하고 난 후 레벨을 검사하기 때문입니다.
즉 문자열 연산이 들어가는 형식으로 한다면 출력할 필요가 없음에도 문자열 연산을 수행하기 때문에 비용면에서 좋지 않습니다.
3. 로그 레벨 설정

로그 레벨을 변경하는 코드는 application.yml이나 application.properties로 설정해 주는 것입니다.
application.properties
// application.properties
logging.level.project=debug
application.ym
// application.yml
logging:
level:
root: "DEBUG"
org.springframework: "TRACE"
위 코드와 같이 debug로 설정하게 된다면 하위 레벨은 로깅에 포함되지 않습니다.
'Framework > Spring\Spring boot' 카테고리의 다른 글
[Spring] Spring에서 빈 이름 결정 방식 (0) | 2024.07.28 |
---|---|
[Spring] Spring IoC 컨테이너에 Bean 수동 등록하기 (@Configuration, @Bean) (0) | 2024.07.28 |
[Spring] Spring IoC Container와 Bean 알아보기 (0) | 2024.07.24 |
[Spring] Spring MVC: HTTP 요청 데이터의 객체 변환 방법 (@ModelAttribute vs @RequestBody) (2) | 2024.07.23 |
[Spring] Spring MVC : HTTP 요청으로 데이터 받기 (URL, Query String) (1) | 2024.07.23 |

1. 서론
Spring boot에서 어떠한 정보를 출력하고 싶을 때 필요한 정보를 출력하거나 디버깅하지 않고, logging을 이용하여 로그를 남기는 경우가 있습니다.
저처럼 제대로 이해하지 않고 로그를 사용하면 원하는 정보가 나오지 않고 불필요한 연산이 일어나기 때문에 로그의 사용법을 정리하고자 합니다.
로그를 사용하기 전 로그가 무엇인지 알아보자.
Log 란?
서버 컴퓨터의 운영 단계에서 사용자에게 시스템이 돌아가는 상황, 행위, 정보, 이벤트를 알려주는 기록이며, 기록된 데이터를 출력한 후 별도로 저장하기 위해 사용합니다.
즉 로그는 기록입니다. 로그를 통해서 프로그램의 상태를 볼 수 잇고, 오류가 발생한 부분에 대해서 쉽게 인지를 할 수있습니다.
따라서 프로그램의 흐름, 예외, 에러 등을 쉽게 인지할 수 있고 로그를 통해서 서비스의 품질을 관리할 수 있습니다.
try{
}catch (Exception e){
log.error("userId={}, method = {}, parameter={}, time={}, errorMsg={}",
userId,method,parameter,time,e.getMessage());
}
log.error는 밑에서 알아보도록 하고, 예를 들면 catch문에 로그를 남길 때 위 코드처럼 사용한다면 누가, 언제, 어디서 어떠한 에러를 등 에러의 정보를 보다 쉽게 파악하고 찾을 수 있습니다.
logging의 장점
그렇다면 왜 굳이 println문으로 찍지 않고, 굳이 logging을 사용해야 하는 것인가?
- 스레드 정보, 클래스 이름 등의 정보를 함께 볼 수 있고, 출력 모양을 원하는 데로 조정할 수 있습니다.
- 로그 레벨에 따라 개발서버에서는 모든 로그를 출력하고, 운영서버에서는 출력하지 않는 등 로그를 상황에 맞게 조절할 수 있습니다.
- console 창에만 출력하는 것이 아니라, 파일이나 네트워크 등, 로그를 별도의 위치에 남길 수 있습니다.
- println을 썼을 때보다 내부 버퍼링, 멀티 스레드 등의 환경에서 훨씬 좋다
개발 서버는 디버깅에 필요한 상세한 정보를 봐야 하기 때문에
➡ debug
운영 서버는 의미 없는 로그와 디버깅이 필요 없고, 기본정보나, 에러가 발생한 경우에만 로그가 필요하기 때문에
➡ info
2. logging
@Controller
public class LogTestController {
private final Logger log = LoggerFactory.getLogger(getClass());//내 클래스를 지정
@RequestMapping("/log_test")
private String logTest() {
log.info("@@@ hello logTest @@@");
return null;
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogTestController {
private final Logger log = LoggerFactory.getLogger(getClass());
@GetMapping("log_test")
public String logTest() {
String name = "Spring";
log.trace("trace log = {}", name);
log.debug("debug log = {}", name);
log.info("info log = {}", name);
log.warn("warn log = {}", name);
log.error("error log = {}", name);
return null;
}
}
로그를 남기고 싶을 때 logging 라이브러리를 사용하여 로그를 남길 수 있습니다.
대표적인 logging 라이브러리는 SLF4 J 인터페이스가 있으며, Logback, log4 j, log4 j2 구현체가 있습니다.
"/log_test"로 요청이 들어오면 "@@@ hello logTest @@@"라는 문자를 가지고 있는 로그가 출력됩니다.
Level | Color | Mean |
1. error | Red | 사용자 요청을 처리하는 중 발생한 문제 |
2. warn | Yellow | 처리 가능한 문제이지만, 향후 시스템 에러의 원인이 될 수 있는 문제 |
3. info | Green | 로그인이나 상태 변경과 같은 정보성 메시지 |
4. debug | Green | 개발시 디버깅 목적으로 출력하는 메시지 |
5. trace | Green | debug 보다 좀 더 상세한 메세지 |
주의점 ❗
2. logging의 코드를 보면 log.trace("trace log = {}", name), log.debug("debug log = {}", name)와 같이 코드의 형식이 "로그 = {} ", log와 같이 되어있습니다.
log.trace("name = " + name)처럼 사용하면 안 되는 것일까?
네. 위처럼 사용하면 안 됩니다. 왜냐하면 ("name = " + name) 코드를 자세히 보면 +가 있습니다. 즉 의미 문자열 출력의 의미를 갖게 되므로, 의미 없는 문자열 연산이 일어나기 때문입니다. 반면에 log.trace("trace log = {}", name)처럼 사용하게 된다면 파라미터로 넘기기 때문에 연산이 일어나지 않습니다.
로그 레벨에 따라서 출력되지 않는 로그 레벨의 문자열 연산이 일어난 뒤 로그 레벨을 검사합니다.
만약에 로그 레벨을 debug로 설정하면 상위 레벨인 TRACE는 검사만 하고 출력하지 않고, 하위 로그 레벨들을 출력하는데, ("name = " + name) 형식으로 사용하면 문자열 연산이 있으므로 문자열 연산을 하고 난 후 레벨을 검사하기 때문입니다.
즉 문자열 연산이 들어가는 형식으로 한다면 출력할 필요가 없음에도 문자열 연산을 수행하기 때문에 비용면에서 좋지 않습니다.
3. 로그 레벨 설정

로그 레벨을 변경하는 코드는 application.yml이나 application.properties로 설정해 주는 것입니다.
application.properties
// application.properties
logging.level.project=debug
application.ym
// application.yml
logging:
level:
root: "DEBUG"
org.springframework: "TRACE"
위 코드와 같이 debug로 설정하게 된다면 하위 레벨은 로깅에 포함되지 않습니다.
'Framework > Spring\Spring boot' 카테고리의 다른 글
[Spring] Spring에서 빈 이름 결정 방식 (0) | 2024.07.28 |
---|---|
[Spring] Spring IoC 컨테이너에 Bean 수동 등록하기 (@Configuration, @Bean) (0) | 2024.07.28 |
[Spring] Spring IoC Container와 Bean 알아보기 (0) | 2024.07.24 |
[Spring] Spring MVC: HTTP 요청 데이터의 객체 변환 방법 (@ModelAttribute vs @RequestBody) (2) | 2024.07.23 |
[Spring] Spring MVC : HTTP 요청으로 데이터 받기 (URL, Query String) (1) | 2024.07.23 |