[로그]log4j2를 이용해 특정 파일에 로그 기록을 모아보았다

zzarbttoo·2021년 8월 4일
0

Spring/Java

목록 보기
3/5

이전에 있던 글을 옮겨온 것으로 과거에 일어났던 상황입니다

A (나): jar 파일로 배치 모듈 만들어서 윈도우 서버에 배포 진행했습니다!
B (상사): 그럼 로그 기록은 어디에 모아놓는거에요?
A (나) : 네...로그기록이요....?(cmd로 주구장창 보기만 함)
B (상사): 백그라운드로 돌릴거 아니에요? 그럼 장애 났을 때 어디서 장애가 났는 지 알아야 할 거 아니에요!로그 모아놓는 파일 따로 만들어서 배포 진행해주세요 그리고 서버 장애나서 내려갔을 때 다시 컴퓨터 재부팅하면 자동으로 실행될 수 있도록 bat파일로 작업 자동으로 등록해주세요
A (나) : 넵!

이런 상황에 맞추어 실행할 때 로그 파일을 따로 모아놓을 수 있는 방법을 적어놓도록 하겠습니다

| 왜 log4j2를 사용했는가?

java에서 로그를 생성하는 프로그램은 log4j, logback, log4j2 등이 있습니다!

그 중에서 log4j는 꽤나 오래된 프로그램이고, 사실 상 개발이 중단되어 (무려 20515년에) 점차 쓰이지 않을 것이라 생각되네요

이후 나온 것이 logback!
log4j를 개발한 개발자가 만든 후속작(!)으로
log4j에 비해 다양한 기능을 제공합니다!(필터링, 자동 리로드, 파일 자동 삭제, 파일 자동 압축 등)

그리고 마지막으로 log4j2!
logback과 비교했을 때 멀티스레드 환경에서 10배에 가까운 처리량을 처리할 수 있고(하지만 지금은 내 알 바 아님 그냥 로그만 찍을거임)
다양한 설정파일 및 appender을 지원해준다고 하는군요!

여하튼 그러한 이유로 log4j2를 이용해보았습니다

| 사용 방식

맨 처음 수정한 것은 pom.xml(maven)!


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
               <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
          </dependency>
        <!-- log4j2 설정 -->
		  <dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot-starter-log4j2</artifactId>
    	  </dependency>
	</dependencies>

기존에 내장되어있던 log4j를 exclude 시키고 log4j2 dependecy를 추가했어요!
아무래도 둘다 로그를 찍는 방식이 같기 때문이라고 생각되는데..
둘이 방식이 같기 때문에 log4j에서 log4j2로 바꾸기 엄청 수월했던 것!

그 다음 application.properties 파일에 log4j2 설정파일.xml를 포함하는 줄을 넣었습니다!

logging.config=src/main/resources/log4j.xml

저 위치에 log4j.xml 설정 파일을 만들었습니다!

이후 아래의 조건을 충족하도록 xml 파일을 작성했습니다

  1. 로그 파일을 지정된 장소에 저장한다
  2. 지정된 로그 파일을 주기적으로 삭제!
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
    <Appenders>
        <Console name="LogToConsole" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <!-- log 파일을 저장하는 위치와 정책 -->
		<RollingFile name="SaveFile">
		  <FileName>{로그 파일 저장될 위치}/Log.log</FileName>
		  <FilePattern>{로그 파일 저장 될 위치}/%d{yyyy-MM-dd-HH}.log</FilePattern>
		  <PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>	
		  <Policies>
		    <TimeBasedTriggeringPolicy interval="1" modulate="true" />
		  </Policies>
		  <DefaultRolloverStrategy max="7" fileIndex="max" >
		  	<Delete basePath = "{로그파일 저장 위치}" maxDepth = "1">
		  		<!-- 3일이 경과한 로그파일은 자동 삭제 -->
		  		<IfLastModified age = "3d"/>
		  	</Delete>
		  </DefaultRolloverStrategy>
		</RollingFile>
    </Appenders>
    <Loggers>
         <!-- 기본(디폴트) loger 설정-->
        <Root level="INFO">
            <AppenderRef ref="LogToConsole"/>
            <AppenderRef ref="SaveFile"/>
        </Root>
    </Loggers>
