본문 바로가기
Java/Log4j 2

Log4j2 - 개요

by TheUphill 2017. 10. 18.

Log4j 2

얼마 전까지 logback을 사용하고 있었는데, logback 대신 log4j를 사용해야 되는 상황이 됐다. 꽤 오래전에 중단됐었던 log4j의 개발이 얼마 전이라고하긴 뭐하지만 대략 4년 전부터 log4j2라는 이름으로 활발하게 릴리즈가 진행되고 있고 현재는 2.9.1 버전까지 릴리즈된 상태이다. 기존에 log4j에서 부족했던 기능들 및 성능이 대폭 개선돼었고 일부 기능은 logback보다 높은 성능을 보여주는 벤치마크 자료도 제공되고 있다. 이런 이유로 log4j2를 사용하게 됐고 적용 과정에서 얻은 정보들을 공유해보려고 한다.

Log4j2 직접 사용할순 있지만 일반적으로는 SLF4J와 함께 사용하기 때문에 아래 내용중에 일부는 실제 개발 환경에서 적용되지 않는 내용들도 있다(예를들면 메뉴얼에는 LogManager를 이용해 Logger를 생성/획득 하지만 SLF4J를 사용할 경우 LoggerFactory의 팩토리 함수를 이용해 Logger를 획득한다)

아래 내용들은 Log4j 2 공식 사이트 내용을 기반으로 작성됐다.

특징

  1. 실행 및 설정 과정에서 발생하는 로그 이벤트 출력 가능.
  2. Asynchronous Logger 도입. Log4j 1.x 및 Logback보다 멀티 스레드 환경에서 10배 가량 높은 처리량
  3. 더 적은 GC 부하
  4. Plugin System으로 사용자 정의 Appender, Filter, Layout, Lookup, Pattern Converter들을 쉽게 사용 가능. 또한 설정 과정에서 fully qualified class name을 입력할 필요 없음.
  5. 사용자 정의 로그 레벨 지원
  6. 람다 표현식 지원
  7. 메세지 템플릿 기능
  8. Filter를 이용한 Logging 이벤트 필터링
  9. 대부분의 Appender에 Layout 사용이 가능해 출력 포멧에 높은 자유도
  10. Layout이 항상 byte array를 반환해 어떤 Appender와도 호환이 가능
  11. Syslog Appender가 TCP, UDP 및 BSD syslog를 지원
  12. 기존 Log4j 1.x 및 Logback에 존재했던 동기화 이슈를 해결

꽤 많은 특징들이 나열 돼 있지만 단순한 디버깅 및 입출력 로깅목적으로 사용하는데 있어 체감할만한 특징들을 정리해 보았다.

  1. 설정파일 구조가 완전히 변경됐다. 기존 1.x 버전에서 사용되던 설정 파일과 호환이 안된다.
  2. 다양한 설정파일 확장자 지원(properties, xml, yaml, json 등).
  3. 다양한 Appender. 특히 logback의 dailyRolling같은 Appender를 기본적으로 제공한다.(1.x 버전에서는 extra 라이브러리가 필요했다.)

구조

architecture

기본 컨셉

  1. Log4j API를 사용해 LogManager에게 Logger를 획득(Logger 이름 기반)
  2. LogManager는 LoggerContext로 부터 Logger를 획득
  3. Logger 획득 요청이 들어오면 다음 기준에 맞는 LoggerConfig를 사용해 Logger를 생성, 반환한다.
    • 요청한 이름과 동일한 Logger 또는,
    • 요청한 이름의 패키지에 해당하는 부모의 Logger 또는,
    • root Logger

Logger 계층

Log4j2에서 Logger간의 계층(Hierarchy)은 LoggerConfig에 기반한다. LoggerConfig는 다른 LoggerConfig의 부모가 될 수 있는데, 이 관계는 점.으로 연결된 LoggerConfig의 이름으로 결정된다. 예를들어 com.foocom.foo.bar라고 명명된 LoggerConfig의 부모이다. 또한 javajava.util의 부모이며. java.util.Vector의 조상이다. root LoggerConfig는 LoggerConfig 계층의 최상위에 있으며 항상 존재하고, 모든 계층의 일부이다.

구성요소

LoggerContext

LoggerContext는 Logging 시스템의 anchor(닻) 역할을 한다. LoggerContext는 Logger 리스트 및 설정 내용을 담고있다. 환경에 따라 여러개의 LoggerContext를 사용할 수 있다.

Configuration

