[아이티센 부트캠프] Spring Boot 7

이언덕·2026년 4월 27일

아이티센 부트캠프

목록 보기
76/115
post-thumbnail

로그

이 단원은 System.out.println()처럼 단순히 값을 출력하는 방식이 아니라, Logger를 사용해 실행 흐름과 오류 상황을 단계별로 기록하는 방법을 이해하는 구간이다.
log는 프로그램이 실행되는 동안 어떤 일이 일어났는지 남기는 기록이다.


웹 애플리케이션은 브라우저 화면만 보고 전체 흐름을 알기 어렵다.
요청이 들어왔는지, 어떤 컨트롤러가 실행됐는지, 오류가 발생했는지, 어떤 값이 처리됐는지는 서버 내부에서 확인해야 한다.
이때 사용하는 것이 로그이다.


로그는 서버 내부에서 발생한 일을 개발자가 확인할 수 있도록 남기는 실행 기록이다.
화면에 보여 주기 위한 출력이 아니라, 개발자가 프로그램 상태를 파악하기 위해 남기는 기록이라고 이해하면 된다.


로그가 필요한 이유

프로그램을 만들다 보면 코드가 내가 생각한 대로 실행되는지 확인해야 한다.
처음에는 System.out.println()으로 값을 출력하면서 확인할 수 있다.
하지만 프로젝트가 커지면 단순 출력만으로는 부족하다.


예를 들어 어떤 요청에서 오류가 났는지, 위험한 상황인지, 단순 확인용 메시지인지 구분해야 한다.
또 운영 중인 서버에서는 모든 메시지를 같은 방식으로 출력하면 필요한 정보를 찾기 어렵다.
그래서 메시지의 중요도에 따라 구분해서 기록하는 방식이 필요하다.


로그를 사용하면 실행 흐름을 단계별로 남길 수 있다.
오류 상황은 error, 경고 상황은 warn, 일반 정보는 info처럼 나누어 기록할 수 있다.
이렇게 나누어 두면 어떤 메시지가 더 중요한지 빠르게 판단할 수 있다.


로그가 필요한 이유를 정리하면 이렇다.

  • 서버 내부 실행 흐름을 확인할 수 있다.
  • 오류가 발생한 위치와 상황을 파악할 수 있다.
  • 메시지의 중요도에 따라 구분해서 출력할 수 있다.
  • 운영 환경에서 불필요한 출력은 줄이고 필요한 기록만 남길 수 있다.

로그의 핵심은 단순 출력이 아니라, 실행 상황을 의미 있는 기록으로 남기는 것이다.
그래서 실무에서는 System.out.println()보다 로그 기능을 사용하는 것이 더 자연스럽다.


출력문과 로그의 차이

System.out.println()은 콘솔에 값을 바로 출력하는 가장 단순한 방법이다.
처음 코드를 확인할 때는 사용하기 쉽다.
하지만 출력 메시지의 중요도를 구분하기 어렵고, 어떤 클래스에서 출력한 메시지인지 관리하기도 어렵다.


반면 로그는 메시지에 레벨을 붙여 출력한다.
레벨은 메시지의 중요도를 뜻한다.
예를 들어 심각한 오류는 error, 주의가 필요한 상황은 warn, 일반 흐름 확인은 info로 구분할 수 있다.


또 로그는 어느 클래스에서 출력됐는지도 함께 확인할 수 있다.
실제 콘솔 로그를 보면 시간, 로그 레벨, 실행 스레드, 클래스명, 메시지가 함께 출력된다.
그래서 단순히 “값이 찍혔다”에서 끝나는 것이 아니라, 언제, 어디서, 어떤 수준의 메시지가 출력됐는지 확인할 수 있다.


차이를 비교하면 이렇다.

  • System.out.println()은 단순 출력이다.
  • 로그는 중요도에 따라 메시지를 구분해서 출력한다.
  • System.out.println()은 출력 관리가 어렵다.
  • 로그는 설정에 따라 특정 레벨 이상의 메시지만 출력할 수 있다.
  • 로그는 어느 클래스에서 출력된 메시지인지 확인하기 쉽다.

