티스토리 뷰

728x90

0. 스프링에서 로거를 사용하기 위해서 Sl4j를 사용한다.

 

1. Sl4j는 Log4j와 Logback을 Wrapping하여 간단한 사용환경을 제공한다.

  1-1 로깅 단계는 Error, Warn, Info, Debug, Trace로 구분된다.

  1-2 하위의 단계는 상위의 단계의 로그를 포함하여 출력한다.

  1-3 레벨의 세팅은 LOGGER.setLevel(INFO); 이런 형식으로 지정할 수 있다.

 

2. Spring Starter 모듈에는 기본적으로 log4j와 logback이 포함되어 별도의 dependecy추가는 필요없다.

  2-1 기본 구현 라이브러리가 Logback이고 원하면 Log4j로 교체할 수 있다.

  2-2 Log4j를 위해서는 추가 dependency설정이 필요하다.

 

3. 사용방법은

  3-1 로거를 static final로 정의하고 클래스를 지정한다.

  3-2 로깅하는 데이터를 5가지 로깅 레벨 중 원하는 레벨에 맞추어 설정한다.

 

package pe.pilseong.flightreservation.controllers;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

import pe.pilseong.flightreservation.entities.Flight;
import pe.pilseong.flightreservation.repositories.FlightRepository;

@Controller
public class FlightController {

  @Autowired
  FlightRepository flightRepository;
  
  private static final Logger LOGGER = LoggerFactory.getLogger(FlightController.class);
  
  @PostMapping("/findFlights")
  public String findFlights(
      @RequestParam String from, 
      @RequestParam String to, 
      @RequestParam("departureDate") @DateTimeFormat(pattern = "MM-dd-yyyy") Date departureDate,
      Model model) {
    
    LOGGER.info("Inside findFlights() from:: " + from + 
      ", to:: " + to + ", departureDate:: " + departureDate.toString());
    
    List<Flight> flights = this.flightRepository.findFlights(from, to, departureDate);
    model.addAttribute("flights", flights);
    
    LOGGER.info("Inside findFlights() fligts are " + flights.toString());
    
    return "displayFlights";
  }
}

 

4. 루트 로거의 레벨을 지정하는 방법은 application.properties에 지정하면 된다.

  4-1 기본 레벨은 Info로 설정되어 있다.

  4-2 레벨 변경은 아래처럼 원하는 레벨을 설정한다.

 

logging.level.root=ERROR

 

5. 간단하게 로거를 사용하기를 원하면 lombok의 @Slf4j를 사용할 수 있다.

  5-1 아래코드를 보면 클래스에 @Slf4j가 지정되어 있는데, 이것은 자동으로 logger 설정을 해준다.

    5-1-1 바로 아래 붙인 LOGGER를 생성해 주는 구문과 동일하다. 변수이름만 log로 다를 뿐이다.

 

  private static final Logger LOGGER = LoggerFactory.getLogger(FlightController.class);

 

  5-2 메소드를 보면 log.info 같은 형식으로 출력이 가능한 것을 볼 수 있다. 아주 편리하다.

 

package pe.pilseong.employees.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import lombok.extern.slf4j.Slf4j;
import pe.pilseong.employees.model.Employee;
import pe.pilseong.employees.serivce.EmployeeService;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

@Slf4j
@RestController
@RequestMapping("/employees")
public class EmployeeController {
  
  @Autowired
  private EmployeeService employeeService;

  @PostMapping
  public Mono<ResponseEntity<Employee>> createEmployee(@RequestBody Employee employee) {
    return this.employeeService.save(employee)
    .map(savedEmployee-> new ResponseEntity<>(savedEmployee, HttpStatus.CREATED))
    .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
  }

  @GetMapping
  public Flux<Employee> findAll() {
    log.info("findAll in EmployeeController");

    return this.employeeService.findAll();
  }

  @GetMapping("/{id}")
  public Mono<ResponseEntity<Employee>> findOne(@PathVariable String id) {
    log.info("find one in EmployeeController id :: " + id);
    return this.employeeService.findOne(id)
      .map(fetchedEmployee-> new ResponseEntity<>(fetchedEmployee, HttpStatus.OK))
      .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
      
  }

  @PutMapping("/{id}")
  public Mono<ResponseEntity<Employee>> update(@PathVariable String id, @RequestBody Employee employee) {
    return this.employeeService.update(id, employee)
    .map(savedEmployee-> new ResponseEntity<>(savedEmployee, HttpStatus.CREATED))
    .defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
  }

  @DeleteMapping("/{id}")
  public Mono<Void> delete(@PathVariable String id) {
    return this.employeeService.delete(id);
  }
}
728x90
댓글