반응형
Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
Tags
- junit
- string
- html
- Visual Studio Code
- 자바스크립트
- Eclipse
- SpringBoot
- IntelliJ
- 정규식
- vscode
- 자바
- junit5
- 자바문법
- HashMap
- 단위테스트
- Java
- js
- javascript
- input
- ArrayList
- 문자열
- 스프링부트
- math
- Array
- 인텔리제이
- java테스트
- CSS
- list
- 테스트자동화
- 배열
Archives
- Today
- Total
어제 오늘 내일
[Spring Boot] 기초편 - System.out.println은 그만! 로그(Log) 제대로 찍기 본문
스프링 부트에서는 System.out.println() 대신 SLF4J라는 인터페이스와 Logback이라는 구현체를 기본으로 사용합니다. 이를 가장 쉽게 쓰는 방법은 롬복(Lombok)의 @Slf4j 어노테이션을 사용하는 것입니다.
기초부터 차근차근 알려드릴게요.
1. 의존성 설정
dependencies {
// 1. Spring Boot Web (여기에 로깅 라이브러리(Logback)가 이미 들어있습니다!)
implementation 'org.springframework.boot:spring-boot-starter-web'
// 2. Lombok (편하게 로그를 찍기 위해 필수)
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// 테스트 코드에서도 롬복을 쓰고 싶다면 추가
testImplementation 'org.projectlombok:lombok'
testAnnotationProcessor 'org.projectlombok:lombok'
}2. 기본 사용법 (@Slf4j)
클래스 위에 @Slf4j만 붙이면 마법처럼 log라는 변수가 생깁니다.
import lombok.extern.slf4j.Slf4j; // 롬복 임포트
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j // ★ 이거 하나면 준비 끝!
@RestController
public class TestController {
@GetMapping("/log-test")
public String logTest() {
String name = "홍길동";
// 1. 문자열 연결 (+) 절대 금지! (메모리 낭비)
// System.out.println("이름은 " + name + "입니다.");
// 2. 중괄호 {} 를 사용하세요 (치환 문자)
log.info("사용자가 접속했습니다. 이름: {}", name);
return "ok";
}
}
결과 콘솔:2025-12-26 14:30:00.123 INFO 12345 --- [nio-8080-exec-1] c.e.board.controller.TestController : 사용자가 접속했습니다. 이름: 홍길동
3. 실무 코드에 적용해보기
우리가 만들었던 MemberController와 MemberService에 로그를 심어보겠습니다.
① MemberController (요청 받음)
사용자가 로그인 데이터를 보냈을 때 로그를 남깁니다.
@Slf4j // ★ 추가
@RestController
@RequestMapping("/members")
@RequiredArgsConstructor
public class MemberController {
private final MemberService memberService;
@PostMapping("/login")
public JwtToken login(@RequestBody MemberLoginDto memberLoginDto) {
// [주의] 비밀번호는 절대 로그에 찍으면 안 됩니다! 보안 사고입니다.
log.info("로그인 요청 들어옴 - username: {}", memberLoginDto.getUsername());
JwtToken token = memberService.login(memberLoginDto.getUsername(), memberLoginDto.getPassword());
log.info("로그인 성공, 토큰 발급 완료");
return token;
}
}
② MemberService (로직 수행)
비즈니스 로직 중간중간 중요한 지점에 로그를 남깁니다.
@Slf4j // ★ 추가
@Service
// ...
public class MemberService {
// ...
@Transactional
public JwtToken login(String username, String password) {
log.info("Service 로그인 로직 시작 - ID: {}", username);
// 1. 검증
// ... (생략)
// 2. 인증 객체 생성
Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken);
log.info("DB 인증 통과 (비밀번호 일치)");
// 3. 토큰 생성
JwtToken jwtToken = jwtTokenProvider.createToken(authentication);
// ... (생략)
return jwtToken;
}
}
4. 로그 레벨 (Level) 이해하기
로그에는 계급(Level)이 있습니다. 중요도에 따라 골라 써야 합니다.
(낮음 🔽 ~ 높음 🔼)
log.trace("..."): 정말 미세한 동작 하나하나 추적할 때 (나사 하나까지 확인)log.debug("..."): 개발할 때 변수 값 확인용, DB 쿼리 확인용 (개발자용)log.info("..."): [기본] 운영 시 확인해야 할 정보 (로그인 성공, 주문 완료 등)log.warn("..."): 에러는 아닌데 주의해야 함 (비번 5회 틀림, 디스크 용량 80% 참)log.error("..."): [비상] 에러 발생! (DB 연결 끊김, 널포인트 익셉션)
[설정 파일에서 조절하기]application.yml에서 "어느 레벨부터 출력할지" 정할 수 있습니다.
logging:
level:
root: INFO # 기본적으로 INFO 이상만 출력 (trace, debug 숨김)
com.example.board: DEBUG # 하지만 내 프로젝트 패키지는 DEBUG 부터 다 보여줘!
5. 왜 System.out.println을 쓰면 안 되나요?
면접 단골 질문이기도 합니다. 꼭 기억하세요!
- 성능 문제:
System.out.println은 출력하는 동안 서버가 잠깐 멈춥니다(Blocking). 사용자가 몰리면 서버가 느려지는 주범이 됩니다. - 정보 부족: 언제(시간), 어디서(클래스), 누가(스레드) 찍었는지 안 나옵니다. "hello" 라고만 찍히면 어디서 찍은 건지 찾을 수가 없습니다.
- 제어 불가: 운영 서버(배포)에서는 잡다한 로그를 끄고 에러만 보고 싶은데,
sout은 일일이 코드를 지우지 않는 이상 끌 수가 없습니다. (로깅 라이브러리는 설정 파일 한 줄로 제어 가능)
반응형
'IT > SpringBoot' 카테고리의 다른 글
| [Spring Boot] AOP 심화 분석 - LogAspect 코드 뜯어보기 & 문법 완벽 정리 (0) | 2026.02.27 |
|---|---|
| [Spring Boot] 로그, 노가다 그만! AOP로 요청/응답/시간 자동 기록하기 (0) | 2026.02.27 |
| [Spring Security] 16편 - "3초 만에 가입" OAuth2 소셜 로그인 연동 (Google) (0) | 2026.02.25 |
| [Spring Security] 15편 - API 문서를 자동으로! Swagger (SpringDoc) 적용하기 (0) | 2026.02.25 |
| [Spring Security] 14편 - 필터 예외 처리의 정석 (ExceptionHandlerFilter) (0) | 2026.02.24 |
Comments
