스프링프레임워크 log4j2 설정 : Spring Framework + log4j 2 + slf4j + jboss/wildfly(ver 9)
* jdk : 1.7
* framework : spring
* was : jboss/wildfly 9
#기본개념
slf4j 는 interface,
log4j 는 구현체
slf4j 사용시 소스에서 interface , imple 사용하듯 구현체만 바꾸면 돼서
log4j 를 나중에 걷어내고 다른 log lib을 사용해도 소스레벨에서 수정할게 없음. 그래서 slf4j 사용.
log4j 2는 log4j 1랑 다른거 없이 log4j 2.x 대 버전을 의미.
(log4j 1.x 는 log4j 라고부르고 log4j 2 는 log4j 2.x 를 말하는 듯)
* log4j2 사용시 slf4j는 1.7.x 이상 사용
참고 : https://goddaehee.tistory.com/45
(위 고수님의 블로그에 log4j, slf4j, logback 에 관한 내용이 상세히 기술되어 있음)
[ # log4j 2 및 slf4j maven dependency 설정 ]
log4j-slf4j-impl jar(actifactId) 사용시 1.7.x 이하 version 사용
log4j-slf4j18-impl jar(actifactId) 사용시 1.8.x 이상 version 사용
참고 : https://logging.apache.org/log4j/2.x/log4j-slf4j-impl/index.html
[ pom.xml ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<modelVersion>4.0.0</modelVersion>
<groupId>com.sample</groupId>
<name>SAMPLE</name>
<packaging>war</packaging>
<version>0.1</version>
<properties>
<!-- 생략 -->
<org.slf4j-version>1.7.5</org.slf4j-version>
<org.log4j-version>2.9.0</org.log4j-version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of slf4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${org.log4j-version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${org.log4j-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of log4j-core -->
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
|
cs |
* spring 의 경우 default 로 jcl(commons-logging)사용하므로 이를 slf4j 로 대체하기 위해 jcl-over-slf4j 사용
* jcl(commons-logging) 대신 slf4j 를 사용하므로 spring-context 에서 commons-logging 제거(exclude)
* jcl-over-slf4j 내부적으로 slf4j-api dependency 를 포함하고 있으므로 slf4j-api 는 별도의 dependency 로 추가 하지 않음
* log4j-core 내에 log4j-api dependency 포함하므로 log4j-slf4j-impl 에서 해당 의존성 제거
[ #log4j2.xml 설정 ]
src/main/resources/ 경로에 생성(/WEB-INF/classes/).
해당 위치에 파일을 위치시킬 경우 log4j 가 초기화 될 때 알아서 해당 파일을 읽어들임
* src/main/resource/ 밑이 아닌 기타 경로에 해당 파일을 위치시킬 경우
web.xml 에 아래와 같이 추가
참고 : https://okky.kr/article/282263
[ web.xml ]
1
2
3
4
5
6
7
8
9
|
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:~~~/log4j2.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
|
cs |
[ log4j2.xml ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="console_root" target="SYSTEM_OUT">
<PatternLayout pattern="%d %5p %m%n" />
</Console>
<Console name="console_com" target="SYSTEM_OUT">
<PatternLayout pattern="%d %5p [%c] %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="java.sql" level="INFO" additivity="false">
<AppenderRef ref="console_com" />
</Logger>
<Logger name="jdbc.sqltiming" level="INFO" additivity="false">
<AppenderRef ref="console_com" />
</Logger>
<Logger name="egovframework" level="INFO" additivity="false">
<AppenderRef ref="console_com" />
</Logger>
<Logger name="com" level="INFO" additivity="false">
<AppenderRef ref="console_com" />
</Logger>
<Logger name="org.springframework" level="INFO" additivity="false">
<AppenderRef ref="console_com" />
</Logger>
<Root level="INFO">
<AppenderRef ref="console_root" />
</Root>
</Loggers>
</Configuration>
|
cs |
[* 어펜더 (Appender) ]
어펜더는 로그이벤트를 목적지에 전달하는 역할을 한다.(타겟 목적지에 이벤트 데이터를 쓰는 역할)
어펜더는 Appender interface 를 구현한다.
name 속성을 가지며 이를 통해 로거에서 참조한다.
아래와 같은 어펜더가 존재.
ConsoleAppender : Sysout 을 찍는 용도로 사용되는 어펜더
FileAppender : 로그를 파일로 저장할 용도로 사용되는 어펜더
RollingFileAppender : FileAppender 에 Rollover 기능(파일 백업)을 추가한 어펜더
[* 로거 (Logger) ]
로거의 위계구조(hierarchy)에 대한 이해가 필요하다. 여기를 읽어보길 바란다.
아래는 로거 위계구조의 예이다.
com.sample.sampleController 클래스 내에서
protected Logger logger = LoggerFactory.getLogger(this.getClass());
logger.info("샘플로깅!");
과 같이 로그를 출력할 경우,
this.getClass() 는 com.sample.sampleController를 반환하고,
해당 클래스는 com 패키지 하위의 클래스(com.*) 이므로 "com"이란 이름(name)으로 명명된 logger설정을 따른다.
* 만약 23~25line 의 "com" logger 를 제거한다면 com 패키지 하위 소스내(com.sample.sampleController)에서 찍은 로그는 Root 로거의 console_root 어펜더에 의해 출력된다. ("com" logger 있을 경우 : console_com(%d %5p [%c] %m%n) appender 에 의해 출력, 없을 경우 root logger인 console_root(%d %5p %m%n) 에 의해 출력
* 이와 같은 위계구조를 활용하여 라이브러리 내부에서 불필요 혹은 원치않는 로그를 출력하고 있는 경우, 해당 라이브러리 패키지 경로를 별도의 logger 로 잡아 로그 출력을 제거 할 수 있다.
* Root 로거는 매핑되는 logger 를 찾지 못하는 경우 가장 마지막에 사용되는 최상위 로거이며, Root 로거는 반드시 설정해주어야 한다.
[* 패턴 (PatternLayout) ]
%d 날짜 년월일시
%c : 클래스명
%5p : 로그레벨(5자리 길이 맞춰서 출력(5자리 이하일경우 공백열로 채워넣음))
%m : 메시지
%n : 줄바꿈
%t : 스레드명
[ # jboss 에서 log4j 사용시 필요한 설정 ]
: jboss 내부적으로 slf4j, log4j 라이브러리를 내장하고 있기 때문에
해당 부분을 exclude 하여 충돌요소를 제거
[ jboss-deployment-structure.xml ]
1
2
3
4
5
6
7
8
9
10
|
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<exclusions>
<module name="org.apache.log4j" />
<module name="org.apache.commons.logging" />
<module name="org.slf4j"/>
</exclusions>
</deployment>
</jboss-deployment-structure>
|
cs |
참고 : http://blog.naver.com/PostView.nhn?blogId=djawl_2&logNo=220665045226&redirect=Dlog&widgetTypeCall=true
(위 고수님의 블로그에 jboss 환경변수를 이용하여 충돌을 막는 방법도 기재되어 있음)
[ # jboss 에서 log4j 2.10 버전 이상 사용시 발생하는 문제 ]
jboss 에서 log4j 2 2.10 이상 버전 사용시 발생하는 warn 로그 :
WARN [org.jboss.as.server.deployment] (MSC service thread 1-5) WFLYSRV0003: Could not index class META-INF/versions/9/module-info.class at /content/example.war/WEB-INF/lib/log4j-api-2.11.1.jar: java.lang.IllegalStateException: Unknown tag! pos=4 poolCount = 32
서버동작에 문제는 없으나 was 기동시 WARN 로그 찍히는게 보기가 싫으니, log4j 버전을 살짝 내려서 사용.
참고 : https://issues.jboss.org/browse/JBEAP-15261
(module-info.class 가 log4j 2.10 이상 버전에 존재하므로 해당 경고가 발생)
참고 : log4j 2 user guide
'back > Spring Framework' 카테고리의 다른 글
[Spring fw] Transaction 설정 및 주의사항 : 예상치 못한 롤백이 이루어 지는 경우, 롤백이 되지 않는 경우 확인해봐야 할 것 (1) | 2019.08.04 |
---|---|
[Spring Fw] POI(Excel lib) 를 사용하여 다운로드하기 (7) | 2019.07.15 |
jar(lib) 동적 빌드 및 배포(profiles 사용) (0) | 2019.04.26 |
스프링프레임워크 AOP를 사용한 로그 출력 : Spring + AOP + logger (0) | 2019.04.19 |
Exception클래스의 구현과 AOP 설정을 이용한 예외처리 (0) | 2019.02.12 |