본문 바로가기

SPRING

김영한 - 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 5일차

로깅 간단히 알아보기

 

운영 시스템에서 System.out.println() 같은 시스템 콘솔을 사용해서 필요한 정보를 출력하지 않고, 별도의 로깅 라이브러리를 사용해서 로그를 출력한다.

 

로깅 라이브러리

 

스프링 부트 라이브러리를 사용하면 스프링 부트 로깅 라이브러리(spring-boot-starter-logging)가 함께 포함된다.

스프링 부트 라이브러리는 기본으로 다음 로깅 라이브러리를 사용한다.

 

SLF4J

LogBack

 

로그라이브러리는 LogBack , Log4J , Log4J2 등등 수 많은 라이브러리가 있는데 그것을 통해서 인터페이스로 제공하는 것이 SLF4J 라이브러리다.

 

로그선언

 

1.

2. @Slf4j : 롬복 사용 가능

 

@RestController 

 

@Controller 는 반환 값이 String이면 뷰 이름으로 인식된다. 그래서 뷰를 찾고 뷰가 렌더링 된다.

@RestController는 반환 값으로 뷰를 찾는 것이 아니라, HTTP 메시지 바디에 바로 입력한다.

 

테스트

 

로그레벨 설정

LEVEL : TRACE > DEBUG > INFO > WARN > ERROR

보통 개발서버는 debug 출력

운영서버는 info 출력

 

로그 레벨 설정

 

application.properties

로그 사용법

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

로그 출력 레벨을 info로 설정해도 해당 코드에 있는 "trace log="+name 가 실제 실행이 되어 버린다.

결과적으로 문자 더하기 연산이 발생한다.

log.trace("trace log={}", name);

로그 출력 레벨을 info로 설정하면 아무일도 발생하지 않는다. 앞과 같은 의미없는 연산이 일어나지 않는다.

 

로그 사용시 장점

 

쓰레드 정보, 클래스 이름 같은 부가 정보를 함께 볼 수 있고, 출력 모양을 조정할 수 있다.

로그 레벨에 따라 개발 서버에서는 모든 로그를 출력하고, 운영 서버에서는 출력하지 않는 등 상황에 맞게 조절 가능

시스템 아웃 콘솔에만 출력하는게 아니라 , 파일이나 네트워크 등 로그를 별도의 위치에 남길 수 있다.

성능이 일반 System.out보다 좋다. 

 

요청 매핑

 

 

@RequestMapping(value = {"/hello-basic", "hello-go"})
public String helloBasic() {
    log.info("helloBasic");
    return "ok";
}

@RequestMapping에 다중 설정이 가능하다.

 

@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
public String mappingGetV1() {
    log.info("mapping-get-v1");
    return "ok";
}

 

@RequestMapping에 method 속성으로 HTTP 메소드를 지정할 수 있다.

 

/**
 * 편리한 축약 애노테이션 (코드보기)
 *
 * @GetMapping
 * @PostMapping
 * @PutMapping
 * @DeleteMapping
 * @PatchMapping
 */
@GetMapping(value = "/mapping-get-v2")
public String mappingGetV2() {
    log.info("mapping-get-v2");
    return "ok";
}

 

HTTP 메소드를 축약한 애노테이션을 사용하는 것이 더 직관적이다.

 

/**
 * PathVariable 사용
 * 변수명이 같으면 생략 가능
 *
 * @PathVariable("userId") String userId -> @PathVariable userId
 */
@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {
    log.info("mappingPath userId={}", data);
    return "ok";
}

 

@RequestMapping은 URL 경로를 템플릿화 할 수 있는데, @PathVariable을 사용하면 매칭 되는 부분을 편리하게 조회 할 수있다.

@PathVariable의 이름과 파라미터 이름이 같으면 생략할 수 있다.

 

/**
 * PathVariable 사용 다중
 */
@GetMapping("/mapping/{userId}/orders/{orderId}")
public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) {
    log.info("mappingPath userId={} , orderId={} ", userId, orderId);
    return "ok";
}

 

@PathVariable을 다중으로 사용할 수 있다.

 

/**
 * 파라미터로 추가 매핑
 * params="mode",
 * params="!mode"
 * params="mode=debug"
 * params="mode!=debug" (! = )
 * params = {"mode=debug","data=good"}
 */
@GetMapping(value = "/mapping-param", params = "mode=debug")
public String mappingParam() {
    log.info("mappingParam");
    return "ok";
}

 

특정 파라미터 조건으로 매핑할 수 있다.

 

/**
 * 특정 헤더로 추가 매핑
 * headers="mode",
 * headers="!mode"
 * headers="mode=debug"
 * headers="mode!=debug" (! = )
 */
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
    log.info("mappingHeader");
    return "ok";
}

 

파라미터 매핑과 비슷하지만 HTTP 헤더를 사용한다.

 

/**
 * Content-Type 헤더 기반 추가 매핑 Media Type
 * consumes="application/json"
 * consumes="!application/json"
 * consumes="application/*"
 * consumes="*\/*"
 * MediaType.APPLICATION_JSON_VALUE
 */
@PostMapping(value = "/mapping-consume", consumes = MediaType.APPLICATION_JSON_VALUE)
public String mappingConsumes() {
    log.info("mappingConsumes");
    return "ok";
}

 

HTTP 요청의 Content-Type 헤더를 기반으로 미디어 타입으로 매핑한다.

만약 맞지 않으면 HTTP 415 상태코드을 반환한다.

 

/**
 * Accept 헤더 기반 Media Type
 * produces = "text/html"
 * produces = "!text/html"
 * produces = "text/*"
 * produces = "*\/*"
 */
@PostMapping(value = "/mapping-produce", produces = MediaType.TEXT_HTML_VALUE)
public String mappingProduces() {
    log.info("mappingProduces");
    return "ok";
}

 

HTTP 요청의 Accept 헤더를 기반으로 미디어 타입으로 매핑한다.

만약 맞지 않으면 HTTP 406 상태코드을 반환한다.

 

출처

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1