System.out.println()은 간단한 확인용으로는 편하다.
하지만 서버 실행 흐름과 오류 상황을 관리하려면 로그를 사용하는 것이 더 적합하다.


로그 도구 관계 이해하기

화면에는 Log4J 테스트라고 표시되어 있다.
하지만 코드에서는 org.slf4j.Logger, LoggerFactory, @Slf4j를 사용한다.
그래서 처음 보면 Log4J와 SLF4J가 헷갈릴 수 있다.


이 단계에서는 깊게 들어가지 않고 역할만 나누어 이해하면 된다.
SLF4J는 로그를 찍기 위한 공통 사용 방식이다.
개발자는 SLF4J의 Logger를 사용해서 log.info(), log.error() 같은 코드를 작성한다.


Log4J, Logback 같은 것은 실제 로그를 출력하는 구현체로 이해하면 된다.
구현체는 실제로 로그를 어떤 방식으로 출력하고 관리할지 담당한다.
즉, SLF4J는 로그를 사용하는 공통 문법에 가깝고, Log4J나 Logback은 실제 출력 담당에 가깝다.


Spring Boot에서는 기본적으로 SLF4J를 통해 로그 코드를 작성하고, 내부 구현체로는 주로 Logback이 사용된다고 이해하면 된다.
즉, 코드에서는 SLF4J 방식으로 log.info()처럼 작성하고, 실제 출력은 내부 구현체가 처리하는 흐름이다.


이 예제에서는 우선 이렇게 이해하면 충분하다.

  • SLF4J는 로그를 남기기 위해 코드에서 사용하는 공통 방식이다.
  • LoggerFactory는 Logger 객체를 직접 만들어 사용할 때 쓴다.
  • @Slf4j는 Lombok을 이용해 log 객체를 자동으로 만들어 주는 방식이다.
  • Log4J 테스트라는 화면 문구는 로그 기능을 테스트한다는 의미로 보면 된다.

이 글의 핵심은 Log4J 설정을 깊게 다루는 것이 아니라, SLF4J 방식으로 로그를 남기고 콘솔에서 확인하는 흐름을 이해하는 것이다.
따라서 먼저 Logger 사용법과 로그 레벨을 정확히 잡으면 된다.


로그 레벨 이해하기

로그 레벨은 로그 메시지의 중요도를 나타낸다.
모든 로그가 같은 중요도를 가지는 것은 아니다.
서버가 바로 확인해야 할 심각한 오류도 있고, 단순히 흐름을 확인하기 위한 메시지도 있다.


자주 사용하는 로그 레벨은 아래와 같다.

  • error는 심각한 오류 상황을 기록할 때 사용한다.
  • warn은 당장 멈추지는 않지만 주의가 필요한 상황을 기록할 때 사용한다.
  • info는 일반적인 실행 흐름이나 상태 정보를 기록할 때 사용한다.
  • debug는 개발 중 자세한 확인이 필요할 때 사용한다.
  • trace는 debug보다 더 자세한 추적 정보가 필요할 때 사용한다.

중요도 기준으로 보면 보통 error가 가장 높고, 그다음 warn, info, debug, trace 순서로 이해하면 된다.


Spring Boot에서는 기본 설정 상태에서 보통 info 이상의 로그가 출력된다.
즉, error, warn, info는 콘솔에 보이고, debug, trace는 설정을 바꾸지 않으면 보이지 않을 수 있다.
그래서 코드에 log.debug()나 log.trace()를 작성했는데 콘솔에 안 보인다고 해서 코드가 실행되지 않은 것은 아니다.


예제에서 log.debug()와 log.trace()를 호출해도 콘솔 이미지에 보이지 않을 수 있다.
이것은 로그 출력 기준이 현재 info 이상으로 잡혀 있기 때문이라고 이해하면 된다.


