How to use Logback to write logs to custom persistent storage

Note

The Basic, Standard, and Enterprise plans will be deprecated starting from mid-March, 2025, with a 3 year retirement period. We recommend transitioning to Azure Container Apps. For more information, see the Azure Spring Apps retirement announcement.

The Standard consumption and dedicated plan will be deprecated starting September 30, 2024, with a complete shutdown after six months. We recommend transitioning to Azure Container Apps. For more information, see Migrate Azure Spring Apps Standard consumption and dedicated plan to Azure Container Apps.

This article applies to: ✅ Java ❎ C#

This article applies to: ✅ Basic/Standard ✅ Enterprise

This article shows you how to load Logback and write logs to custom persistent storage in Azure Spring Apps.

Note

When a file in the application's classpath has one of the following names, Spring Boot will automatically load it over the default configuration for Logback:

  • logback-spring.xml
  • logback.xml
  • logback-spring.groovy
  • logback.groovy

Prerequisites

Edit the Logback configuration to write logs into a specific path

You can set the path to where logs will be written by using the logback-spring.xml example file.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="Console"
              class="ch.qos.logback.core.ConsoleAppender">
        <!-- please feel free to customize the log layout -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                %black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
            </Pattern>
        </layout>
    </appender>

    <appender name="RollingFile"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 'LOGS' here is a value to be read from the application's environment variable -->
        <file>${LOGS}/spring-boot-logger.log</file>
        <!-- please feel free to customize the log layout pattern -->
        <encoder
                class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
        </encoder>

        <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- rollover daily and when the file reaches 10 MegaBytes -->
            <fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log
            </fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>

    <!-- LOG everything at the INFO level -->
    <root level="info">
        <appender-ref ref="RollingFile" />
        <appender-ref ref="Console" />
    </root>

    <!-- LOG "com.baeldung*" at the TRACE level -->
    <logger name="com.baeldung" level="trace" additivity="false">
        <appender-ref ref="RollingFile" />
        <appender-ref ref="Console" />
    </logger>

</configuration>

In the preceding example, there are two placeholders named {LOGS} in the path for writing the application's logs to. A value needs to be assigned to the environment variable LOGS to have the log write to both the console and your persistent storage.

Use the Azure CLI to create and deploy a new app with Logback on persistent storage

  1. Use the following command to create an application in Azure Spring Apps with persistent storage enabled and the environment variable set:

    az spring app create \
         --resource-group <resource-group-name> \
         --name <app-name> \
         --service <spring-instance-name> \
         --persistent-storage <path-to-json-file> \
         --env LOGS=/byos/logs
    

    Note

    The value of the LOGS environment variable can be the same as, or a subdirectory of the mountPath.

    Here's an example of the JSON file that is passed to the --persistent-storage parameter in the create command. In this example, the same value is passed for the environment variable in the CLI command above and in the mountPath property below:

    {
        "customPersistentDisks": [
            {
                "storageName": "<Storage-Resource-Name>",
                "customPersistentDiskProperties": {
                    "type": "AzureFileVolume",
                    "shareName": "<Azure-File-Share-Name>",
                    "mountPath": "/byos/logs",
                    "readOnly": false
                }
            }
        ]
    }
    
  2. Use the following command to deploy your application:

    az spring app deploy \
         --resource-group <resource-group-name> \
         --name <app-name> \
         --service <spring-instance-name> \
         --artifact-path <path-to-jar-file>
    
  3. Use the following command to check your application's console log:

    az spring app logs \
         --resource-group <resource-group-name> \
         --name <app-name> \
         --service <spring-instance-name>
    

    Go to the Azure Storage Account resource you bound and find the Azure file share that was attached as persistent storage. In this example, the logs will be written to the spring-boot-logger.log file at the root of your Azure file share. All of the rotated log files will be stored in the /archived folder in your Azure file share.

  4. Optionally, use the following command to update the path or persistent storage of an existing app:

    The path or persistent storage where the logs are saved can be changed at any time. The application will restart when changes are made to either environment variables or persistent storage.

    az spring app update \
         --resource-group <resource-group-name> \
         --name <app-name> \
         --service <spring-instance-name> \
         --persistent-storage <path-to-new-json-file> \
         --env LOGS=<new-path>
    

Next steps