Spring Boot Logging to File with Pattern Layout, Package-specific Levels, and Rolling Policies

Logging is one of the most important parts of any production-grade Spring Boot application. Done right, it:

Helps debug issues quickly
Prevents log flooding
Organizes logs for different modules or packages
Manages file sizes automatically

In this b…


This content originally appeared on DEV Community and was authored by DevCorner2

Logging is one of the most important parts of any production-grade Spring Boot application. Done right, it:

  • Helps debug issues quickly
  • Prevents log flooding
  • Organizes logs for different modules or packages
  • Manages file sizes automatically

In this blog, we’ll configure logging so that:

  • Logs are written to files with a custom pattern layout
  • Different packages have different logging levels
  • Logs are rolled over daily and by file size
  • Log files are named using a date-based format
  • Old logs are automatically cleaned up

1. Default Spring Boot Logging Behavior

Spring Boot uses SLF4J as the logging facade and Logback as the default logging implementation.
By default:

  • Logs go to the console
  • Log level is INFO
  • No rolling file is configured

We need to customize this to:

  • Store logs in a file
  • Control rolling policies
  • Fine-tune package log levels

2. Setting Up Basic Logging in application.properties

You can control log patterns, log levels, and the base log file name from application.properties.

src/main/resources/application.properties:

############################################
# LOGGING CONFIGURATION
############################################

# ---- Log File Location ----
logging.file.name=logs/app.log  # Writes to logs/app.log

# ---- Log Pattern for File & Console ----
# Date Time | Thread | Level | Logger | Message
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
logging.pattern.console=%d{HH:mm:ss.SSS} %-5level [%thread] %logger{36} - %msg%n

# ---- Package-specific log levels ----
logging.level.root=INFO
logging.level.com.example.productapi.service=DEBUG
logging.level.com.example.productapi.repository=WARN
logging.level.org.springframework.web=ERROR

✅ This will:

  • Send logs to both console and logs/app.log
  • Use a readable timestamped pattern
  • Assign different log levels for different packages

⚠️ Limitation:
application.properties cannot configure rolling policies (e.g., max file size, date-based naming). For that, we need Logback XML.

3. Advanced Rolling File Configuration with logback-spring.xml

For enterprise-grade log management, we want:

  • Time-based rolling (daily logs)
  • Size-based rolling (split large logs into chunks)
  • Retention policy (keep logs for N days)
  • Date-based file naming

Create src/main/resources/logback-spring.xml:

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

    <!-- === PROPERTIES === -->
    <property name="LOG_HOME" value="logs" />
    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>

    <!-- === ROLLING FILE APPENDER === -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/app.log</file>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>

        <!-- Time + Size Based Rolling -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- File name with date and index -->
            <fileNamePattern>${LOG_HOME}/app-%d{yyyy-MM-dd}.%i.log</fileNamePattern>

            <!-- Roll when size exceeds 10MB -->
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>

            <!-- Keep logs for 30 days -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- === CONSOLE APPENDER === -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- === ROOT LOGGER === -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>

    <!-- === PACKAGE-SPECIFIC LOGGERS === -->
    <logger name="com.example.productapi.service" level="DEBUG" />
    <logger name="com.example.productapi.repository" level="WARN" />
    <logger name="org.springframework.web" level="ERROR" />

</configuration>

4. How This Works

  • RollingFileAppender writes logs to a file and handles rolling.
  • TimeBasedRollingPolicy ensures that a new file is created daily.
  • SizeAndTimeBasedFNATP creates new files if a log file exceeds 10MB within the same day.
  • Log file names will look like:
  logs/app-2025-08-12.0.log
  logs/app-2025-08-12.1.log
  logs/app-2025-08-13.0.log
  • maxHistory ensures logs older than 30 days are deleted automatically.

5. Testing the Logging

You can create a simple Spring Boot controller to generate logs for testing:

@RestController
@RequestMapping("/log")
public class LogTestController {

    private static final Logger log = LoggerFactory.getLogger(LogTestController.class);

    @GetMapping
    public String testLogs() {
        log.debug("Debug log message");
        log.info("Info log message");
        log.warn("Warn log message");
        log.error("Error log message");
        return "Logs generated!";
    }
}

Run:

mvn spring-boot:run

Then hit:

http://localhost:8080/log

You’ll see logs in:

  • Console
  • logs/app.log And rolled files will appear once size/date conditions are met.

6. Best Practices for Logging in Production

  • Don’t log sensitive data (passwords, tokens)
  • Use DEBUG level sparingly in production
  • Rotate logs to prevent disk overuse
  • Use centralized log aggregation tools like ELK or Grafana Loki
  • Always keep log format consistent for easier parsing

Final Output:

  • Logs to both console and file
  • Custom pattern layout
  • Package-specific log levels
  • Rolling policy based on date and size
  • Automatic cleanup after 30 days

Alright — let’s extend the logging setup so that each package logs into its own file, with its own rolling policy, file naming format, and retention.

This is a very enterprise-friendly approach because:

  • Service-related logs go into one file
  • Repository (DB) logs go into another
  • Framework (Spring) logs are isolated
  • Easier to debug and monitor each layer independently