debug 로그까지 보고 싶다면 설정 파일에서 로그 레벨을 바꿀 수 있다.
예를 들어 application.properties에 아래처럼 작성하면 com.example.springedu 패키지의 debug 로그까지 출력할 수 있다.

// application.properties
logging.level.com.example.springedu=debug

이 설정을 추가하면 log.debug()로 작성한 로그도 콘솔에 출력될 수 있다.
다만 trace까지 보고 싶다면 값을 trace로 더 낮춰야 한다.

// application.properties
logging.level.com.example.springedu=trace

로그는 작성한 모든 메시지가 항상 보이는 것이 아니라, 현재 로그 레벨 설정에 따라 출력 여부가 달라질 수 있다.
이 점을 알아야 콘솔 결과를 보고 헷갈리지 않는다.

기본 개념예제

아래 예제는 로그 레벨별로 메시지를 출력하는 기본 흐름이다.

// LogLevelBasicController.java
package com.example.springedu.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class LogLevelBasicController {
    private static final Logger log = LoggerFactory.getLogger(LogLevelBasicController.class); // 로그 객체를 만든다

    @RequestMapping("/log-level-basic")
    public String logLevelBasic() {
        log.error("error 로그입니다."); // 가장 심각한 오류 상황
        log.warn("warn 로그입니다."); // 주의가 필요한 상황
        log.info("info 로그입니다."); // 일반 실행 정보
        log.debug("debug 로그입니다."); // 개발 중 자세한 확인 정보
        log.trace("trace 로그입니다."); // 가장 자세한 추적 정보
        return "logView"; // 화면 이름을 반환한다
    }
}

이 코드는 /log-level-basic 요청이 들어오면 로그를 레벨별로 출력한다.
기본 설정에서는 error, warn, info만 보이고 debug, trace는 보이지 않을 수 있다.
이 기본예제에서는 화면 자체가 핵심이 아니므로, 응용예제에서 사용하는 logView.html 같은 간단한 안내 화면으로 이동한다고 보면 된다.

// 콘솔 결과 예시
// ERROR ... LogLevelBasicController : error 로그입니다.
// WARN  ... LogLevelBasicController : warn 로그입니다.
// INFO  ... LogLevelBasicController : info 로그입니다.

이 결과에서 중요한 점은 debug와 trace 코드가 있어도 콘솔에 안 보일 수 있다는 것이다.
그 이유는 현재 로그 출력 기준이 info 이상으로 잡혀 있을 수 있기 때문이다.


로그 객체 직접 만들기

LoggerFactory는 로그를 출력할 Logger 객체를 직접 만들 때 사용한다.
Logger 객체가 있어야 log.error(), log.warn(), log.info() 같은 메서드를 호출할 수 있다.


보통 클래스 안에 아래와 같은 형태로 작성한다.


private static final Logger log = LoggerFactory.getLogger(클래스명.class);


여기서 private static final은 로그 객체를 클래스 안에서 하나만 만들어 계속 사용하겠다는 의미로 이해하면 된다.
초보자 단계에서는 “이 클래스에서 사용할 로그 도구를 하나 준비한다” 정도로 이해하면 충분하다.


LoggerFactory.getLogger(LogTestController1.class)처럼 클래스 정보를 넘기면, 로그 출력 시 어떤 클래스에서 찍힌 로그인지 확인할 수 있다.
그래서 콘솔 로그에 컨트롤러 클래스명이 함께 표시된다.

기본 개념예제

아래 예제는 LoggerFactory로 로그 객체를 직접 만든 뒤, 요청이 들어왔을 때 로그를 출력하는 흐름이다.

// LoggerFactoryBasicController.java
package com.example.springedu.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class LoggerFactoryBasicController {
    private static final Logger log = LoggerFactory.getLogger(LoggerFactoryBasicController.class); // 로그 객체 생성

    @RequestMapping("/logger-basic")
    public String loggerBasic() {
        log.info("LoggerFactory 방식으로 로그를 출력합니다."); // info 로그 출력
        return "logView"; // logView.html로 이동
    }
}