</Configuration>
  • configration stsatus = INFO : 이것은 이 configuratoin file(log4j.xml)이 로그레벨 몇으로 지정 될 것인지를 알려주는 것입니다! 저는 INFO 레벨로 지정했어요

  • PatternLayout : 로그가 어떤 모양으로 출력 될 것인지를 알려줍니다

  • rollingFile : 사실 나에게 가장 중요한 기능!!! 로그 파일이 어디에 어떻게 저장될 지를 지정해주는 기능!
    - FilePattern : 로그 파일 제목 패턴을 지정해주는 것이며, 제목 패턴일 뿐만 아니라 로그 파일 저장 주기를 설정해줍니다!
    - %d{yyyy-MM-dd-HH}. log 이런식으로 저장하면 한시간마다 로그가 저장되고
    %d{yyyy-MM-dd-HH-mm}.log 이런식으로 저장하면 분마다 로그가 저장됩니다!

  • polices : TimeBasedTriggeringPolicy, SizeBasedTriggeringPolicy 등이 있고 이는 각각 어떠한 정책이 반영될 것인가를 지정해주는 것!

  • Delete : 나에게 두번째로 중요한 기능! 파일을 어떤 기준으로 자동 삭제 할 것인지를 지정해줍니다
    - <IfLastModified age = "3d"/> : 나는 이렇게 지정을 했는데 이는 3일이 지난 파일을 삭제한 다는 것! 3d, 2h, 1m 이런 식으로 다양하게 삭제 주기를 정해줄 수 있더라~~
    - <IfFileName glob="del-*.log"/> : 이건 주기에 상관 없이 지우고 싶은 파일의 패턴을 정해주는 것! (예시는 del-*.log 인 모든 파일을 삭제)
    로그가 찍히자 마자 바로 삭제되는 사태가 일어나서 저는 이 태그를 사용하지 않았습니다!

  • Loggers : 마지막으로 어떤 로그 레벨들을 어떻게 출력할 것인지!
    • Root : 루트 레벨은 꼭 지정해줘야하는데, 나는 INFO를 root level로 정했습니다!
    • root level을 debug 같이 너무 낮게 지정 할 경우에 불필요한 로그가 너무 많이 쌓일 수도 있기 때문에!!
    • AppenderRef : 이제 해당 로그 레벨로 어느정도까지의 일을 수행할 지! 나는 로그를 콘솔에 찍는 것과, 파일로 출력하는 것만 할 수 있도록 지정했습니다

그리고 이제 실제로 개발 환경에서 로그를 찍어보아야겠죵

@Slf4j
@Component
public class LogTestApi {
	
	private final Logger log = LoggerFactory.getLogger(LogTestApi.class);

	private void logTest(String logTestString) {
		log.info("logTestString 출력 ::: " + logTestString);
		log.info("------------------------로그 테스트 입니다-------------------------");
	
 
	}

1) @Slf4j : log4j를 사용 할 때와 동일한 annotation을 사용했어요!
2) private final Logger log = LoggerFactory.getLogger(LogTestApi.class);
: Logger 호출! 이 역시 log4j와 동일한 방식이었어요
3) log.info("logTestString 출력 ::: " + logTestString);
log.log단계(""); 이런 식으로 호출을 했습니다! 이건 log4j와는 살짝 달랐어요

이렇게 log4j2 를 이용해 로그를 찍어보았어용!

사실 로그 파일을 왜 찍는거지...?(자동 로그가 찍히는 편안한 환경에서만 살아온 나) 라고 생각했는데 저런 각박한(!) 상황에 놓여보니 왜 로그 파일을 직접 바깥으로 찍는지도 알 듯 했습니다..

하지만 저렇게 극악무도한 환경 살고 싶지 않아..자동 로그 줘..
암튼 오늘은 이렇게 끝!

혹시 틀린 부분이 있다면 댓글로 달아주세용~! 그럼 뿅

profile
나는야 누워있는 개발머신

0개의 댓글