TOMCAT7 에 LOG4J2 셋팅
프레임워크는 없이 모델1 방식으로 만들어진 프로젝트에 log4j2 를 셋팅할 일이 생겼다.
Tomcat는 jdk1.7 에 servlet 3.0 환경이었다.
Log4j2 사이트 : http://logging.apache.org/log4j/2.x/manual/layouts.html#LocationInformation
일단 해당 사이트에서 다운로드
다운로드 하면 엄청나게 많은 jar들이 있다.
이중 core 와 api와 web를 사용하였다.
(web은 web.xml 에 설정 시 필요하였다.)
log4j-api-2.1.jar
log4j-core-2.1.jar
log4j-web-2.1.jar
해당 파일들은 tomcat의 web-inf 밑의 lib폴더에 복사
Servlet3.0 일 경우 자동인식이 된다고 한다.
근데 영어가 약해서..-_-; 정확히는 모르겠다.
일단 자동인식은 배제하고 2.5 기준의 셋팅을 잡았다.
(해당 프로젝트가 3.0 을 쓰지만 실수로 3.0으로 한 듯 하다…)
Web.xml
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="true">
<description>
TEST
</description>
<display-name>TEST</display-name>
<!-- isLog4jAutoInitializationDisabled 가 true 이면 log4jContextName 혹은 display-name 을 설정해야 한다고 한다. -->
<!-- 역활은 몬지 모르겠음. -->
<context-param>
<param-name>log4jContextName</param-name>
<param-value>TEST</param-value>
</context-param>
<!-- log4j2 자동 시작 방지
현재 이 web.xml 은 servlet3.0 기준이다.
하지만 아래의 log4j2 는 2.5기준으로 동작하게 하기 위해
isLog4jAutoInitializationDisabled 항목을 true 로 추가하였음
3.0 기준으로 돌아가게 하려면 아래 항목을 삭제 바람
-->
<context-param>
<param-name>isLog4jAutoInitializationDisabled</param-name>
<param-value>true</param-value>
</context-param>
<!-- 기본으로는 /WEB-INF 아래의 log4j2.xml을 읽어들인다.
이를 별도로 변경하고 싶을경우 log4jConfiguration 항목을 생성한다.
TOMCAT 의 경우 기본적으로 루트인 WebContent 를 기준으로 본다.
접근방법 예
file:///etc/myApp/myLogging.xml
classpath:
등이 있을 것 같음
-->
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>/WEB-INF/config/log4j2.xml</param-value>
</context-param>
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
/WEB-INF/config 밑에 Log4j2.xml 추가
실제적으론 WEB-INF 밑에 log4j2.xml 이름으로 파일을 넣어두면 자동으로 읽는 듯 하다.
이름이 바뀌어도 되는지는 확인 못함
src 밑에 넣어두어도 설정을 자동으로 읽어낼 것 같지만 테스트는 안해봄
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<properties>
<property name="log-path">c:\\logs</property>
</properties>
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36}::%M - %msg%n" />
</Console>
<File name="simple_file" fileName="${log-path}/sample.log" append="true">
<PatternLayout pattern="%d %5p [%c::%M] %m%n"/>
</File>
<RollingFile name="file" fileName="${log-path}/test.log" filePattern="${log-path}/test_%d{yyyy-MM-dd}.log" append="true">
<PatternLayout pattern="%d %5p [%c::%M] %m%n"/>
<Policies>
<!-- interval(default 1)이므로 1초 간격으로 rolling 수행
intervar속성 추가
-->
<TimeBasedTriggeringPolicy interval="24" />
<!-- 사이즈 제한을 하고 싶을 경우 아래 속성 추가
-->
<!-- <SizeBasedTriggeringPolicy size="250 MB"/> -->
</Policies>
</RollingFile>
</appenders>
<Loggers>
<!-- logger의 name에는 class 속성이 들어간다.
문제는 현재 프로젝트는 src밑에 개별로 package를 쪼개놔서 이를 설정하기가 애매해보인다.
그냥 각각 logger 설정-_-;
additivity => 로그 중복여부, ROOT와 중복될 경우 한곳에서만 출력
-->
<Logger name="test" level="DEBUG" additivity="false">
<AppenderRef ref="Console" />
<AppenderRef ref="file" />
</Logger>
<!-- console 에 출력하는건 ROOT를 사용하게 함 -->
<Root level="DEBUG">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</configuration>
Package 를 src밑에 트리구조가 아니게 잡아놓은지라 설정하는데 그지같았음
logger설정에서 logger를 test 로 잡을 경우 package가 test로 시작하는 녀석은 해당 logger를 가지고 사용하게 된다.
이제 사용은 일반적으로 사용하는
private final Logger logger = LogManager.getLogger(this.getClass());
를 이용하여 사용
SLF4J 랑 연동시에는 logger를 가져오는 부분이 달랐던 것 같았는데 log4만 이용할 경우에는 그냥 사용하면 될 듯 함
- exception로그 남길 때 방법 2가지
logger.error(e, e); //e : exception 객체
logger.catch(e);
둘다 e.printStackTrace() 를 로그에 출력하게 된다.
- 로그 Pattern 에서 메서드를 출력하고 싶을 경우
%M or %method 를 사용함
아는 상식선에서는 따로 commons-logging 파일을 넣지 않았으므로 java.util.logging 쪽 클래스들을 사용하지 않을 까 싶음
설정 참고 URL