본문 바로가기

Programming/스프링

logback-spring.xml로 로그 설정하기 (+ log rotate)

참고

 

Dependency 설정

implementation 'org.slf4j:slf4j-api:2.0.6'
implementation 'ch.qos.logback:logback-classic:1.4.5'

 

 

logback-spring.xml 기본 문법

xml 규칙 대부분 따름

camelCase 권장

<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>foo.log</file>
    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file : %line] %msg%n</pattern>
    </encoder>
  </appender>
  
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
   <encoder>
     <pattern>
        %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
      </pattern>
    </encoder>
  </appender>

  <!-- 모든 로그 출력 안함 -->
  <root level="OFF">
    <appender-ref ref="STDOUT" />
  </root>

  <!-- logger 태그에서 level 오버라이드 => 해당 로거는 INFO/DEBUG 레벨 출력함 -->
  <logger name="chapters.configuration" level="INFO" additivity="false"/>
  <logger name="chapters.configuration.Foo" level="DEBUG" additivity="false"/>

</configuration>

 

  • root : 최상단 로거level 속성만 허용 (INHERITED, NULL 불가)
    • 최대 1개로 구성

 

  • appender : 로그 형태 설정 (콘솔, 파일 등)
    • 속성 : name(필수), class(필수)

 

  • logger : 로그 package, level 설정
    • <appender-ref> 태그로 appender 참조 가능
    • 속성 : name(필수), level(선택), additivity(선택) ⇒ 대소문자 구분 X
    • level : 기존 로그 레벨 + INHERITED,NULL(상위 로거 level 따름)
    • 여러 하위 로거에 동일 appender 등록 시 상위 로거(root)에도 출력됨 => additivity=true 설정으로 방지 가능

 

※ 기존 로그 레벨 : TRACE < DEBUG < INFO < WARN < ERROR < OFF

 

 

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

        <springProperty name="LEVEL" source="log.config.level" defaultValue=""/>


	<springProfile name="local"> <!-- 로컬 환경 -->

		<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
			<layout class="ch.qos.logback.classic.PatternLayout">
				<Pattern>
					%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
				</Pattern>
			</layout>
		</appender>

		<root level="${LEVEL}">
			<appender-ref ref="CONSOLE"/>
		</root

	</springProfile>

	<springProfile name="dev, stg, prd"> <!-- 개발 등 환경 -->

		<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
			<layout class="ch.qos.logback.classic.PatternLayout">
				<Pattern>
					%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
				</Pattern>
			</layout>
			
                        <filter class="ch.qos.logback.classic.filter.LevelFilter"> <!-- -->
                              <level>ERROR</level> <!-- 설정한 로그 레벨 -->
                              <onMatch>ACCEPT</onMatch> <!-- ERROR과 일치 시 현 appender 적용-->
                              <onMismatch>DENY</onMismatch> <!-- 불일치 시 appender 적용 안함 -->
                        </filter>
		</appender>

		<root level="${LEVEL}">
			<appender-ref ref="CONSOLE"/>
		</root>

	</springProfile>

</configuration>

 

  • 기타 기능
    • springProfile : 개발, 운영 등 환경 별로 로그 설정 다르게 지정
    • springProperty : 스프링 환경변수를 logback-spring.xml에서 사용하도록 변수 설정
    • filter : 별도로 로그 레벨 설정

 

 

RollingFileAppender

: 파일 rolling(=rotate) 해주는 appender 클래스

 

<?xml version="1.0" encoding="UTF-8"?>
<!-- 15초마다 설정 파일 확인, 변경 시 갱신하려면 
configuration scan="true" scanPeriod="15 seconds" -->
<configuration >
    <springProperty name="profile" source="spring.profiles.active" defaultValue=""/>
    <springProperty name="LOG_PATH" source="log.config.path" defaultValue=""/>
    <springProperty name="LOG_FILE_NAME" source="log.config.filename" defaultValue=""/>
    <springProperty name="ERR_LOG_FILE_NAME" source="error.log.config.filename" defaultValue=""/>
    <springProperty name="LOG_LEVEL" source="log.config.level" defaultValue=""/>
    <property name="LOG_PATTERN" value="%-5level %d{yy-MM-dd HH:mm:ss} [%thread] [%logger{0}-%M:%line] - %msg%n "/>
    <property resource="logback-${profile}.properties"/>

    <timestamp key="BY_DATE" datePattern="yyyyMMdd"/>
    <timestamp key="BY_TIME" datePattern="HH"/>
    
    <!-- Console Appender -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- File Appender -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 파일경로 설정 -->
        <file>${LOG_PATH}/${BY_DATE}/${BY_DATE}_${LOG_FILE_NAME}.log</file>
        <!-- 해당 레벨보다 같거나 높은 수준의 로그 출력 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${LOG_LEVEL}</level>
        </filter>
        <!-- 출력패턴 설정-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>

	<append>true</append>
    
        <!-- Rolling 정책 (파일 관리설정) -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- .gz,.zip 등 넣으면 일자 지났을 때 자동 압축 -->
            <fileNamePattern>${LOG_PATH}/%d{yyyyMMdd}/%d{yyyyMMdd}_${LOG_FILE_NAME}_%i.log</fileNamePattern>
			<!-- 파일 크기 지정 -->
			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
				<!-- 파일당 최고 용량 (kb, mb, gb) -->
				<maxFileSize>10MB</maxFileSize>
			</timeBasedFileNamingAndTriggeringPolicy>
            <!-- 로그 최대 보관 주기 (자동 삭제)-->
            <maxHistory>10</maxHistory>
            <!--<MinIndex>1</MinIndex> <MaxIndex>10</MaxIndex>-->
        </rollingPolicy>
    </appender>

	<root>
		<appender-ref ref="CONSOLE"/>
		<appender-ref ref="FILE"/>
	</root>