이 방식은 로그 객체를 직접 선언하는 방식이다.
코드가 조금 길지만, 어떤 클래스의 로그 객체를 만드는지 명확하게 보인다.

// 콘솔 결과 예시
// INFO ... LoggerFactoryBasicController : LoggerFactory 방식으로 로그를 출력합니다.

이 예제의 핵심은 LoggerFactory.getLogger()로 log 객체를 직접 만든다는 점이다.
이후에는 log.info()처럼 로그 메서드를 호출해서 콘솔에 기록을 남긴다.


로그 객체 자동 생성하기

@Slf4j는 Lombok이 제공하는 어노테이션이다.
클래스 위에 @Slf4j를 붙이면 log라는 이름의 로그 객체가 자동으로 만들어진다.
그래서 LoggerFactory.getLogger() 코드를 직접 작성하지 않아도 된다.


@Slf4j는 Lombok이 제공하는 어노테이션이므로, 프로젝트에서 Lombok을 사용할 수 있는 상태여야 한다.
Lombok 설정이 되어 있지 않으면 log 객체가 자동 생성되지 않아 오류가 날 수 있다.


즉, 아래 두 방식은 목적이 같다.
하나는 로그 객체를 직접 만들고, 다른 하나는 Lombok이 자동으로 만들어 주는 방식이다.

  • LoggerFactory 방식은 Logger 객체를 직접 선언한다.
  • @Slf4j 방식은 log 객체를 자동 생성한다.

@Slf4j를 사용하면 코드가 짧아진다.
하지만 내부적으로는 결국 로그를 출력할 log 객체를 사용하는 흐름이라고 이해하면 된다.

기본 개념예제

아래 예제는 @Slf4j를 사용해 로그 객체를 자동으로 만든 뒤 로그를 출력하는 흐름이다.

// Slf4jBasicController.java
package com.example.springedu.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Slf4j
@Controller
public class Slf4jBasicController {
    @RequestMapping("/slf4j-basic")
    public String slf4jBasic() {
        log.info("@Slf4j 방식으로 로그를 출력합니다."); // 자동 생성된 log 객체 사용
        return "logView"; // logView.html로 이동
    }
}

이 코드에는 LoggerFactory.getLogger()가 없다.
그 대신 클래스 위에 @Slf4j가 붙어 있다.
Lombok이 log 객체를 자동으로 만들어 주기 때문에 바로 log.info()를 사용할 수 있다.

// 콘솔 결과 예시
// INFO ... Slf4jBasicController : @Slf4j 방식으로 로그를 출력합니다.

이 예제의 핵심은 @Slf4j를 사용하면 로그 객체 선언 코드를 줄일 수 있다는 점이다.
다만 로그를 출력하는 방식 자체는 log.info(), log.error()처럼 동일하다.


로그 출력 결과는 어디서 확인하는가

로그는 브라우저 화면에 직접 출력되는 것이 아니다.
브라우저 화면은 컨트롤러가 반환한 View를 보여 준다.
반면 로그는 서버 콘솔에서 확인한다.


예를 들어 컨트롤러에서 log.info("요청이 들어왔습니다.")를 실행해도, 이 문장이 브라우저 화면에 바로 보이는 것은 아니다.
브라우저에는 logView.html 같은 화면이 보이고, 로그 메시지는 톰캣 콘솔이나 서버 실행 콘솔에 출력된다.


그래서 로그 예제에서는 화면에 “톰캣콘솔창에서 확인하세요!!” 같은 안내 문구를 보여 줄 수 있다.
실제 확인해야 하는 것은 브라우저 화면이 아니라 서버 콘솔이다.