모든 LoggerContext는 Configuration을 갖는다. Configuration은 Appenders, context-wide Filters, LoggerConfig 및 StrSubstitutor(문자열의 특정 문자를 입력된 변수로 치환해주는 클래스)에 대한 참조를 갖는다. Configuration은 어플리케이션 구동되는 동안 재설정이 가능한데 재설정되는 동안 두개의 Configuration이 동시에 존재하며 모든 Logger가 새로운 Configuration을 바라보게 되면 이전의 Configuration은 삭제된다.

Logger

LoggerManager.getLogger() 함수를 이용해 생성 가능하다. Logger 자체는 어떠한 동작도 하지 않으며 단순히 이름을 갖고 특정 LoggerConfig와 연결돼 있다. AbstractLogger를 확장하며 필요한 함수들을 구현한다.

같은 이름을 파라미터로 사용해 LogManager.getLogger로 얻은 Logger은 동일한 Logger이다.

// x,y는 같은 Logger이다.
Logger x = LogManager.getLogger(“test”);
Logger y = Logmanager.getLogger(“text”);

Logger의 이름은 일반적으로 클래스의 풀네임(ex - package.to.class.ClassName)으로 만드는데, 로그 출력에 Logger의 이름이 포함돼서 로그를 더 쉽게 이해할 수 있게 해주기 때문에다. 반드시 이 방법을 따를 필요는 없지만 권장하는 방법이다. LogManager.getLogger()를 이용하면 자동으로 클래스의 풀네임으로 Logger를 생성,획득 한다.

LoggerConfig

설정(properties, xml, yml 등을 통해)에 명시된 Logger 설정을 기반으로 LoggerConfig객체가 생성된다. LoggerConfig는 Filter(LogEvent가 Appender에 전달되기 전에 거치는 필터) 및 Appender(로깅 이벤트 출력을 담당하는 객체)등을 포함하고 있다.

  • 로그 레벨 : LoggerConfig는 Log level을 설정할 수 있다. 기본으로 제공되는 로그 레벨은 TRACE, DEBUG, INFO, WARN, ERROR 그리고 FATAL이며 사용자 정의 로그 레벨도 설정 가능하다.

Appender

로그는 다양한 경로로 출력이 가능한데 목적지에 관한 정보를 Appender라고 부른다. 하나의 Logger에는 하나 이상의 Appender를 붙일 수 있다. 현재 제공하고 있는 목적지 종류는 다음과 같다.

  • 콘솔
  • 파일
  • 원격 소켓서버
  • 파일
  • 원격 소켓 서버
  • 아파치 Flume
  • JMS
  • 원격 유닉스 Syslog 데몬
  • DB API
Aditivity

특정 Logger에 전달된 로그 이벤트들은 해당 Logger의 LoggerConfig에서 참조하는 Appender들로 전달될 뿐만 아니라 부모 LoggerConfig의 Appender에도 전달된다. 예를들어 만약 root Logger에 consone Appender가 설정돼 있고 C라는 Logger에 file Appender가 설정돼 있는 상태에서 C로 전달된 유효한 로그는 file로도 출력되고 console로도 출력된다. 이 현상을 막기 위해서는 Logger의 속성에 additivity=false를 설정하면 된다.

Layout

Layout은 사용자가 Appender를 통해 출력되는 메세지 포맷을 원하는대로 설정할 수 있게 해준다. Layout 구현체인 PatternLayout은 log4j에서 기본으로 제공하는 문자열 포멧 변환 컴포넌트이다. 예를들어 PatternLayout의 패턴 설정을 다음과 같이 할경우 %r [%t] %-5p %c - %m%n 아래와 같이 출력된다.

176 [main] INFO  org.foo.Bar - Located nearest gas station
Log4j는 XML, JSON, HTML, Syslog 등을 지원하는 다양한 Layouts을 제공한다

StrSubstitutor and StrLookup

StrSubstitutor과 StrLookup은 Log4j 설정의 특정 문자열을 외부에서(시스템 설정, 설정 파일, ThreadContext Map, LogEvent의 StructeredData 등) 참조할 수 있게 해준다. 예를들어 FileAppender의 파일 출력을 tomcat의 인스턴스 아래 출력하고 싶은 경우, 톰캣 구동과정에서 설정되는 catalina.base 프로퍼티를 참조해 설정 가능하게 해준다.

'Java > Log4j 2' 카테고리의 다른 글

Log4j2 - 설정  (0) 2017.12.09

댓글