관리 메뉴

거니의 velog

(4) 메이븐과 스프링 STS 사용법 4 본문

Java_Spring Framework part2

(4) 메이븐과 스프링 STS 사용법 4

Unlimited00 2023. 11. 14. 20:52

8. log4j란?

* 지금까지의 실습이 정상적으로 실행되었는지 확인하기 위해 그동안 자바의 println() 메서드를 이용해 데이터를 콘솔로 출력해서 살펴보았다.

* 그런데 개발이 끝나고 실제 서비스를 한 후로는 더 이상 메시지를 출력하는 구문을 필요가 없어진다. 따라서 주석 처리를 하거나 삭제해야 한다. 하지만 유지관리를 하다 보면 필요한 경우 다시 콘솔에 메시지를 출력해야 하는 경우가 발생하기도 한다. 그러면 번거롭다. 게다가 애플리케이션의 코드 양이 많아지면 이렇게 관리하기는 어렵다.

* 실제 애플리케이션에서는 유지관리를 위해 웹 사이트에 접속한 사용자 정보나 각 클래스의 메서드 호출 시각 등 여러 가지 정보를 파일로 저장해서 관리한다. 이런 로그 관련 기능을 제공하는 것이 log4j이다. log4j 기능은 독립적으로 라이브러리를 설치해서 사용할 수 있으며, 메이븐 같은 빌드 툴에서는 프로젝트 생성 시 자동으로 log4j 라이브러리가 설치된다.

* log4j 기능 관련 설정은 log4j.xml 파일에서 수행한다.

* 그럼 log4j 의 사용법에 대해 간단히 알아보자.

* log4j.xml을 이루는 태그들의 특징은 아래 표와 같다.

< log4j.xml을 이루는 태그 >

태그 설명
<Appender> 로그의 출력 위치를 결정(파일, 콘솔, DB 등)한다. log4j API 문서의 XXXAppender로 끝나는 클래스들의 이름을 보면 출력 위치를 알 수 있다.
<Layout> Appender가 어디에 출력할 것인지 결정했다면 어떤 형식으로 출력할 지 출력 레이아웃을 결정한다.
<Logger> 로깅 메시지를 Appender에 전달한다. 개발자가 로그 레벨을 이용해 로그 출력 여부를 조정할 수 있다. logger는 로그 레벨을 가지고 있으며, 로그 출력 여부는 로그문의 레벨과 로거의 레벨을 가지고 결정한다.

* <Appender> 태그를 이용해 로그를 콘솔로 출력할지 파일로 출력할지와 출력 위치를 설정한다. 그리고 <Layout> 태그로 출력 시 어떤 형식으로 출력할지를 설정한다. <Logger> 태그에서 로그 레벨을 설정해 선택적으로 로그를 출력할 수 있다.

* 다음의 표는 출력 위치를 지정할 수 있는 여러 가지 Appender 클래스들이다.

< 여러 가지 Appender 클래스 >

Appender 클래스 설명
ConsoleAppender org.apache.log4j.ConsoleAppender 클래스로, 콘솔에 로그 메시지를 출력한다.
FileAppender org.apache.log4j.FileAppender 클래스로, 파일에 로그 메시지를 출력한다.
RollingFileAppender org.apache.log4j.RollingFileAppender 클래스로, 파일 크기가 일정 기준을 넘으면 기존 파일을 백업 파일로 바꾸고 처음부터 다시 기록한다.
DailyRollingAppender org.apache.log4j.DailyRollingAppender 클래스로, 설정한 기간 단위로 새 파일을 만들어 로그 메시지를 출력한다.

* 다음 표는 일반적으로 많이 사용되는 PatternLayout 클래스의 출력 형식을 지정하는 속성들이다.

< PatternLayout 클래스에서 사용되는 여러 가지 출력 속성들 >

속성 설명
%p debug, info, error, fatal 등 로그 레벨 이름 출력
%m 로그 메시지 출력
%d 로깅 이벤트 발생 시각 출력
%F 로깅이 발생한 프로그램 파일 이름 출력
%l 로깅이 발생한 caller의 정보 출력
%L 로깅이 발생한 caller의 라인 수 출력
%M 로깅이 발생한 method 이름 출력
%c 로깅이 메시지 앞에 전체 패키지 이름이나 전체 파일 이름 출력
... ...

* log4j의 레벨은 다음 표와 같이 총 6단계로 나누어진다.

< log4j의 여러 가지 로그 레벨들 >

레벨 설명
FATAL 시스템 차원에서 심각한 문제가 발생해 애플리케이션 작동이 불가능할 경우에 해당하는 레벨이다. 일반적으로 애플리케이션에서는 사용할 일이 없다.
ERROR 실행 중 문제가 발생한 상태를 나타낸다.
WARN 향후 시스템 오류의 원인이 될 수 있는 경고 메시지를 나타낸다.
INFO 로그인, 상태 변경과 같은 실제 애플리케이션 운영과 관련된 정보 메시지를 나타낸다.
DEBUG 개발 시 디버깅 용도로 사용한 메시지를 나타낸다.
TRACE DEBUG 레벨보다 상새한 로깅 정보를 출력하기 위해 도입된 레벨이다.

* 낮은 레벨로 코드의 메시지를 설정했다면 그 레벨보다 높게 설정한 메시지들은 모두 출력된다. 예를 들어 log4j.xml에서 DEBUG로 애플리케이션 레벨을 설정했다면 실제 코드에서 그 이상의 레벨로 설정된 메시지들은 모두 출력된다. 더 자세한 내용은 log4j 홈페이지를 참고하기 바란다.

