Spring Boot Profile Based Logging

Introduction

Here in this example, I am going to show you how to create Spring Boot profile based logging. For any applications logging is an important things which will help you to debug through your application errors or issues and you can fix them easily by analyzing those errors or issues from the log files.

Let’s say you want to keep different types of configurations for your log files in different environments and it would be difficult to modify the log file configuration when you deploy your spring boot applications. Your local environment where you generally develop your application code may have different configurations than your dev environment or your dev environment’s log file may have different configurations than your prod environment, etc.

Let’s also say that your local environment where you are developing code for your application may have debug as a log level and your prod environment may have an error as a log level. Your local environment may also have your log enabled for console but not in other environments.

Related Posts:

In Spring Boot applications, you can run different configurations in your different environments based on Spring profile. It’s not limited to the logging but also other things, such as, you can execute certain things in your applications based on Spring profile. So, Spring Profiles provide a way to segregate parts of your application configuration and make it only available in certain environments.

spring boot profile based logging

In the normal Spring way, you can use a spring.profiles.active Environment property to specify which profiles are active. You can specify the property in any of the usual ways, for example you could include it in your application.properties file:

spring.profiles.active=dev,hsqldb

Or specify on the command line using the switch --spring.profiles.active=dev,hsqldb.

Remember if you specify active profiles in application.properties file and if you also specify active profiles in command line argument, then command line argument will replace the active profile at run time.

If you want to include profiles from application.properties and command line argument then in your application.properties file you have to use:

spring.profiles.include=<comma separated names for multiple profiles>

Spring Profile – Prerequisites

Java 1.8+, Maven 3.8.2, Spring Boot 2.5.4

Spring Profile – Project Setup

Create a maven-based project in your favorite IDE or tool. The name of the project is spring-boot-profile-based-logging.

The build file pom.xml is given below with required dependency.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.roytuts</groupId>
	<artifactId>spring-boot-profile-based-logging</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>8</maven.compiler.source>
		<maven.compiler.target>8</maven.compiler.target>
	</properties>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.4</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Log File – logback.xml or logback-spring.xml

Spring recommends that you use the -spring variants for your logging configuration (for example, logback-spring.xml rather than logback.xml). logback-spring.xml is generally used to take advantage of the templating features provided by Spring Boot. If you use standard configuration locations, Spring cannot completely control log initialization.

Any one of the names between logback.xml and logback-spring.xml will work fine when put in the class path folder – src/main/resources.

The following content shows how to work with Spring Boot profile based logging.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<!--<include resource="org/springframework/boot/logging/logback/defaults.xml" />-->

	<springProfile name="local">
		<appender name="CA" class="ch.qos.logback.core.ConsoleAppender">
			<!-- Log message format -->
			<encoder>
				<pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}
					-
					%msg%n
				</pattern>
			</encoder>
		</appender>

		<property name="LOG_FILE" value="C:/logs/SpringBoot.log" />
		<appender name="RFA"
			class="ch.qos.logback.core.rolling.RollingFileAppender">
			<file>${LOG_FILE}</file>
			<encoder>
				<pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}
					-
					%msg%n
				</pattern>
			</encoder>
			<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
				<fileNamePattern>${LOG_FILE}-%d{dd-MM-yyyy}.log</fileNamePattern>
			</rollingPolicy>
		</appender>

		<root>
			<level value="DEBUG" />
			<appender-ref ref="CA" />
			<appender-ref ref="RFA" />
		</root>
	</springProfile>

	<springProfile name="dev">
		<property name="LOG_FILE" value="C:/logs/SpringBoot.log" />
		<appender name="RFA"
			class="ch.qos.logback.core.rolling.RollingFileAppender">
			<file>${LOG_FILE}</file>
			<encoder>
				<pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}
					-
					%msg%n
				</pattern>
			</encoder>
			<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
				<fileNamePattern>${LOG_FILE}-%d{dd-MM-yyyy}.%i.log</fileNamePattern>
				<timeBasedFileNamingAndTriggeringPolicy
					class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
					<maxFileSize>5MB</maxFileSize>
				</timeBasedFileNamingAndTriggeringPolicy>
			</rollingPolicy>
		</appender>

		<root>
			<level value="INFO" />
			<appender-ref ref="RFA" />
		</root>
	</springProfile>

	<springProfile name="prod">
		<property name="LOG_FILE" value="C:/logs/SpringBoot.log" />
		<appender name="RFA"
			class="ch.qos.logback.core.rolling.RollingFileAppender">
			<file>${LOG_FILE}</file>
			<encoder>
				<pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}
					-
					%msg%n
				</pattern>
			</encoder>
			<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
				<fileNamePattern>${LOG_FILE}-%d{dd-MM-yyyy}.%i.log</fileNamePattern>
				<timeBasedFileNamingAndTriggeringPolicy
					class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
					<maxFileSize>10MB</maxFileSize>
				</timeBasedFileNamingAndTriggeringPolicy>
			</rollingPolicy>
		</appender>

		<root>
			<level value="INFO" />
			<appender-ref ref="RFA" />
		</root>
	</springProfile>