로그는 사용자에게 보여 주는 화면 출력이 아니라, 개발자가 서버 실행 상태를 확인하기 위해 콘솔에서 보는 기록이다.
이 차이를 알면 /log1, /log2 결과 화면과 콘솔 로그를 함께 보는 이유를 이해할 수 있다.


로그 핵심 정리

로그는 서버 내부 실행 흐름과 오류 상황을 확인하기 위한 기록이다.
System.out.println()보다 관리하기 좋고, 메시지의 중요도에 따라 구분해서 출력할 수 있다.


이 단원에서 중요한 흐름은 다음과 같다.

  • 로그는 서버 내부 실행 상황을 기록하는 기능이다.
  • System.out.println()은 단순 출력이고, 로그는 레벨을 가진 기록이다.
  • error, warn, info, debug, trace는 로그 레벨이다.
  • 기본 설정에서는 보통 error, warn, info가 콘솔에 출력된다.
  • debug, trace는 코드에 있어도 설정에 따라 콘솔에 보이지 않을 수 있다.
  • application.properties에서 로그 레벨을 바꾸면 debug, trace 출력 여부를 조정할 수 있다.
  • SLF4J는 로그를 작성하는 공통 방식이다.
  • Spring Boot에서는 보통 SLF4J를 통해 로그를 작성하고 Logback이 실제 출력을 처리한다고 이해하면 된다.
  • LoggerFactory는 Logger 객체를 직접 만들 때 사용한다.
  • @Slf4j는 Lombok이 log 객체를 자동으로 만들어 주는 방식이다.
  • 로그 출력 결과는 브라우저가 아니라 톰캣 콘솔에서 확인한다.

로그의 핵심은 서버에서 일어난 일을 중요도에 따라 기록하고, 개발자가 콘솔에서 그 흐름을 확인할 수 있게 하는 것이다.
이제 응용예제에서 /log1, /log2 요청을 통해 실제 로그가 어떻게 콘솔에 출력되는지 확인하면 된다.




응용예제

1. LoggerFactory와 Slf4j 로그 출력 확인하기 (LogTestController1.java, LogTestController2.java, logView.html)

앞에서는 로그가 서버 내부 실행 흐름을 기록하기 위한 기능이고, LoggerFactory와 @Slf4j를 통해 log 객체를 사용할 수 있다고 정리했다.
이 예제는 그 개념을 실제 컨트롤러 요청과 톰캣 콘솔 출력으로 확인하는 예제이다.


실제로는 LoggerFactory 방식으로 로그 객체 만들기, @Slf4j 방식으로 로그 객체 자동 생성하기, 로그 레벨별 출력, 브라우저 화면과 콘솔 로그의 차이, 요청한 클라이언트 정보 출력까지 함께 보여 준다.
즉, 이 묶음은 /log1, /log2 요청을 통해 브라우저에는 안내 화면을 보여 주고, 실제 로그는 톰캣 콘솔에서 확인하는 응용예제이다.


먼저 실행 흐름만 간단히 보면 이렇다.

  • /log1 요청은 LogTestController1이 처리한다.
  • LogTestController1은 LoggerFactory.getLogger()로 직접 만든 log 객체를 사용한다.
  • /log2 요청은 LogTestController2가 처리한다.
  • LogTestController2는 @Slf4j로 자동 생성된 log 객체를 사용한다.
  • 두 요청 모두 브라우저에는 logView.html을 보여 준다.
  • 실제 로그 메시지는 톰캣 콘솔에서 확인한다.



이 예제가 같이 보여주는 개념

먼저 화면으로 사용할 logView.html을 확인한다.
이 화면은 로그 내용을 직접 보여 주는 화면이 아니다.
브라우저에는 안내 문구만 보여 주고, 실제 로그는 톰캣 콘솔에서 확인하게 만든다.

// logView.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>Log4J 테스트</h1>
<hr>
<h2>[[${ msg }]]</h2>
</body>
</html>

