여러 종류의 다양한 로그 라이브러리들이 존재한다.
Log4 j : java loggin API
Logback : Log4j를 개선시키기 위해 만든 프로젝트
java.util.logging : 이번에 간단하게 사용할 로거.
그리고 흔하게 말하는 SLF4 J는 Simple Logging Facade for Java의 약자로, 자바 애플리케이션에서 로깅을 추상화하는 인터페이스입니다. 로깅은 애플리케이션의 실행 중에 발생하는 이벤트와 정보를 기록하는 작업을 말합니다.
SLF4J는 로깅 시스템과의 결합을 줄이고, 로깅 시스템을 유연하게 교체할 수 있는 기능을 제공하여 개발자에게 편의성을 제공합니다.
SLF4J의 핵심 아이디어는 인터페이스와 바인딩으로 이루어져 있습니다. SLF4J는 인터페이스를 제공하여 개발자가 코드를 작성할 때 일관된 로깅 메서드를 사용할 수 있도록 합니다. 이 인터페이스는 로깅 시스템에 대한 추상화를 제공하며, 다양한 로깅 시스템을 지원하기 위해 설계되었습니다.
실제로 로깅을 수행하는 로깅 시스템은 SLF4J 바인딩을 통해 설정됩니다. SLF4J 바인딩은 SLF4J 인터페이스 호출을 특정 로깅 시스템의 호출로 변환하여 실제 로그를 기록합니다. 예를 들어, SLF4J 바인딩을 사용하여 Logback, Log4j, java.util.logging 등 다양한 로깅 시스템을 지원할 수 있습니다.
SLF4J를 사용하면 개발자는 로깅 시스템에 종속되지 않고 코드를 작성할 수 있습니다. 또한, 로깅 시스템을 변경하거나 다른 로깅 시스템을 함께 사용할 때도 코드 변경을 최소화할 수 있습니다. 이를 통해 애플리케이션의 유지 보수성과 확장성을 향상시킬 수 있습니다.
보통 자바 애플리케이션을 만들 때 SLF4J를 사용하되 실제 구현체로는 logback을 자주 사용합니다.
다만 간단한 애플리케이션인 경우 간단한 java Logger을 사용하는 것도 큰 무리는 아닐 것입니다.
간단한 예시를 들어서 log대한 Level을 지정해 메시지를 출력할 수 있습니다.
public class Logger {
private final static java.util.logging.Logger LOG = java.util.logging.Logger.getGlobal();
public static void main(String[] args) {
LOG.setLevel(Level.INFO);
LOG.severe("severe");
LOG.warning("warning");
LOG.info("info");
}
}
Log의 수준을 높은 순서로 자주 쓰이는 순서로 나열하면 SEVERE , WARNING, INFO로 나열한다.
순서 OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL
레벨을 지정하고 싶다면 setLevel()를 사용해 지정해줄 수 있습니다. 다만 로그의 형식을 재조정하는 일이 필요합니다.
이때 Formatter클래스를 이용해 우리가 원하는 로그를 만들어 줄 수 있습니다.
또한 로그를 어디에 출력할지 정하기 위해선 핸들러를 통해서 지정합니다.
- StreamHandler는 OutputStream 형태로 출력합니다.
- ConsoleHandler는 시스템 콘솔에 출력합니다.
- FileHandler는 파일을 생성해 해당 파일에 로그를 출력합니다.
- SocketHandler는 원격 TCP 포트를 사용합니다.
- MemoryHandler : 메모리의 순환 버퍼에 요청을 버퍼링하는 핸들러입니다. 일반적으로 이 핸들러는 들어오는 LogRecord를 메모리 버퍼에 저장하고 이전 레코드를 버립니다. 이 버퍼링은 매우 저렴하며 포맷 비용을 방지합니다. 특정 트리거 조건에서 MemoryHandler는 현재 버퍼 내용을 대상 Handler로 푸시하여 일반적으로 외부 세계에 게시합니다. -oracle.doc
기본 설정 파일 경로는 JRE/lib/logging.properties입니다.
만약 설정 파일을 따로 지정하기 위해서는 자바 실행 옵션에 다음 내용을 추가해야 한다.
- Djava.utill.logging.config.file = D~~~~... log.properties
전문적인 애플리케이션에서는 보통 전역 로거 하나로 모든 레코드를 로그로 기록하지 않는다.
대신 로거를 직접 정의해서 사용한다.
Logger logger = Logger.getLogger("com.mycompany.myapp");
패키지 이름과 유사하게 로거 이름은 계층구조다.
로깅 레벨은 SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST가 있다. 기본적으로는 INFO 이상만 로그로 기록하지만 변경 가능하다.
logger.setLevel(Level.FINE); // FINE이상 레벨을 다 로그로 출력
로그의 기본 출력을 custom 하기 위한 방법으로 Formatter를 상속받을 클래스를 생성해 format을 오버라이드 하면 된다.
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.LogRecord;
public class CustomLogFormatter extends Formatter {
@Override
public String getHead(Handler h) {
return "login log start\n";
}
@Override
public String format(LogRecord record) {
StringBuffer str = new StringBuffer(1000);
str.append("[");
str.append(record.getLevel());
str.append("] ");
str.append("[");
str.append(record.getSourceMethodName());
str.append("] ");
str.append(record.getMessage());
return str.toString();
}
@Override
public String getTail(Handler h) {
return "login log end\n";
}
public String dateFormat(ZonedDateTime dateTime) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd HH:mm:ss");
dateTime.format(formatter);
return dateTime.toString();
}
}
포맷 설정을 완료했다면 사용해보자.
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.logging.*;
public class Logger {
private final static java.util.logging.Logger logger = java.util.logging.Logger.getLogger("com.company.app");
public static void main(String[] args) {
logger.setLevel(Level.FINE);
logger.severe("severe");
logger.warning("warning");
logger.info("info");
logger.info(logger.getName());
ZonedDateTime dateTime = ZonedDateTime.now(ZoneId.of("Asia/Seoul"));
CustomLogFormatter formatter = new CustomLogFormatter();
String formatText = formatter.dateFormat(dateTime);
logger.info(formatText);
//console.Handler사용
Handler handler = new ConsoleHandler();
handler.setFormatter(formatter);
logger.addHandler(handler);
logger.severe("severe");
logger.warning("warning");
logger.info("info");
}
}
'JAVA > [JAVA] 바구니' 카테고리의 다른 글
[JAVA] 디자인 패턴 (0) | 2021.04.13 |
---|---|
[JAVA] 예외 처리 (0) | 2021.03.27 |
[JAVA] Java Virtual Machine (0) | 2020.07.08 |
[JAVA] RuntimeException (0) | 2020.06.06 |
[JAVA] Exception (0) | 2020.06.06 |
댓글