</configuration>

In the above log file (logback-spring.xml or logback.xml), springProfile node has been used to configure logging for different environments.

For springProfile name local I have used both console-based and file-based logging. For dev and prod profiles I have used only file-based logging.

The appender name ideally should be unique but for this example this is fine.

You can also include multiple names in the springProfile tag separated by comma (,), for example, to include dev and uat, use:

<springProfile name="dev, uat">…</springProfile>

I have also kept the same log file name and same path for log file for this example just to give an idea how it works.

I have used RollingFileAppender and also using TImeBasedRollingPolicy with size. So everyday you will have separate log file and even you can have multiple log files on the same day if the size of the log file reaches to maximum size specified in the configuration file.

I have also specified log patterns when displayed or written to the log file and log file name pattern.

Spring Profile – application.properties

The application.properties file is created under class path folder src/main/resources with the following content.

spring.profiles.active=${spring.profiles.active}

The key spring.profiles.active is used to activate the profile and based on the profile value, such as, local, dev, prod, your log file will be created. You have to pass -Dspring.profiles.active as a VM argument while you are running the application.

You can put VM argument by going to the Run As -> Run Configurations in your Eclipse/Spring Tool Suite IDE. Then on the Arguments tab of the main class under the VM Arguments section you can put the following value:

-Dspring.profiles.active=dev

If you want to pass multiple profiles then you can pass as:

-Dspring.profiles.active=local,dev

Spring Profile – Main Class

The class is having a main method with @SpringBootApplication annotation will deploy the application in the embedded Tomcat server when the class is run.

@SpringBootApplication
public class SpringProfileBasedLoggingApp implements CommandLineRunner {

	private static final Logger LOG = LoggerFactory.getLogger(SpringProfileBasedLoggingApp.class);

	public static void main(String[] args) {
		SpringApplication.run(SpringProfileBasedLoggingApp.class, args).close();
	}

	@Override
	public void run(String... args) throws Exception {
		LOG.debug("Debug Message");
		LOG.warn("Warn Message");
		LOG.error("Error Message");
		LOG.info("Info Message");
		LOG.trace("Trace Message");
	}

}

Testing Spring Profile Application

When you run the local profile, you will see logs both in console and file (under C:\logs\SpringBoot.log) with the following message:

Debug Message
Warn Message
Error Message
Info Message

For dev or prod you won’t find any log in the console, but you will find the following log messages in the log file (under C:\logs\SpringBoot.log) only:

Warn Message
Error Message
Info Message

For local profile, the level of log is debug whereas, for dev and prod, the level of log is info.

When you run your application on next day then you will see that your log file has been renamed with date and a new log file with name SpringBoot.log gets generated.

Hope you got an idea how to work with Spring Profiles and how to create Spring profile based logging.

Source Code

Download

Leave a Reply

Your email address will not be published.