Java 애플리케이션의 성능 문제를 해결할 때는 JVM 메트릭만으로는 충분하지 않습니다. Java 개념을 완전히 이해하려면 Java 로그와 추적도 필요합니다. 이 글에서는 Java 애플리케이션 로그에 대해 집중적으로 살펴보겠습니다.
로깅(Logging)이란?
로깅은 애플리케이션의 오류를 추적할 수 있는 기능을 제공하는 API입니다. 애플리케이션이 로깅 호출을 생성하면 Logger가 LogRecordfile에 이벤트를 기록합니다. 그런 다음 해당 핸들러(handler) 또는 어펜더(appender)로 이벤트를 보냅니다. 콘솔이나 파일로 보내기 전에 어펜더는 포맷터 또는 레이아웃을 사용하여 로그 기록을 포맷합니다.
Java 로깅 라이브러리/프레임워크
- SLF4J
- java.util.logging
- Logback
- Log4j
- Log4j2
SLF4J
- SLF4J는 Java를 위한 Simple Logging Facade 또는 SLF4J로 알려져 있습니다. 다양한 로깅 프레임워크를 위한 추상화 계층으로, 개발 시점이 아닌 배포 시점에 사용자가 로깅 프레임워크를 선택할 수 있습니다.
- 따라서 필요할 때 원하는 로깅 프레임워크를 빠르고 쉽게 변경할 수 있습니다.
Java util.logging
- java.util.logging 패키지는 Java 핵심 로깅 기능을 위한 클래스와 인터페이스를 제공합니다.
- Java 개발 키트와 함께 번들로 제공되며 Java 1.4 이후 Java를 사용하는 모든 개발자가 사용할 수 있습니다.
Logback
- Logback은 Log4j의 첫 번째 버전의 후속 버전으로 시작되었습니다.
- 세 가지 주요 모듈로 구성되어 있으며, Tomcat 또는 Jetty와 같은 서블릿 컨테이너와 통합되어 HTTP 액세스 로그 기능을 제공합니다.
Log4j
- Log4j는 가장 널리 알려진 Java 로깅 라이브러리 중 하나이며 Logback 또는 Log4j 2와 같은 프로젝트의 전신입니다.
- 그러나 Log4j는 2015년 8월 5일에 수명이 종료되었으며 사용자는 Log4j 2를 사용할 것을 권장합니다.
Log4j 2
- Log4j 2는 앞서 언급한 모든 Java 로깅 프레임워크 목록에서 가장 최신 버전입니다.
- 이전 버전에 비해 많은 개선 사항이 포함되어 있으며 일부 아키텍처 문제를 해결하면서 Logback 개선 사항을 제공할 것을 약속합니다. 새 프로젝트를 시작하면서 선택할 라이브러리를 찾고 있다면 Log4j 2를 중점적으로 고려해야 합니다.
Java 로깅 API를 사용하여 로깅하는 방법
- Java에는 어떤 유형의 로그 메시지를 기록할지 구성할 수 있는 Java 로깅 API가 포함되어 있습니다.
- 이 API에는 기본 로깅 이상의 작업을 진행하고 논의하기 위해 알아야 할 핵심 요소의 표준 세트가 포함되어 있습니다.
- java.util.logging 패키지는 애플리케이션 메시지를 로깅하기 위한 Logger 클래스를 제공합니다.
Logger
- Logger는 애플리케이션이 로깅 호출을 수행하고 적절한 핸들러로 LogRecord를 캡처하는 데 사용하는 주요 엔티티입니다.
- LogRecord(또는 로깅 이벤트)는 로깅에 사용되는 프레임워크와 로그 전송을 담당하는 핸들러 간에 로깅 요청을 전달하는 데 사용되는 엔티티입니다.
- Logger 객체는 일반적으로 특정 사용 사례에 컨텍스트 바인딩된 기능을 제공하기 위해 단일 클래스 또는 단일 컴포넌트에 사용됩니다.
- Java 애플리케이션에 로깅을 추가하려면 일반적으로 선택한 라이브러리를 구성하고 Logger를 포함해야 합니다. 이를 통해 애플리케이션에서 알고 싶은 부분에 로깅을 추가할 수 있습니다.
Handler
-
핸들러(Handler)는 LogRecord 엔티티를 지정된 대상으로 내보내는 데 사용됩니다.
-
이러한 대상은 메모리, 콘솔, 파일, 소켓 및 다양한 API를 통한 원격 위치가 될 수 있습니다. 다양한 표준 핸들러가 있습니다. 다음은 이러한 핸들러의 몇 가지 예입니다.
-
ConsoleHandler
-
FileHandler
-
SyslogHandler
1 | public class ExampleHandler extends Handler { |
Logging 레벨
- Java 로그 레벨은 로깅 메시지에 대한 일련의 표준입니다. 로그 레코드가 얼마나 중요한지를 알려줍니다.
- 예를 들어, 다음 로그 레벨은 가장 중요하지 않은 것부터 가장 중요한 것까지 몇 가지 설명과 함께 정렬되어 있습니다.
TRACE
- TRACE은 애플리케이션에서 일어나는 일을 완전히 파악해야 하는 드문 경우에만 사용됩니다.
- 대부분의 경우 TRACE 레벨은 매우 장황하지만 애플리케이션에 대한 많은 정보를 기대할 수 있습니다.
- 예시: 일상적인 사용과 관련이 없는 알고리즘의 단계에 주석을 달 때 사용합니다.
1 | LOGGER.trace("This is a TRACE log level message"); |
DEBUG
- DEBUG는 TRACE 레벨보다 덜 세분화되어 있습니다.
- 문제 해결에 도움이 될 수 있는 정보에는 DEBUG 레벨을 사용해야 합니다.
1 | LOGGER.debug("This is a DEBUG log level message"); |
INFO
- INFO는 로그 정보의 표준 레벨로 알려져 있습니다. INFO 레벨은 성공 또는 실패 정보와 함께 완료된 특정 프로세스에 대한 정보를 제공합니다.
- 예를 들어 “{} 아이디로 {} 사용자를 만들었습니다.”
1 | LOGGER.info("This is a INFO log level message"); |
WARN
- WARN 로그는 일반적으로 문제가 있거나 비정상적인 실행을 감지한 애플리케이션의 상태를 나타냅니다.
- 예를 들어, 메시지가 올바르게 구문 분석되지 않았기 때문에 메시지가 올바르게 구문 분석되지 않았습니다.
- 코드 실행은 계속되고 있지만 잠재적인 문제가 발생하고 있음을 자신과 다른 사람들에게 알리기 위해 경고로 로그를 기록할 수 있습니다.
1 | LOGGER.warn("This is a WARN log level message"); |
ERROR
- 특정 기능이 작동하지 못하게 하는 시스템 문제를 나타내는 로그 레벨입니다.
- 예를 들어 시스템에 로그인하는 방법 중 하나로 소셜 미디어를 통한 로그인을 제공하는 경우 이러한 모듈의 실패는 ERROR 레벨 로그입니다.
1 | LOGGER.error("This is a ERROR log level message"); |
FATAL
- FATAL 로그 레벨은 애플리케이션이 작동하지 못하게 하는 이벤트가 발생했거나 애플리케이션의 중요한 부분이 작동하지 않았음을 나타냅니다.
- 예를 들어, 시스템이 의존하는 데이터베이스에 연결할 수 없거나 전자상거래 시스템에서 카트를 결제하는 데 필요한 외부 결제 시스템에 연결할 수 없는 경우입니다. 또한 치명적인 오류는 SLF4J에 표시되지 않습니다.