[[${ msg }]]는 컨트롤러에서 넘긴 msg 값을 화면에 출력한다.
이 예제에서는 msg에 "톰캣콘솔창에서 확인하세요!!"를 담아 브라우저에 보여 준다.
즉, 브라우저 화면은 로그 결과가 아니라 로그를 콘솔에서 확인하라는 안내 화면이다.


첫 번째 컨트롤러는 LogTestController1.java이다.
이 컨트롤러는 LoggerFactory.getLogger()로 Logger 객체를 직접 만든다.

// LogTestController1.java
package com.example.springedu.controller;

import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class LogTestController1 {
    private static final Logger log = LoggerFactory.getLogger(LogTestController1.class); // 로그 객체를 직접 만든다

    @RequestMapping("/log1")
    public ModelAndView xxx(HttpServletRequest req) {
        log.error("error-로그를 테스트합니다!"); // error 로그 출력
        log.warn("warn-로그를 테스트합니다!"); // warn 로그 출력
        log.info("info-로그를 테스트합니다!"); // info 로그 출력
        log.debug("debug-로그를 테스트합니다!"); // debug 로그 출력
        log.trace("trace-로그를 테스트합니다!"); // trace 로그 출력

        ModelAndView mav = new ModelAndView(); // 화면 이름과 데이터를 함께 담을 객체를 만든다
        mav.setViewName("logView"); // logView.html로 이동한다
        mav.addObject("msg", "톰캣콘솔창에서 확인하세요!!"); // 화면에 보여 줄 안내 메시지를 담는다
        return mav;
    }
}

이 코드의 핵심은 LoggerFactory.getLogger(LogTestController1.class)이다.
이 코드로 LogTestController1에서 사용할 로그 객체를 직접 만든다.
그 다음 log.error(), log.warn(), log.info(), log.debug(), log.trace()를 호출해 레벨별 로그를 출력한다.


하지만 기본 설정에서는 보통 debug와 trace가 콘솔에 보이지 않을 수 있다.
그래서 결과 화면에서는 error, warn, info 로그만 확인될 수 있다.
이것은 코드가 실행되지 않은 것이 아니라, 현재 로그 출력 기준이 info 이상으로 설정되어 있기 때문이라고 이해하면 된다.


두 번째 컨트롤러는 LogTestController2.java이다.
이 컨트롤러는 LoggerFactory를 직접 쓰지 않고 @Slf4j를 사용한다.

// LogTestController2.java
package com.example.springedu.controller;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Slf4j
@Controller
public class LogTestController2 {
    @RequestMapping("/log2")
    public ModelAndView xxx(HttpServletRequest req) {
        log.error(req.getRemoteHost() + "로 부터 요청이 왔어요!"); // 요청한 클라이언트 정보를 error 로그로 출력
        log.warn(req.getRemoteHost() + "로 부터 요청이 왔어요!"); // 요청한 클라이언트 정보를 warn 로그로 출력
        log.info(req.getRemoteHost() + "로 부터 요청이 왔어요!"); // 요청한 클라이언트 정보를 info 로그로 출력
        log.debug(req.getRemoteHost() + "로 부터 요청이 왔어요!"); // 요청한 클라이언트 정보를 debug 로그로 출력
        log.trace(req.getRemoteHost() + "로 부터 요청이 왔어요!"); // 요청한 클라이언트 정보를 trace 로그로 출력

        ModelAndView mav = new ModelAndView(); // 화면 이름과 데이터를 함께 담을 객체를 만든다
        mav.setViewName("logView"); // logView.html로 이동한다
        mav.addObject("msg", "톰캣콘솔창에서 확인하세요!!"); // 화면에 보여 줄 안내 메시지를 담는다
        return mav;
    }
}

@Slf4j가 붙어 있기 때문에 log 객체를 직접 선언하지 않아도 된다.
Lombok이 자동으로 log 객체를 만들어 준다.
그래서 바로 log.error(), log.warn(), log.info() 같은 메서드를 사용할 수 있다.


