Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject active spring profile into logback

I'm using a spring boot project.

Environment:

ch.qos.logback:logback-core:jar:1.1.5
ch.qos.logback:logback-classic:jar:1.1.5
org.springframework.boot:spring-boot-starter-logging:jar:1.3.3.RELEASE

In my project I'm using properties with application.yml (application-dev.yml and application-production.yml)

Since the Logback Spring extension starts before Spring I'm not able to inject the spring.profiles.active into the logback.xml file.

This is a simpler version of my logback.xml file:

<configuration scan="true">

   <property name="LOG_PATH" value="/var/log/" />
   <property name="APP_NAME" value="xyz" />
   <property name="PROFILE" value="-${spring.profiles.active}" />
   <property name="CHARSET" value="utf-8" />
   <property name="PATTERN" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />

   <appender name="APP-FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>${LOG_PATH}${APP_NAME}${PROFILE}.log</file>
      <encoder>
         <charset>${CHARSET}</charset>
         <Pattern>${PATTERN}</Pattern>
      </encoder>
   </appender>

   <logger name="a.b.c" level="INFO">
      <appender-ref ref="APP-FILE" />
   </logger>

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

The PROFILE I'm looking for is the property spring.profiles.active.

My goal is to have a log file on directory /var/log the files xyz-dev or xyz-production but I getting xyz-spring.profiles.active_IS_UNDEFINED.log instead of course.

Approaches:

1 - Using a component like:

@Component
public class InitializationService implements ApplicationListener<ContextRefreshedEvent> {

// inject spring profile active into logback.xml

}

is not working of course because the logback Spring extension starts before Spring Boot application.

2 - Using a property on the logback.xml like this

<file>${LOG_PATH}${APP_NAME}${PROFILE}.log</file>

The result is xyz-spring.profiles.active_IS_UNDEFINED.log

like image 605
Leonel Avatar asked Sep 17 '16 11:09

Leonel


People also ask

How does Spring Boot Logback work?

Logback is provided out of the box with Spring Boot when you use one of the Spring Boot starter dependencies, as they include spring-boot-starter-logging — providing logging without any configuration that can be altered to work differently if required. There are two ways of providing your own configuration.

Does spring use Logback by default?

By default, Spring Boot picks up the native configuration from its default location for the system (such as classpath:logback.

Does spring use Log4j or Logback?

Spring Boot supports Log4j 2 for logging configuration if it is on the classpath. If you are using the starters for assembling dependencies that means you have to exclude Logback and then include log4j 2 instead. If you aren't using the starters then you need to provide jcl-over-slf4j (at least) in addition to Log4j 2.

What is Logback xml?

Logback is a logging framework with those qualities. If you are new to Logback, I suggest going through my introductory post on Logback: Logback Introduction: An Enterprise Logging Framework. Logback supports configuration through XML and Groovy. In this post, I'll discuss how to configure Logback using an XML file.


2 Answers

This is a little late to answer, but I have successfully logged the Spring profile by renaming my "logback.xml" file to "logback-spring.xml", and accessed the profile like this (much) simplified version

<springProperty scope="context" name="ACTIVE_PROFILE" source="spring.profiles.active"/>

<appender name="GRAYLOG" class="com.github.pukkaone.gelf.logback.GelfAppender">

    <additionalField>environment=${ACTIVE_PROFILE}</additionalField>

</appender>

<root level="WARN">
    <appender-ref ref="GRAYLOG" />
</root>

It seems that "logback-spring.xml" can pick up the profile information.

The specific documentation is here.

like image 187
scudsucker Avatar answered Oct 24 '22 16:10

scudsucker


  • Since you're using Spring Boot you can define logging.file=blah.log. See official docs.
  • Or you can use vanilla Logback and pass a system variable: -DLOG_FILE=blah.log.

Why you shouldn't use profiles:

What you're trying to do is not what spring profiles were created for. They are needed to switch on/off beans to activate/deactivate behaviour during startup. Profiles is not recommended practice in general since what you test and what works in production is different (though sometimes there is no other choice). See Caveats section of the original announcement.

Another problem with your usage of profiles is that multiple profiles can be activated at the same time. Profiles were created to switch on/off small unrelated parts. E.g. spring.profiles.active=cache-off,perf-monitoring-on or something of that kind.

Having all that said you can still define a profile and set logging.file=prod.log property within that profile. That's still very bad and not how profiles should be used, but that's better.

like image 36
Stanislav Bashkyrtsev Avatar answered Oct 24 '22 17:10

Stanislav Bashkyrtsev