System.out.print
우리는 System.out.print로 우리는 로그를 출력하곤 합니다. 그래서, 로그를 많이 출력하게 되면 로그용 함수를 만들어서 보기 쉽게 만들어 주거나, 파일로 출력해서 나중에 확인할수 있게 하기도 합니다. 참 아마추어 적인 코드입니다.
public void log(String tag, String message) {
System.out.println("[" + tag + "]" + message);
filelog("logfile.txt", "[" + tag + "]" + message);
}
추가 개발 요구사항
- 로그가 너무많이 쌓이니, 오래된 로그는 삭제해 주세요.
- 하지만, 이렇게 하면 로그가 용량이 많은 서비스에선 로그때문에 서비스가 죽는 사고가 발생합니다.
Kafka같은 시스템에서 log가 엄청나게 쌓인다. 그럼 오래된 로그는 삭제해야 겠군.
- 하지만, 이렇게 하면 로그가 용량이 많은 서비스에선 로그때문에 서비스가 죽는 사고가 발생합니다.
- 한 로그파일에만 로그가 쌓여서 검색하기 힘듭니다. 파일명에 시스템날짜를 넣어주세요.
- 시스템 날짜에 맞게 파일명을 바꾸라는 요구가 들어올수도 있다. 그런데, 로그시스템을 개발하느라, 정작 핵심기능은 언제 개발하지?
Log4j
그래서, 나온것이 바로 Log4j이다.나도 log4j를 최근에야 알았다. 한심하다 Log4j는 아파치재단에서 나온것으로서, 프로젝트를 개발하는데 Log관련 스트레스를 없애준다.
log4j는 1.2버전과 2버전으로 나뉘어 있는데, 1.2버전도 kafka, Elasticsearch에서 쓰이는등 쓰는데 하등 문제가 없어 보인다. 나는 1.2버전을 설명하겠다. 괜히 최신버전 쓸 필요가 있낭?
- Log4j v1.2 사이트: http://logging.apache.org/log4j/1.2/publications.html
- Log4j v2 사이트: https://logging.apache.org/log4j/2.x/index.html
maven설정은 아래와 같이 하나만, dependency를 걸면 된다.
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
Java 코드에서 사용법은 아래와 같다. 복잡하지 않다.
import org.apache.log4j.Logger;
public class Test {
public static Logger logger = Logger.getLogger(Test.class.getName());
public static void main(String[] args) {
logger.fatal("fatal log");
logger.error("error log");
logger.warn("warn log");
logger.info("info log");
logger.debug("debug log");
logger.trace("trace log");
}
}
log4j 환경설정
Debug Level에 콘솔창에만 로그 출력하기
# log4j Setting file
log4j.rootLogger=DEBUG, console
# Console log
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log 출력은? 아래와 같이 그냥 message ARG만 출력된다.
fatal log
error log
warn log
info log
debug log
그런데, 부가정보도 같이 출력하고 싶으면? conversionPattern을 쓰면 된다.
# log4j Setting file
log4j.rootLogger=DEBUG, console
# Console log
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %l -%m%n
아래처럼 분석에 도움이 되는 부가정보를 같이 보여준다. 참 좋다^^
2019-03-01 11:11:29 FATAL Test.main(Test.java:17) fatal log
2019-03-01 11:11:29 ERROR Test.main(Test.java:18) error log
2019-03-01 11:11:29 WARN Test.main(Test.java:19) warn log
2019-03-01 11:11:29 INFO Test.main(Test.java:20) info log
2019-03-01 11:11:29 DEBUG Test.main(Test.java:21) debug log
File log를 저장하기
DailyRollingFileAppender
# log4j Setting file
log4j.rootLogger=DEBUG, console
# Console log
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %l -%m%n
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.Treshhold=DEBUG
log4j.appender.file.File=/home/manager/project/log/data.log4j
log4j.appender.file.appender=true
log4j.appender.file.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p], %d{yyyy-MM-dd HH:mm:ss}, %m, %n
$ ls log
data.log
data.log.2019-03-01.log
data.log.2019-02-28.log
log4j.RollingFileAppender
RollingFileAppender는 날짜별로 로그파일을 관리하는게 아니라, 로그사이즈별로 관리하는 방법이다. 아래 환경설정대로라면 로그가 3KB를 넘길때마다 파일 새로 만들고, 로그파일은 MAX 3개만 관리하고 3개가 넘으면 OLD 로그는 자동 삭제한다.
# log4j Setting file
log4j.rootLogger=DEBUG, console
# Console log
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %l -%m%n
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.Treshhold=DEBUG
log4j.appender.file.File=/home/manager/project/log/data.log4j
log4j.appender.file.MaxFileSize=3KB
log4j.appender.file.MaxBackupIndex=3
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p], %d{yyyy-MM-dd HH:mm:ss}, %m, %n
결과는요
$ ls log
data.log
data.log.1
data.log.2
log4j.rolling.RollingFileAppender
그런데 말이다. 위에 2가지 기능만으론 뭔가 아쉽다. 오래된 로그파일을 zip파일로 압축해 줬으면 좋겠다. 이런 확장기능을 위해서 log4j-extras 라이브러리가 나왔다. 쓰기위해선 아래 추가 dependency가 필요하다.
<dependency>
<groupId>log4j</groupId>
<artifactId>apache-log4j-extras</artifactId>
<version>1.2.17</version>
</dependency>
org.apache.log4j.rolling.RollingFileAppender가 필요하다. policy는 log4j.rolling.TimeBasedRollingPolicy이다.
log4j.rootLogger=WARN, console, file
# Console log
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n
#File log
log4j.appender.file=org.apache.log4j.rolling.RollingFileAppender
log4j.appender.Threshold=WARN
log4j.appender.file.rollingPolicy=org.apache.log4j.rolling.TimeBasedRollingPolicy
log4j.appender.file.rollingPolicy.ActiveFileName=./logs/streams.log
log4j.appender.file.rollingPolicy.FileNamePattern=./logs/streams.log.%d{yyyy-MM-dd}.gz
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p], %d{yyyy-MM-dd HH:mm:ss}, %m%n
결과는요
$ ls log
streams.log
streams.log.2019-03-01.gz
streams.log.2019-02-28.gz
추가 기능
추가기능은 아래 사이트를 참고하세요. log4j에는 우리가 모르는 많이 기능이 있다. http://2min2code.com/articles/log4j_intro/rolling_archiving_file_per_day_prop