스프링에서 가장 많이 사용되는 로그 관련 라이브러리는 slf4j와 logback이라 볼 수 있다.
slf4j는 인터페이스이고, 이를 구현한 구현체 중 가장 많이 사용되는 라이브러리는 logback이다. slf4j는 spring-boot라이브러리 안에 포함되어 있기 때문에, import만 해주고 아래와 같이 선언하여 바로 사용이 가능하다.
private final Logger logger = LoggerFactory.getLogger(getClass());
서버개발자 입장에서 log가 가장 필요한 순간은 어떤 순간일까? 아마도 에러가 발생했을때, client에서 어떤 값으로 어떻게 요청했는지에 대해서 궁금할때 일 것이다. get요청과 post요청시 try catch를 통해 예외처리하고, 예외시에 사용자의 요청값을 logger를 통해 출력하는 간단한 방법을 적어보겠다.
먼저, post요청이 객체형태로 들어올때 객체를 json 문자열 형태로 변환해서 log로 출력해보자.
post요청
먼저, 아래 예제는 게시판에 글을 create하는 간단한 컨트롤러이다. controller에서 객체를 조립해서 service를 통해 db에 save하는 코드이다. try catch에서 catch문을 위주로 봐보자.
@Controller
public class PostController {
// json으로 변환을 위해 mapper를 주입
@Autowired
private ObjectMapper mapper;
@Autowired
private final PostService postService;
@PostMapping("/posts/api/new")
@ResponseBody
public void createApi(@RequestBody PostForm postForm) throws JsonProcessingException {
try{
Post post = new Post();
post.setTitle(postForm.getTitle());
post.setContents(postForm.getContents());
post.setEmail(postForm.getEmail());
post.setCreateDate(LocalDateTime.now());
postService.create(post);
}catch (Exception e){
//입력받은 DTO객체를 mapper를 이용해 String으로 변환
String tempText = mapper.writeValueAsString(postForm);
//변환된 String 출력
logger.info("PostController createApi");
logger.info("Error request : {}", tempText);
e.printStackTrace();
}
}
}
catch인 경우가 아닌 모든 경우에 log를 찍게 되면, 실제 운영환경에서는 문제가 발생할 것이다. 그래서 에러의 경우에만 사용자의 입력값을 출력해보고자 한다.
먼저 위 코드에서는 @RequestBody를 통해 request데이터에서 손쉽게 DTO 객체로 변환하고 있음을 알 수가 있다. 그런데, 객체를 그대로 출력시에는 객체의 주소가 출력될것이다. 이를 mapper를 통해 String으로 변환하여 출력하면 된다.
물론 아래와 같은 방식으로도 출력은 가능하다. 다만 객체에 담긴값을 꺼내는 방식이므로 데이터가 정제가 되어 온전한 사용자의 request가 아니라는 문제가 있고, 코드가 다소 지저분해진다는 문제가 있을 수 있겠다.
logger.error("info request postForm = {}, {}, {}", postForm.getTitle(),post.getContents(), post.getEmail());
get요청
@GetMapping("posts/api/findById")
@ResponseBody
public Post findByIdApi(@RequestParam(value="id")Long id) throws Exception {
try{
Post post = postService.findById(id).orElse(null);
return post;
}catch (Exception e){
logger.info("posts/api/findById");
logger.info("Error request : {}", id);
e.printStackTrace();
}
return null;
}
get요청의 경우 현재 long타입의 id를 parama으로 받고 있는데, 만약 문자 형태를 request던진다면 예외가 발생할 것이고, 해당 요청이 무엇인지 아래와 같은 형식으로 출력이 가능할 것이다.

get요청은 간단하니 추가적인 설명은 생략하도록 하겠다.
'프로그래밍 > java, spring' 카테고리의 다른 글
spring 예외처리 정리(exception기본, 중첩된 예외, 멀티서버간 예외처리) (0) | 2023.01.11 |
---|---|
Spring JWT 토큰 서버 구현(+ ajax 프론트테스트) (0) | 2023.01.08 |
junit repository test - 서비스용DB mysql과 테스트DB h2사용 (0) | 2023.01.01 |
Spring Scheduler, Batch연동 (0) | 2022.12.31 |
Spring Scheduler - 게시판 예약 글쓰기 (0) | 2022.12.31 |