1. Updated logback-spring.xml for Multiple Package-specific Files

Place this in src/main/resources/logback-spring.xml:

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

    <!-- === GLOBAL PROPERTIES === -->
    <property name="LOG_HOME" value="logs" />
    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
    <property name="MAX_FILE_SIZE" value="10MB" />
    <property name="MAX_HISTORY_DAYS" value="30" />

    <!-- === COMMON ROLLING POLICY TEMPLATE === -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- === Root Application Log (catch-all) === -->
    <appender name="ROOT_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/app.log</file>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/app-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>${MAX_HISTORY_DAYS}</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- === Service Layer Logs === -->
    <appender name="SERVICE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/service.log</file>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/service-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>${MAX_HISTORY_DAYS}</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- === Repository Layer Logs === -->
    <appender name="REPOSITORY_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/repository.log</file>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/repository-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>${MAX_HISTORY_DAYS}</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- === Spring Framework Logs === -->
    <appender name="SPRING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_HOME}/spring.log</file>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_HOME}/spring-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>${MAX_HISTORY_DAYS}</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- === LOGGERS WITH APPENDER MAPPING === -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="ROOT_FILE" />
    </root>

    <logger name="com.example.productapi.service" level="DEBUG" additivity="false">
        <appender-ref ref="SERVICE_FILE" />
        <appender-ref ref="CONSOLE" />
    </logger>

    <logger name="com.example.productapi.repository" level="WARN" additivity="false">
        <appender-ref ref="REPOSITORY_FILE" />
        <appender-ref ref="CONSOLE" />
    </logger>

    <logger name="org.springframework" level="ERROR" additivity="false">
        <appender-ref ref="SPRING_FILE" />
        <appender-ref ref="CONSOLE" />
    </logger>

</configuration>

2. How This Works

  • Multiple file appenders are defined — one for each log category (service, repository, spring, root).
  • additivity="false" ensures logs from a package don’t go to multiple files unintentionally.
  • Each appender:

    • Rolls logs daily
    • Splits files when size exceeds 10MB
    • Deletes logs older than 30 days
  • File names look like:

  logs/service-2025-08-12.0.log
  logs/service-2025-08-12.1.log
  logs/repository-2025-08-13.0.log
  logs/spring-2025-08-13.0.log

3. Benefits of This Approach

  • Separation of Concerns — each package logs into its own file
  • Easier Debugging — when investigating an issue, you can check only relevant logs
  • Controlled Size & Retention — prevents huge unmanageable log files
  • Production Friendly — works seamlessly with log aggregation tools like ELK, Loki, Splunk

4. Testing the Setup

You can trigger logs in each package and verify that:

  • Service layer logs go into service-YYYY-MM-DD.log
  • Repository layer logs go into repository-YYYY-MM-DD.log
  • Spring framework logs go into spring-YYYY-MM-DD.log
  • Miscellaneous logs go into app-YYYY-MM-DD.log


This content originally appeared on DEV Community and was authored by DevCorner2


Print Share Comment Cite Upload Translate Updates
APA

DevCorner2 | Sciencx (2025-08-12T12:19:10+00:00) Spring Boot Logging to File with Pattern Layout, Package-specific Levels, and Rolling Policies. Retrieved from https://www.scien.cx/2025/08/12/spring-boot-logging-to-file-with-pattern-layout-package-specific-levels-and-rolling-policies/

MLA
" » Spring Boot Logging to File with Pattern Layout, Package-specific Levels, and Rolling Policies." DevCorner2 | Sciencx - Tuesday August 12, 2025, https://www.scien.cx/2025/08/12/spring-boot-logging-to-file-with-pattern-layout-package-specific-levels-and-rolling-policies/
HARVARD
DevCorner2 | Sciencx Tuesday August 12, 2025 » Spring Boot Logging to File with Pattern Layout, Package-specific Levels, and Rolling Policies., viewed ,<https://www.scien.cx/2025/08/12/spring-boot-logging-to-file-with-pattern-layout-package-specific-levels-and-rolling-policies/>
VANCOUVER
DevCorner2 | Sciencx - » Spring Boot Logging to File with Pattern Layout, Package-specific Levels, and Rolling Policies. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/08/12/spring-boot-logging-to-file-with-pattern-layout-package-specific-levels-and-rolling-policies/
CHICAGO
" » Spring Boot Logging to File with Pattern Layout, Package-specific Levels, and Rolling Policies." DevCorner2 | Sciencx - Accessed . https://www.scien.cx/2025/08/12/spring-boot-logging-to-file-with-pattern-layout-package-specific-levels-and-rolling-policies/
IEEE
" » Spring Boot Logging to File with Pattern Layout, Package-specific Levels, and Rolling Policies." DevCorner2 | Sciencx [Online]. Available: https://www.scien.cx/2025/08/12/spring-boot-logging-to-file-with-pattern-layout-package-specific-levels-and-rolling-policies/. [Accessed: ]
rf:citation
» Spring Boot Logging to File with Pattern Layout, Package-specific Levels, and Rolling Policies | DevCorner2 | Sciencx | https://www.scien.cx/2025/08/12/spring-boot-logging-to-file-with-pattern-layout-package-specific-levels-and-rolling-policies/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.