https://logging.apache.org/log4j/1.2/manual.html

 

Apache log4j 1.2 - Short introduction to log4j

<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apa

logging.apache.org


(1) log4j.xml 이용해 로그 메시지 출력하기

* 그럼 회원 조회 시 log4j.xml을 이용해 응답할 JSP 이름을 출력해 보자.

1. 다음과 같이 log4j.xml을 작성한다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

	<!-- Console Appenders -->
	<!-- ConsoleAppender를 이용해서 로그 메시지를 콘솔로 출력한다. -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p: %c - %m%n" /> <!-- PatternLayout의 출력 형식을 지정한다. -->
		</layout>
	</appender>
	
	<!-- DailyFile Appenders -->
	<!-- DailyRollingFileAppender를 이용해서 로그 메시지를 파일로 출력한다. -->
	<appender name="dailyFileAppender" class="org.apache.log4j.DailyRollingFileAppender">
		<param name="File" value="C:\\spring\\logs\\output.log" /> <!-- 로그 파일 생성 위치를 설정한다. -->
		<param name="Append" value="true" />
		<layout class="org.apache.log4j.PatternLayout">
		  <param name="DatePattern"   value="'.'yyyy-MM-dd"/>
			<param name="ConversionPattern" value="[%d{HH:mm:ss}][%-5p](%F:%L)-%m%n"/> <!-- PatternLayout의 출력 형식을 지정한다. -->
		</layout>
	</appender>
	
	<!-- Application Loggers -->
	<!-- logger 태그로 com.myspring.pro27 패키지에 존재하는 클래스들의 로그 레벨을 info로 설정한다. -->
	<logger name="com.myspring.pro27">
		<level value="info" />
	</logger>
	
	<!-- 3rdparty Loggers -->
	<logger name="org.springframework.core">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.beans">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.context">
		<level value="info" />
	</logger>

	<logger name="org.springframework.web">
		<level value="info" />
	</logger>

	<!-- Root Logger -->
	<root>
		<priority value="debug" />
		<appender-ref ref="console" /> <!-- 애플리케이션 전체 로그를 콘솔로 출력한다. -->
		<appender-ref ref="dailyFileAppender" /> <!-- 애플리케이션 전체 로그를 파일로 출력한다. -->
	</root>
	
</log4j:configuration>

2. MemberControllerImpl 클래스를 다음과 같이 작성한다.

@Controller("memberController")
public class MemberControllerImpl   implements MemberController {
	
	// LoggerFactory 클래스를 이용해 Logger 클래스 객체를 가져온다.
	private static final Logger logger = LoggerFactory.getLogger(MemberControllerImpl.class);
	
	...
	
	@Override
	@RequestMapping(value="/member/listMembers.do" ,method = RequestMethod.GET)
	public ModelAndView listMembers(HttpServletRequest request, HttpServletResponse response) throws Exception {
		String viewName = getViewName(request);
		logger.info("viewName: "+ viewName); // Logger 클래스의 info() 메서드로 로그 메시지 레벨을 info로 설정한다.
		logger.debug("viewName: "+ viewName); // Logger 클래스의 debug() 메서드로 로그 메시지 레벨을 debug로 설정한다.
		List membersList = memberService.listMembers();
		ModelAndView mav = new ModelAndView(viewName);
		mav.addObject("membersList", membersList);
		return mav;
	}
    
    ...

* 다음은 브라우저에서 회원 목록을 요청하여 콘솔로 출력된 메시지이다. log4j.xml에서 로그 레벨을 info로 설정했기 때문에 debug() 메서드로 설정한 메시지는 레벨이 낮아 출력되지 않는다.

* log4j.xml의 로그 레벨을 debug로 변경한 후 브라우저에서 요청하면 이번에는 debug 레벨 메시지와 상위 info 레벨 메시지가 모두 출력된다.

* 소스 코드에서 메서드를 이용해 로그를 설정하면 log4j.xml에서 설정한 로그 레벨보다 높게 설정한 로그 메시지들이 출력되는 것을 알 수 있다. 그리고 C:\spring\logs 폴더에는 날짜별로 output.log 파일이 생성된다.


(2) 마이바티스 SQL문을 로그로 출력하기

* 지금까지는 매퍼 파일에 작성한 SQL문을 실행할 경우 로그를 출력할 수 없었다. 그러나 log4j.xml을 이용하면 개발 시 SQL문과 관련된 정보를 로그로 출력함으로써 정상적으로 실행되는지 확인할 수 있다.

* log4j.xml을 다음과 같이 작성한다. <root> 태그는 애플리케이션 전체에 적용되는 로그 레벨을 설정한다. <root> 태그의 하위 <priority> 태그의 value 속성 값을 debug로 변경한 후 다시 회원 조회를 요청하면 실행되는 SQL문 관련 정보를 로그로 출력할 수 있다.

	<!-- Root Logger -->
	<root>
		<priority value="debug" />
		<appender-ref ref="console" /> <!-- 애플리케이션 전체 로그를 콘솔로 출력한다. -->
		<appender-ref ref="dailyFileAppender" /> <!-- 애플리케이션 전체 로그를 파일로 출력한다. -->
	</root>
	
</log4j:configuration>

마이바티스로 실행하는 SQL문 관련 정보를 로그로 출력

* 그리고 Service와 DAO 클래스의 메서드 호출 시 스프링 AOP를 이용해서 로그를 출력하는 기능은 추후 실습해 보시기 바란다.