ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • log4j / logback / log4j2 정리
    개발공부/JAVA 2022. 11. 9. 14:47

    ⊙ 적용환경

    • sprnigboot 2.3.1버전
    • jdk 1.8
    • tomcat 7

    ⊙ 로그(Log)란 ?

    • 애플리케이션의 상태를 관찰할 수 있도록 애플리케이션이 제공하는 정보 (=기록)
    • log4j, logback, log4j2 모두 Java 로깅 애플리케이션
    • 시간 순으로는 log4j → logback → log4j2 으로 등장
    • 다른 로깅 프레임 워크로 전환할 때 slf4j 필요

    ※ slf4j

    • Java 로깅 프레임워크들의 추상체 역할, 이 자체를 사용하는 편은 적음
    • 자바로 따지면 인터페이스와 비슷한 역할, 사용중인 로깅 프레임워크가 변경되더라도 소스코드 자체의 변경을 막을 수 있음
    • 만약 log4j → logback으로 변경할 때 log4j를 import 하던 파일들을 다 logback으로 바꿔줘야함
    import org.apache.log4j.Logger;
    
    import org.apache.log4j.spi.LoggerFactory;

    💡 소스마다 박혀있는 apache.log4j를 다 바꿔줘야함

     

    • 하지만 slf4j를 쓴다면 사용하지 않는 dependency만 제거하면됨
    import org.slf4j.Logger;
    
    import org.slf4j.LoggerFactory;
    • 개발자는 어떤 상황이든 대처하고 확장될 수 있는 느슨하고 유연한 코드를 만들어야 하기때문에 어떤 라이브러리를 쓰든 동일하게 동작하는 코드를 작성해야하고 그렇기때문에 slf4j를 사용해야함

    💡 pom.xml

    ...
    <!-- Logging -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>
    ...
    

    ● log4j

    • Apache에서 만든 오픈소스 라이브러리로 프로그램을 작성하는 도중 로그를 남기기 위해 사용되는 자바 기반 로깅 유틸리티

    - !! 2015년 개발팀의 log4j 개발 중단 발표가 있어서 더이상 사용X !!

     

    **구조

    • Logger : 로깅이 일어나느 부분을 그룹화, 필요한 그룹의 로그만 추출하거나 카테고리에 우서순위를 부여함으로써 여러가지 출력방법을 지원
    • Appender : 로그의 출력 위치를 지정
    1) ConsoleAppender : 콘솔에 로그 메세지를 출력
    - 현재 LCA는 이걸로 설정되어있음
    
    2) FileAppender: 파일에 로그 메시지를 출력
    
    3) RollingFileAppender: 로그의 크기가 지정한 용량 이상이 되면 다른 이름의 파일을 출력
    - txt파일로 설정하고 싶으면 이걸로 설정
    
    4) DailyRollingFileAppender: 하루를 단위로 로그 메세지를 파일에 출력
    
    5) SMTPAppender: 로그 메세지를 이메일로 전송
    
    6) NTEventLogAppender: 윈도우의 이벤트 로그 시스템에 기록한다.
    • Layout : 로그의 출력 포맷을 지정
     - %d : 로그의 기록시간
    
     - %p : 로깅의 레벨
    
     - %F : 로깅이 발생한 프로그램의 파일명
    
     - %M : 로깅이 발생한 메소드의 이름
    
     - %I : 호출지의 정보
    
     - %L : 로깅이 발생한 호출지의 라인 수
    
     - %t : 로깅이 발생한 Thread 명
    
     - %c : 로깅이 발생한 카테고리
    
     - %C : 로깅이 발생한 클래스명
    
     - %m : 로그 메세지
    
     - %n : 개행문자 출력
    
     - %% : % 출력
    
     - %r : 시작 이후로부터 로깅이 발생한 시점까지의 시간(ms)
    

    ▶ 실행

    💡 pom.xml

    ...
    
    <!-- Logging -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>
    
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    
    ...
    

    💡 logback.xml

    <예시>
    ex) [%d{HH:mm:ss}] [%-5p] [%t] %c[%M:%L] - %m%n
    

    💡 CzDemoApplication.java

    💡 콘솔 로그 출력


    ● logback

    • Logs4j를 토대로 새롭게 만들어진 로깅 라이브러리로 스프링부트의 기본 로그 객체
    • 스프링이나 일반적인 자바프로그램의 경우 resources 디렉토리안의 logback.xml 참고

    (logback.groovy → logback-test.xml → logback.xml 순서대로 찾음)

    • 스프링부트는 logback-spring.xml 파일을 참고

    **구조 : Log4j와 유사한 구조

    • Logger : 실제 로깅을 수행하는 구성요소로 Level속성을 통해서 출력할 로그의 레벨 조절 가능
    <Log4j의 로깅 레벨(지정한 것 이상의 레벨메세지가 출력)>
    
    1) ERROR : 일반 에러가 일어났을 때 사용
    
    2) WARN : 에러는 아니지만 주의할 필요가 있을 때 사용
    
    3) INFO : 일반 정보를 나타낼 때 사용
    
    4) DEBUG : 일반 정보를 상세히 나타낼 때 사용
    
    5) TRACE : 경로추적을 위해 사용
    
    • Layout
     - %logger{length} : Logger name을 축약할 수 있음 {length}는 최대 자리 수
    
     - %thread : 현재 Thread 이름
    
     - %-5level : 로그 레벨, -5는 출력의 고정폭 값
    
     - %msg : 로그 메시지 ( =%message)
    
     - %n : new line
    
     - %highlight: 로그레벨에 따른 색을 줄 수 있는 듯 함
    
     - 나머지는 log4j와 비슷
    

    ** 특징

    • log4j보다 약 10배정도 빠름, 메모리 효율성 향상
    • 설정 파일을 변경하였을 경우, 서버 재기동 없이 변경 내용이 자동으로 갱신
    • RollingFileAppender로 자동으로 오래된 로그 삭제

    ▶ 실행

    💡 pom.xml

    ...
    
    <!-- Logging -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>slf4j-api</artifactId>
    			<version>${org.slf4j-version}</version>
    		</dependency>
    
    		<dependency>
    		    <groupId>ch.qos.logback</groupId>
    		    <artifactId>logback-classic</artifactId>
    		    <version>1.2.3</version>
    		</dependency>
    
    ...
    
    • logback은 logback-core, logback-classic, logback-access 3개의 모듈이 존재
    1. logback-core : classic과 access의 공통, 핵심 코어 컴포넌트
    2. logback-classic : slf4j에서 사용가능하도록 만든 플러그인 컴포넌트
    3. logback-access : 사용하는 어플리케이션이 '웹 어플리케이션'일 때 유용, HTTP요청에 대한 강력한 디버깅 기능을 제공
    • maven repository를 쓴다면 classic만 추가하여 관련 라이브러리 사용 가능

    💡 logback.xml

    <예시>
    ex) [%d{HH:mm:ss}] [%-5level] [%thread] %logger[%method:%line] - %msg%n
    

    💡 CzDemoApplication.java

    💡 콘솔 로그 출력

    • 코드에는 trace레벨이 선언되어있는데(25줄) 콘솔 결과에는 출력되지 않음

    → logback설정에 로그출력레벨을 debug로 지정

    → 지정안하면 기본설정의 로그출력레벨은 debug


    ● log4j2

    • log4j와 logback과 비교했을 때 가장 최근에 등장
    • 다양한 설정파일 확장자 지원(properties, xml, yaml, json 등)
    • logback의 기능을 대부분 제공하지만 성능면에서는 전반적으로 앞서고 있음

    → 이전버전들의 동기화 이슈들을 해결

    ▶ 실행

    💡 pom.xml

    ...
    <dependencies>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    			
    			<!-- 해당 설정 안하는 경우 스프링부트에서 기본설정되어있는 logback을 사용하게됨 -->
    			<exclusions>
    				<exclusion>
    					<groupId>org.springframework.boot</groupId>
    					<artifactId>spring-boot-starter-logging</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    ...
    <!-- Logging -->
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-log4j2</artifactId>
    		</dependency>
    	</dependencies>
    

    💡 log4j2.xml

    • resources에 log4j2.xml 파일 생성해야함

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="INFO">
        <Appenders>
            <Console name="console" target="SYSTEM_OUT">
                <PatternLayout pattern="[%d{HH:mm:ss}] [%-5p] [%t] %c[%M:%L] - %m%n" />
            </Console>
        </Appenders>
        
        <Loggers>
            <Root level="debug">
    	        <AppenderRef ref="console" />
    	    </Root>
        </Loggers>
    </Configuration>
    

    💡 application.properties

    logging.config=classpath:log4j2.xml
    

    💡 CzDemoApplication.java

    💡 콘솔 로그 출력

    • logback과 마찬가지로 debug레벨이라 trace는 출력되지않음

    ● 이슈사항 정리

    1) SLF4j(Logback) MultipleBinding

    • slf4j와 logback 두개를 모두 dependency에 추가하여 생긴 멀티바인딩 문제
    • log4j2를 사용하고싶은데 logback이 default로 잡히면서 문제가 생김
    • 1개만 dependency를 사용하던지 아니면 pom.xml에 필요없는건 exclusion으로 제외시켜줘야함

    SLF4J: Class path contains multiple SLF4J bindings.
    SLF4J: Found binding in [jar:file:/C:/Users/CZ-kmki-N1/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: Found binding in [jar:file:/C:/Users/CZ-kmki-N1/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.12.0/log4j-slf4j-impl-2.12.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
    SLF4J: See <http://www.slf4j.org/codes.html#multiple_bindings> for an explanation.
    

    2) springboot에서 log4j2 적용

    ...
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            **<exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>**
        </dependency>
    ...
    <!-- Logging -->
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			**<artifactId>spring-boot-starter-log4j2</artifactId>**
    		</dependency>
    ...
    
    • log4j 나 logback와 다르게 log4j2는 스프링부트 log4j2로 적용해야함

    (log4j나 logback은 기존 spring프로젝트에 있던거 적용해도 문제가 안됐었음)

    • spring-boot-starter-web안에 exclusion 선언해줘야함
          •  
Designed by Tistory.