스프링/3. 스프링 MVC

38. 로그

sdafdq 2023. 8. 11. 23:19

이제 Soutv 같은 거 안쓰고

로그 씀

 

로그는 스프링 부트 하면 보통 기본 라이브러리로 딸려옴.

SLF4J가 인터페이스고

Logback이 구현한 건데 우리가 이걸 씀.

 

종속 라이브러리 중에서

 

spring-boot-starter-logging에서 확인 가능

 

 

@RestController
public class LogTestController {
    private final Logger log = (Logger)LoggerFactory.getLogger(LogTestController.class);

    @GetMapping("log-test")
    public String logTest(){
        String name = "Spring";

        log.info("info log={}", name);
        return "ok";
    }
}

Logger는 slf4j꺼 import 해야 한다. 그리고 LoggerFactory.getLogger(현재클래스.class)

저건 그냥 getClass()해도 된다. 

 

get 메소드로 /log-test로 들어오면 이걸로 응답 받는다.]

 

로그 사용은 log.info("info log={}". name) 이렇게 한다.

 

그럼 

2023-08-11T22:27:45.981+09:00  INFO 20504 --- [nio-8080-exec-1] hello.springmvc.basic.LogTestController      : info log=Spring

 

이렇게 출력된다. 

시간,  INFO 20504 이건 프로세스 ID, [nio-8080-exec-1]  이건 어떤 쓰레드 사용했는지, 컨트롤러와, 내가 log.info로 쓴 메시지가 출력된다.

log.info에서 {}는 변수로 치환하나 보다.

 

@RestController는 원래 다른 컨트롤러에노테이션의 경우 뷰 이름을 반환토록 해야 하지만, 

저렇게 하면 return 그대로를 메시지바디에 써준다.

그래서 저거 하고 응답받은거 메시지 바디 보면 그냥 딱 ok만 써있다.

rest api 만들 때 저거 쓴다. http api 할때 이거 씀

 

 

 

@RestController
public class LogTestController {
    private final Logger log = (Logger)LoggerFactory.getLogger(LogTestController.class);

    @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 "ok";
    }
}

저건 로그의 레벨들이다. 갈수록 심각한 수준임.

 

 

출력해보면

2023-08-11T22:53:52.869+09:00  INFO 4140 --- [nio-8080-exec-1] h.springmvc.basic.LogTestController      : info log=Spring
2023-08-11T22:53:52.870+09:00  WARN 4140 --- [nio-8080-exec-1] h.springmvc.basic.LogTestController      : warn log=Spring
2023-08-11T22:53:52.870+09:00 ERROR 4140 --- [nio-8080-exec-1] h.springmvc.basic.LogTestController      : error log=Spring

이렇게 나온다. 이렇게 나눠두면, 뭐 하나 따로 모아서 볼 수 있다.

trace, debug 레벨은 안보이는데, 

application.properties에 

logging.level.hello.springmvc=info

이렇게 해두면 (로깅 레벨 어디부터)

info부터만 보겠다는 뜻.

trace는 다 보겠다는 뜻.

 

 

개발서버에서는 debug로 보고

로컬pc에서는 debug나 trace로 보고

운영서버에서는 보통 info로 함.

 

그렇게 바꿔서 배포

 

기본값은 info임

logging.level.root=info 임

저걸 한단계만 낮춰도 너무 많이 출력됨. 

 

 

 

@Slf4j
@RestController
public class LogTestController {

    @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 "ok";
    }
}

@Slf4j

이 에노테이션 쓰면 그냥 log로 사용할 수 있음..

 

 

주의점

log.trace("trace log="+ name);

이렇게 플러스로 쓰면 안됨.

왜냐하면, 저렇게 하면 원래 연산부터 하기 때문에 내가 trace 저거 debug 레벨에 있으면 쓰지도 않는데 연산이 발생하게 됨.

 

근데,

log.trace("trace log={}", name); 이거는 그냥 인자들을 넘기는 거임. 그래서 일단 trace가 출력허용되는 레벨인지 trace 안에서 확인함.

옛날에는 진짜

if(log.isTraceEnabled()){
    log.trace("trace log="+ name);
}

이렇게 썼음.

 

 

클래스 이름, 쓰레드 정보 등의 부가 정보.

 

그리고 파일로 남기거나, 아예 네트워크로 전송도 가능하다.

 

파일 저장도 파일 일정용량 넘으면 분할, 분할도 최대 10개까지만 유지해(그럼 오래된 로그들은 삭제되겠지?), 백업해, 

 

그리고 성능도 sout 보다 좋음. 성능 굉장히 좋음.

 

스프링부트로 로그 설정도 가능함.

 

 

 

'스프링 > 3. 스프링 MVC' 카테고리의 다른 글

40. 요청 종류에 따른 api 구현  (0) 2023.08.12
39. 요청매핑  (0) 2023.08.11
37. 스프링MVC 시작  (0) 2023.08.11
36. 실용적인 형식  (0) 2023.08.11
35. 통합  (0) 2023.08.10