spring boot에서 ~~~xml ${LOG_FILE} ${FILE_PATTERN} ${LOG_FILE}.%d{yyyy-MM-dd} 5 ~~~ 이런식으로 rolling을 지정해줄 수 있다. 어떻게 rolling이 되는 걸까? 우선 두가지를 봐야하는데, 현재 위의 logback configuration에서는 RollingFileAppender를 사용하며, Rolling Policy로 TimeBasedRollingPolicy를 사용한다. RollingFileAppender의 ~~~java public void rollover() { lock.lock(); try { // Note: This method needs to be synchronized because it needs exclusive // access while it closes and then re-opens the target file. // // make sure to close the hereto active log file! Renaming under windows // does not work for open files. this.closeOutputStream(); attemptRollover(); attemptOpenFile(); } finally { lock.unlock(); } } ~~~ 를 확인해보면 ```attemptRollover()```라는 함수가 있다. ~~~java private void attemptRollover() { try { rollingPolicy.rollover(); } catch (RolloverFailure rf) { addWarn("RolloverFailure occurred. Deferring roll-over."); // we failed to roll-over, let us not truncate and risk data loss this.append = true; } } ~~~ 를 보면 rollingPolicy의 rollover함수를 실행시키고, TimeBasedRollingPolicy에서 이를 확인해보면 ~~~java public void rollover() throws RolloverFailure { // when rollover is called the elapsed period's file has // been already closed. This is a working assumption of this method. String elapsedPeriodsFileName = timeBasedFileNamingAndTriggeringPolicy.getElapsedPeriodsFileName(); String elapsedPeriodStem = FileFilterUtil.afterLastSlash(elapsedPeriodsFileName); if (compressionMode == CompressionMode.NONE) { if (getParentsRawFileProperty() != null) { renameUtil.rename(getParentsRawFileProperty(), elapsedPeriodsFileName); } // else { nothing to do if CompressionMode == NONE and parentsRawFileProperty == null } } else { if (getParentsRawFileProperty() == null) { compressionFuture = compressor.asyncCompress(elapsedPeriodsFileName, elapsedPeriodsFileName, elapsedPeriodStem); } else { compressionFuture = renameRawAndAsyncCompress(elapsedPeriodsFileName, elapsedPeriodStem); } } if (archiveRemover != null) { Date now = new Date(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime()); this.cleanUpFuture = archiveRemover.cleanAsynchronously(now); } } ~~~ rename을 하는 것을 확인할 수 있다. 그리고 다시 ```rollover```의 ```attemptOpenFile```를 확인해보면 ~~~java private void attemptOpenFile() { try { // update the currentlyActiveFile LOGBACK-64 currentlyActiveFile = new File(rollingPolicy.getActiveFileName()); // This will also close the file. This is OK since multiple close operations are safe. this.openFile(rollingPolicy.getActiveFileName()); } catch (IOException e) { addError("setFile(" + fileName + ", false) call failed.", e); } } ~~~ 새롭게 activeFileName을 이용하여 file을 생성함을 알 수 있다.