</configuration>

 

  • file
    • springProperty로 설정한 변수를 파일 경로에 설정 → 파일명 동적으로 설정
  • rollingPolicy
    • 하위 설정 정책에 의해 적재된 로깅 파일을 롤링
  • rollingPolicy.fileNamePattern
    • 롤링된 파일을 압축하여 롤링되도록 파일명 패턴 재지정
  • rollingPolicy.timeBasedFileNamingAndTriggeringPolicy
    • 시간, 용량 기반 롤링 설정
  • rollingPolicy.timeBasedFileNamingAndTriggeringPolicy.maxFileSize
    • 파일 용량 제한 설정
  • rollingPolicy.maxHistory
    • 저장 일수 제한 설정

 

 

개발 환경

<configuration>
	<!-- 변수 선언 -->
	<property name="root" value="${logging.level.root}"/>
	<property name="jdbc_sqlonly" value="${logging.level.jdbc.sqlonly}"/>
	<property name="jdbc_resultsettable" value="${logging.level.jdbc.resultsettable}"/>
	<property name="path" value="/logs"/> 

	<!-- Console Appender --> 
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> 
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> 
			<pattern>${log_pattern}</pattern> 
		</encoder> 
	</appender>

	<!-- File Appender-->
	<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${path}/consoleLog.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!-- zip 파일로 일별 저장 -->
			<fileNamePattern>${path}\\consoleLog.%d{yyyy-MM-dd}.zip</fileNamePattern>
				<!-- 7일 지나면 파일 자동 삭제 -->
				<maxHistory>7</maxHistory>
		</rollingPolicy>
		<encoder>
			<pattern>
				%d{yyyy-MM-dd HH:mm: ss.SSS} [%thread] %-5level %logger{35} - %msg%n
			</pattern>
		</encoder>
	</appender>

    <root level="INFO">
        <appender-ref ref="FILE" />
        <appender-ref ref="STDOUT" />
    </root>

    <logger name="com.xx" level="${com_xx}" additivity="false">
        <appender-ref ref="FILE" />
    </logger>
    <logger name="jdbc.sqlonly" level="${jdbc_sqlonly}" additivity="false">
        <appender-ref ref="FILE" />
    </logger>

</configuration>

콘솔 + 파일 로그 출력

 

 

운영 환경

<configuration>
	<!-- 변수 선언 -->
	<property name="root" value="${logging.level.root}"/>
	<property name="jdbc_sqlonly" value="${logging.level.jdbc.sqlonly}"/>
	<property name="jdbc_resultsettable" value="${logging.level.jdbc.resultsettable}"/>
	<property name="path" value="/logs"/> 

	<!-- File Appender-->
	<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<file>${path}/consoleLog.log</file>
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!-- zip 파일로 일별 저장 -->
			<fileNamePattern>${path}\\consoleLog.%d{yyyy-MM-dd}.zip</fileNamePattern>
				<!-- 7일 지나면 파일 자동 삭제 -->
				<maxHistory>7</maxHistory>
		</rollingPolicy>
		<encoder>
			<pattern>
				%d{yyyy-MM-dd HH:mm: ss.SSS} [%thread] %-5level %logger{35} - %msg%n
			</pattern>
		</encoder>
	</appender>

    <root level="ERROR">
        <appender-ref ref="FILE" />
    </root>

    <logger name="com.xx" level="${com_xx}" additivity="false">
        <appender-ref ref="FILE" />
    </logger>
    <logger name="jdbc.sqlonly" level="${jdbc_sqlonly}" additivity="false">
        <appender-ref ref="FILE" />
    </logger>

</configuration>

파일로만 로그 출력

 

※ Windows 운영기 실시간 로그 확인

powershell ⇒ Get-Content "파일 경로" -Wait -Tail 10