본문 바로가기

목록이 없습니다.

[Spring framework] logback RollingFileAppender 설정

Framework/Spring
    반응형

     

    logback 이미지.. 상당히 오래된 기술로 보인다.

     

    기존에 log4j를 로깅 구현체로 사용하고 있었는데 보안이슈가 연달아 터지면서 관리하는 여러 서버들의 버전업을 일괄 처리하는 매우 비효율적인 작업을 반복하다 보니 log4j를 사용하기 싫어지기도 했고 logback이 log4j를 만든분이 그 다음에 만든 것이라고하여 뭔가 좀 더 나은게 있지 않을까 찾아보았다.

     

    사실 log4j 자체도 제대로 사용하고 있다는 느낌은 아니었기 때문에 이번에 바꾸기로 한거 좀 더 깊게 알아보자하여 찾아보니 logback에 유용한 기능들이 아주 많다는 것을 알게 되었고 logback으로 바꾸는게 좋겠다는 생각이 좀 더 기울었다.

    우선 log4j로 서버에서 로깅을하면 아무래도 파일 기반 로깅을 하고 있기 때문에 한정된 서버 용량에 로그가 넘치지 않게 하기 위해서 주기적으로 관리가 필요한데 logback에서는 설정을 통해서 알아서 되게끔 할 수 있다는 것에 정말 좋다고 느꼈다.

     

    주저리주저리 이정도만 하고 어떤식으로 설정하는지 삽질의 결과를 정리해보려고한다.

     

    logback.xml

    spring boot는 logback-spring.xml이라는 이름으로 해도 인식이 되는데 boot가 아닌 경우에는 인식되지 않는 것 같다. 그리고 위치도 web.xml에 context-param으로 지정하면 다른 위치에 둬도 인식되게 할 수 있긴 할것 같은데 그냥 기본 위치인 resources 아래에 두었다. 인식이 되기도 했고 다른 위치에 옮길 이유도 없었기 때문에 그냥 사용한다.

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    
    	<!-- properties -->
    	<property name="SERVICE_NAME" value="GOOD" />
    	
    	<!-- Log info properties -->
    	<property name="LOG_DIR_NAME" value="${SERVICE_NAME}_LOG" />
    	<property name="LOG_PATH" value="F:/${LOG_DIR_NAME}" />
    	<property name="LOG_LEVEL" value="DEBUG" />
    	<property name="LOG_PATTERN" value="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
    	
    	<!-- File name properties -->
    	<property name="FILE_NAME" value="${LOG_PATH}/${SERVICE_NAME}" />
    	<property name="DEBUG_FILE_NAME" value="${FILE_NAME}_debug.log" />
    	<property name="INFO_FILE_NAME" value="${FILE_NAME}_info.log" />
    	<property name="ERROR_FILE_NAME" value="${FILE_NAME}_error.log" />
    	
    	<!-- File pattern properties -->
    	<property name="FILE_PATTERN" value="${FILE_NAME}_%d{yyyy-MM-dd}" />
    	<property name="DEBUG_FILE_PATTERN" value="${FILE_PATTERN}_debug(%i).log" />
    	<property name="INFO_FILE_PATTERN" value="${FILE_PATTERN}_info(%i).log" />
    	<property name="ERROR_FILE_PATTERN" value="${FILE_PATTERN}_error(%i).log" />
    	
    	<!-- Rolling properties -->
    	<property name="MAX_HISTORY" value="30" />
    	<property name="MAX_FILE_SIZE" value="1GB" />
    	<property name="TOTAL_SIZE_CAP" value="10GB" />
    	
    	<!-- Console appender -->
    	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
    			<level>${LOG_LEVEL}</level>
    			<onMatch>ACCEPT</onMatch>
    			<onMismatch>DENY</onMismatch>
    		</filter>
        </appender>
        
        <!-- Debug log appender -->
        <appender name="debugLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    		<file>${DEBUG_FILE_NAME}</file>
    		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    			<fileNamePattern>${DEBUG_FILE_PATTERN}</fileNamePattern>
    			<maxHistory>${MAX_HISTORY}</maxHistory>
    			<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
    			<totalSizeCap>${TOTAL_SIZE_CAP}</totalSizeCap>
    		</rollingPolicy>
            <encoder>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
    			<level>DEBUG</level>
    			<onMatch>ACCEPT</onMatch>
    			<onMismatch>DENY</onMismatch>
    		</filter>
        </appender>
        
        <!-- Info log appender -->
        <appender name="infoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    		<file>${INFO_FILE_NAME}</file>
    		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    			<fileNamePattern>${INFO_FILE_PATTERN}</fileNamePattern>
    			<maxHistory>${MAX_HISTORY}</maxHistory>
    			<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
    			<totalSizeCap>${TOTAL_SIZE_CAP}</totalSizeCap>
    		</rollingPolicy>
            <encoder>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
    			<level>INFO</level>
    			<onMatch>ACCEPT</onMatch>
    			<onMismatch>DENY</onMismatch>
    		</filter>
        </appender>
        
        <!-- Error log appender -->
        <appender name="errorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    		<file>${ERROR_FILE_NAME}</file>
    		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    			<fileNamePattern>${ERROR_FILE_PATTERN}</fileNamePattern>
    			<maxHistory>${MAX_HISTORY}</maxHistory>
    			<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
    			<totalSizeCap>${TOTAL_SIZE_CAP}</totalSizeCap>
    		</rollingPolicy>
            <encoder>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
    			<level>ERROR</level>
    			<onMatch>ACCEPT</onMatch>
    			<onMismatch>DENY</onMismatch>
    		</filter>
        </appender>
        
        <root level="DEBUG">
            <appender-ref ref="console" />
            <appender-ref ref="errorLog" />
            <appender-ref ref="infoLog" />
            <appender-ref ref="debugLog" />
     	</root>
    </configuration>

     

    삽질 1.

    logback.xml을 설정할 때 시행착오를 겪었는데 RollingFileAppender를 설정하는 부분에서 사용하는 class에 필수로 필요한 설정값, 예를들어 rollingPolicy의 class가 SizeAndTimeBasedRollingPolicy 이면 Size와 Time에 대한 설정값이 Policy태그 안에 설정이 되어 있어야 정상적으로 로깅이 된다.

    <appender name="debugLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    	...
    	<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    		<fileNamePattern>${DEBUG_FILE_PATTERN}</fileNamePattern>
    		<maxHistory>${MAX_HISTORY}</maxHistory>
    		<maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
    		<totalSizeCap>${TOTAL_SIZE_CAP}</totalSizeCap>
    	</rollingPolicy>
        ...
    </appender>

     

    삽질 2.

    또 한가지 삽질을 한 것은 이번 설정의 경우 root logger에 여러 appender를 붙여서 로그 레벨별로 다른 파일이 나오도록 설정을 했는데 이 부분에서 File pattern이 겹치게 되면 그 중에 한가지 file로만 로깅이 된다.

     

    <!-- Debug log appender -->
    <appender name="debugLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    	<file>debug.log</file>
    	<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    		<fileNamePattern>%i.log</fileNamePattern>
    		...
    	</rollingPolicy>
        ...
    </appender>
    
    <!-- Info log appender -->
    <appender name="infoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    	<file>info.log</file>
    	<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    		<fileNamePattern>%i.log</fileNamePattern>
    		...
    	</rollingPolicy>
        ...
    </appender>
    
    <!-- Error log appender -->
    <appender name="errorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    	<file>error.log</file>
    	<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    		<fileNamePattern>%i.log</fileNamePattern>
    		...
    	</rollingPolicy>
        ...
    </appender>

    위의 경우 로깅이 최상단에 설정된 debugLog만 실제 로그파일로 appender가 동작하고 나머지 infoLog와 errorLog같은 경우에는 동작하지도 않고 어떤 에러가 발생하지도 않는다.. 내 경우에는 에러가 발생하지 않아서 헤매었다.

     

    개인적인 바람

    xml 설정을 할 때 불편한점이 눈에 잘 안들어오는 가독성도 있지만 잘못 설정했을 때 어디부분이 잘못된건지 모르겠다. 오류를 뱉어주는것도 아니고 그냥 안된다. 그러다보면 찍어맞추는 과정이 계속 반복된다. 결과적으로는 성공했지만 결과물 자체를 두고 보면 들인 시간에 비해서 한없이 초라하다.
    이번 logback.xml 설정 과정에서도 역시 마찬가지였다. 이런 점에서는 boot로 넘어가서 properties 기반으로 설정하면 좋을 것 같다는 생각이 든다. properties에서는 다 그런건지는 모르겠지만 assistent가 되던데.. 그럼 편하게 설정 가능할 것 같다.

     

     

     

     

     

     

    참고

     

     

    Chapter 4: Appenders

    Chapter 4: Appenders 和訳 (Japanese translation) There is so much to tell about the Western country in that day that it is hard to know where to start. One thing sets off a hundred others. The problem is to decide which one to tell first. —JOHN STEINBE

    logback.qos.ch

     

     

    Log4j에서 LOGBack으로 마이그레이션 하기 ( migrate from log4j to logback)

    몇년전 부터 프로젝트에서 로그 라이브러리로 “LOGBack”를 사용하고 있습니다. 혹시나 모르시는 분을 위해서 간략하게 설명하면 “LOGBack”은 “Log4J”, “Apache Common Logging”, “Java Logging” 같은

    beyondj2ee.wordpress.com

     

     

    logback 사용해야 하는 이유 (Reasons to prefer logback over log4j)

    최근 프로젝트를 진행하면서 자바 로깅 구현체(logger)로  “LOGBack”을 사용 하고 있습니다. “개발자의 얼리”적 성향이기 보다는 “log4j”에서 제공을 하지 않는 기능 외에 다양한 이점이 있기

    beyondj2ee.wordpress.com

     

     

     

     

     

    반응형