10

I'm using Spring Boot 1.3.0.RC1 through spring-cloud Brixton.M2 and have been unable to pull spring boot properties into logback.xml as implied by this feature checkin Support springProperty in logback configurations

I'm using .yml files and want to pull application name out of bootstrap.yml or application.yml.

logback-spring.xml:

<configuration>
      <springProperty scope="context" name="myappName" source="spring.application.name"/>
      <contextName>${myappName}</contextName>
      <appender name="logFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
         <file>logs/${myappName}.log</file>
         ... 
      </appender>
      ...
</configuration>

The documentation here Spring Boot Logback extensions doesn't help much.

This other stackoverflow question Unable to use Spring Property Placeholders in logback.xml is older and doesnt work for me either. Any insight would be helpful.

Per request, here is the relevant dependency tree that is being used

[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.3.0.RC1:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:1.3.0.RC1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:1.3.0.RC1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.3.0.RC1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.3.0.RC1:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.1.3:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.1.3:compile
[INFO] |  |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.12:compile
[INFO] |  |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.12:compile
[INFO] |  |  |  \- org.slf4j:log4j-over-slf4j:jar:1.7.12:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.16:runtime

Per 2nd request for info, what is actually going on is that logback property myappName does not get a value. The way I know this is that the value becomes "myappName_IS_UNDEFINED" and my logfile gets named "myappName_IS_UNDEFINED.log" and the %contextName is set to "myappName_IS_UNDEFINED".

Didier L
  • 18,905
  • 10
  • 61
  • 103
RubesMN
  • 939
  • 1
  • 12
  • 22

10 Answers10

14

To provide my analysis and a solution for future readers... I tried with spring.application.name values in bootstrap.yml, then application.yml, then application.properties but none worked. I thought it was because I used logback.xml, but converting to logback-spring.xml resulted in no change. Looking at the code committed here, pulling the values via this.environment.getProperty(source) is dependent on when the property sources are loaded vs when the logback-spring.xml file is interpreted. Not sure why Dave Syer was able to get it to work but my .xml variable was populated before local property sources are added to the environment.

The value is populated within the .xml file if I set it via SpringApplication.setDefaultProperties(). Hence that is the route I took.

  • Built a SpringApplicationRunListener
  • In SpringApplicationRunListener.started(), I read in bootstrap.yml (where I required spring.application.name for all framework users) via new ClassPathResource("/bootstrap.yml")
  • Set a new property, service.log.name in a HashMap based off the value
  • Called SpringApplication.setDefaultProperties() with that HashMap
  • Then I was able to use ${myappName} within the logback-spring.xml file

I admit this is not a perfect solution, but one that works for now and will likely continue to work for future releases of springBoot. I am open to further ideas but wanted to provide a solution that worked for others that are having the same experience.

RubesMN
  • 939
  • 1
  • 12
  • 22
  • cause it is too early that spring has not make the Environment ready. – Horsing Apr 30 '16 at 11:39
  • if you load your own properties why wouldn't you just add it to argument in form of `--property=value`? this should be priorer then default property source and simple. – Horsing Apr 30 '16 at 11:43
10

Our solution is to rename logback(-spring).xml to e.g. logback-delayed.xml so that it won't be read before Spring Cloud Config, and then activate it later explicitly from the config file in the Cloud Config repo, e.g.:

logging:
    config: classpath:logback-delayed.xml
    prop-to-fill-in-logback-delayed.xml: whatever

Declaring the variable in logback-delayed.xml

<springProperty scope="context" name="localName" source="prop-to-fill-in-logback-delayed.xml"/>

Using the variable in logback-delayed.xml

<file>${localName}.log</file>
LIU ShouHai
  • 151
  • 1
  • 5
6

You can simply add this to your logback file:

<property resource="application.properties" />
2

I'm on Spring Boot 1.3.1 and I was facing the same issue.

What I finally found out was that the property must be set in BOTH application.yml AND bootstrap.yml. Setting it in just one or the other does not work. Passing it only as a -D argument does also work.

It's a bit of a hazzle to have a double configuration though, especially when it is configured per profile as well.

Maybe the logback configuration is needed in both phases and the property value does not carry over.

nedenom
  • 405
  • 4
  • 14
2

first of all, your logback configuration file name should be suffixed with -spring, no matter the file is in xml or groovy format.

in spring, config center is preferred, then command line arguments, then local properties in bootstrap.yml and all local property files.

if there are many properties in multiple configuration files the first will effect no matter what value it is.

by the way, please make sure there are no programmatically logback settings before EnvironmentPrepared event cause the logback settings will be reset. meanwhile, if there are multiple spring contexts the logback settings will be reset several times for each context.

please check these rules and make sure every step is in control.

Horsing
  • 1,070
  • 7
  • 22
2

In order to access the spring app name , you must first defined the spring property in logback-spring.xml as shown below :

<springProperty scope="context" name="MyApp" source="com.app.star"/>

So If you are accessing the source above then logically it must be defined in application.yml file as below :

com: app: star: HelloWorld

# Logging Configurations logging: config: "classpath:logback-spring.xml"


Now in logback-spring.xml, the appName would be set with name as 'HelloWorld' which you can access with {MyApp}.

Hope the above explanation would help.

0

It works for me if I put the "spring.application.name" in "application.properties" (not "bootstrap.properties" because the logging system is initialized in a phase where the bootstrap properties are not yet available I believe). I don't think logback will let you set the "context" name either but YMMV.

Dave Syer
  • 56,583
  • 10
  • 155
  • 143
  • Still doesn't work for me. Using spring-boot 1.3.0.RC1 and logback 1.1.3. Tried application.properties in /resources and in root directory. Works if I do straight logback properties using this ``. The contextName setting doesn't work half the time, I keep getting (http://jira.qos.ch/browse/LOGBACK-801) problem. So still something fishy. – RubesMN Nov 03 '15 at 22:14
  • Maybe you could update your question with more details of what actually goes wrong? – Dave Syer Nov 04 '15 at 07:17
  • It works for me if I put the value in "application.properties", but not "application.yml". Are yaml files processed at a later point then property files? I'm using spring-boot 1.3.8. – bruce szalwinski Oct 01 '16 at 01:24
0

For me, it only worked using a command line property, like --property.value=asd.

Alessandro Dionisi
  • 2,494
  • 4
  • 33
  • 37
0

It worked for me after I have updated only in bootstrap.properties. Updates in application.properties does not work and also not needed.

kafka.host.name=xxxxx
kafka.host.port=9092

In Logback.xml

<springProperty scope="context" name="kafkaHostName" source="kafka.host.name" /> 

<springProperty scope="context" name="kafkaHostPort" source="kafka.host.port" />

  <appender name="asyncXSPKafkaAppender" class="com.github.danielwegener.logback.kafka.KafkaAppender">
        <encoder class="com.github.danielwegener.logback.kafka.encoding.LayoutKafkaMessageEncoder">
            <layout class="ch.qos.logback.classic.PatternLayout">
                <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </layout>
        </encoder>
        <topic>logstash_logs</topic>
        <keyingStrategy class="com.github.danielwegener.logback.kafka.keying.RoundRobinKeyingStrategy" />
        <deliveryStrategy class="com.github.danielwegener.logback.kafka.delivery.AsynchronousDeliveryStrategy" />
        <producerConfig>bootstrap.servers=**${kafkaHostName}:${kafkaHostPort}**</producerConfig>
        <producerConfig>retries=2</producerConfig>
    </appender>
sivakadi
  • 181
  • 1
  • 4
0

I had the same issue, solved it by moving the properties I needed from application.properties to bootstrap.properties

Chris Jansson
  • 55
  • 1
  • 11