이 코드에서는 req.getRemoteHost()를 사용한다.
req는 요청 정보를 담고 있는 HttpServletRequest 객체이다.
getRemoteHost()는 요청을 보낸 클라이언트의 호스트 정보를 가져온다.
로컬 환경에서 테스트하면 0:0:0:0:0:0:0:1처럼 보일 수 있는데, 이는 로컬 주소를 나타내는 IPv6 형태의 localhost라고 이해하면 된다.


그래서 결과가 이렇게 나온다

첫 번째는 /log1을 요청한 경우이다.
브라우저에는 logView.html이 열린다.
화면에는 Log4J 테스트 제목과 톰캣콘솔창에서 확인하세요!! 문구가 출력된다.


log1 브라우저 결과

이 화면에서 중요한 점은 로그가 브라우저에 직접 출력되지 않는다는 것이다.
브라우저는 컨트롤러가 반환한 logView.html을 보여 줄 뿐이다.
실제 로그는 톰캣 콘솔에서 확인해야 한다.


/log1 요청 후 톰캣 콘솔을 보면 LogTestController1에서 출력한 로그가 보인다.

// 콘솔 결과
// ERROR ... LogTestController1 : error-로그를 테스트합니다!
// WARN  ... LogTestController1 : warn-로그를 테스트합니다!
// INFO  ... LogTestController1 : info-로그를 테스트합니다!

log2 브라우저 결과

콘솔에는 error, warn, info 로그가 출력된다.
코드에는 debug, trace도 있지만 기본 설정에서는 보이지 않을 수 있다.
즉, 로그 출력 결과는 코드에 작성한 로그 레벨과 현재 로그 설정에 따라 달라질 수 있다.


두 번째는 /log2를 요청한 경우이다.
브라우저에는 /log1과 같은 logView.html이 열린다.
화면에 보이는 문구도 같다.


LogTestController1 콘솔 로그

/log2도 브라우저 화면만 보면 /log1과 거의 같다.
하지만 콘솔 로그를 보면 차이가 있다.
LogTestController2는 요청한 클라이언트 정보를 로그 메시지에 함께 출력한다.

// 콘솔 결과
// ERROR ... LogTestController2 : 0:0:0:0:0:0:0:1로 부터 요청이 왔어요!
// WARN  ... LogTestController2 : 0:0:0:0:0:0:0:1로 부터 요청이 왔어요!
// INFO  ... LogTestController2 : 0:0:0:0:0:0:0:1로 부터 요청이 왔어요!

LogTestController2 콘솔 로그

콘솔에는 LogTestController2에서 출력한 로그가 보인다.
0:0:0:0:0:0:0:1은 로컬에서 요청했을 때 보일 수 있는 주소이다.
즉, 같은 화면을 반환하더라도 로그 메시지에는 요청한 클라이언트 정보처럼 서버 내부 확인용 정보를 남길 수 있다.


이 예제의 핵심을 다시 정리하면 이렇다.

  • /log1은 LoggerFactory로 직접 만든 log 객체를 사용한다.
  • /log2는 @Slf4j로 자동 생성된 log 객체를 사용한다.
  • 두 방식 모두 log.error(), log.warn(), log.info()처럼 로그를 출력한다.
  • 브라우저에는 logView.html이 보인다.
  • 실제 로그 결과는 톰캣 콘솔에서 확인한다.
  • 기본 설정에서는 debug, trace 로그가 보이지 않을 수 있다.
  • HttpServletRequest의 getRemoteHost()를 사용하면 요청한 클라이언트 정보를 로그에 남길 수 있다.

결국 이 응용예제는 브라우저 화면과 서버 로그는 역할이 다르며, 로그는 서버 내부 흐름을 확인하기 위해 콘솔에서 보는 기록이라는 점을 확인하는 예제이다.
LoggerFactory 방식과 @Slf4j 방식은 로그 객체를 준비하는 방법이 다를 뿐, 최종적으로 log 객체로 로그를 출력한다는 흐름은 같다.

0개의 댓글